gallium/nouveau: clean-up #includes
[mesa.git] / src / gallium / drivers / nouveau / nouveau_screen.c
1 #include "pipe/p_defines.h"
2 #include "pipe/p_screen.h"
3 #include "pipe/p_state.h"
4
5 #include "util/u_memory.h"
6 #include "util/u_inlines.h"
7
8 #include <stdio.h>
9 #include <errno.h>
10
11 #include "nouveau/nouveau_bo.h"
12 #include "nouveau_winsys.h"
13 #include "nouveau_screen.h"
14
15 static const char *
16 nouveau_screen_get_name(struct pipe_screen *pscreen)
17 {
18 struct nouveau_device *dev = nouveau_screen(pscreen)->device;
19 static char buffer[128];
20
21 snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset);
22 return buffer;
23 }
24
25 static const char *
26 nouveau_screen_get_vendor(struct pipe_screen *pscreen)
27 {
28 return "nouveau";
29 }
30
31 static struct pipe_buffer *
32 nouveau_screen_bo_skel(struct pipe_screen *pscreen, struct nouveau_bo *bo,
33 unsigned alignment, unsigned usage, unsigned size)
34 {
35 struct pipe_buffer *pb;
36
37 pb = CALLOC(1, sizeof(struct pipe_buffer)+sizeof(struct nouveau_bo *));
38 if (!pb) {
39 nouveau_bo_ref(NULL, &bo);
40 return NULL;
41 }
42
43 pipe_reference_init(&pb->reference, 1);
44 pb->screen = pscreen;
45 pb->alignment = alignment;
46 pb->usage = usage;
47 pb->size = size;
48 *(struct nouveau_bo **)(pb + 1) = bo;
49 return pb;
50 }
51
52 static struct pipe_buffer *
53 nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment,
54 unsigned usage, unsigned size)
55 {
56 struct nouveau_device *dev = nouveau_screen(pscreen)->device;
57 struct nouveau_bo *bo = NULL;
58 uint32_t flags = NOUVEAU_BO_MAP, tile_mode = 0, tile_flags = 0;
59 int ret;
60
61 if (usage & NOUVEAU_BUFFER_USAGE_TRANSFER)
62 flags |= NOUVEAU_BO_GART;
63 else
64 if (usage & PIPE_BUFFER_USAGE_VERTEX) {
65 if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF))
66 flags |= NOUVEAU_BO_GART;
67 } else
68 if (usage & PIPE_BUFFER_USAGE_INDEX) {
69 if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF))
70 flags |= NOUVEAU_BO_GART;
71 }
72
73 if (usage & PIPE_BUFFER_USAGE_PIXEL) {
74 if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE)
75 flags |= NOUVEAU_BO_GART;
76 if (!(usage & PIPE_BUFFER_USAGE_CPU_READ_WRITE))
77 flags |= NOUVEAU_BO_VRAM;
78
79 if (dev->chipset == 0x50 || dev->chipset >= 0x80) {
80 if (usage & NOUVEAU_BUFFER_USAGE_ZETA)
81 tile_flags = 0x2800;
82 else
83 tile_flags = 0x7000;
84 }
85 }
86
87 ret = nouveau_bo_new_tile(dev, flags, alignment, size,
88 tile_mode, tile_flags, &bo);
89 if (ret)
90 return NULL;
91
92 return nouveau_screen_bo_skel(pscreen, bo, alignment, usage, size);
93 }
94
95 static struct pipe_buffer *
96 nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes)
97 {
98 struct nouveau_device *dev = nouveau_screen(pscreen)->device;
99 struct nouveau_bo *bo = NULL;
100 int ret;
101
102 ret = nouveau_bo_user(dev, ptr, bytes, &bo);
103 if (ret)
104 return NULL;
105
106 return nouveau_screen_bo_skel(pscreen, bo, 0, 0, bytes);
107 }
108
109 static inline uint32_t
110 nouveau_screen_map_flags(unsigned pipe)
111 {
112 uint32_t flags = 0;
113
114 if (pipe & PIPE_BUFFER_USAGE_CPU_READ)
115 flags |= NOUVEAU_BO_RD;
116 if (pipe & PIPE_BUFFER_USAGE_CPU_WRITE)
117 flags |= NOUVEAU_BO_WR;
118 if (pipe & PIPE_BUFFER_USAGE_DISCARD)
119 flags |= NOUVEAU_BO_INVAL;
120 if (pipe & PIPE_BUFFER_USAGE_DONTBLOCK)
121 flags |= NOUVEAU_BO_NOWAIT;
122 else
123 if (pipe & 0 /*PIPE_BUFFER_USAGE_UNSYNCHRONIZED*/)
124 flags |= NOUVEAU_BO_NOSYNC;
125
126 return flags;
127 }
128
129 static void *
130 nouveau_screen_bo_map(struct pipe_screen *pscreen, struct pipe_buffer *pb,
131 unsigned usage)
132 {
133 struct nouveau_bo *bo = nouveau_bo(pb);
134 struct nouveau_screen *nscreen = nouveau_screen(pscreen);
135 int ret;
136
137 if (nscreen->pre_pipebuffer_map_callback) {
138 ret = nscreen->pre_pipebuffer_map_callback(pscreen, pb, usage);
139 if (ret) {
140 debug_printf("pre_pipebuffer_map_callback failed %d\n",
141 ret);
142 return NULL;
143 }
144 }
145
146 ret = nouveau_bo_map(bo, nouveau_screen_map_flags(usage));
147 if (ret) {
148 debug_printf("map failed: %d\n", ret);
149 return NULL;
150 }
151
152 return bo->map;
153 }
154
155 static void *
156 nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct pipe_buffer *pb,
157 unsigned offset, unsigned length, unsigned usage)
158 {
159 struct nouveau_bo *bo = nouveau_bo(pb);
160 struct nouveau_screen *nscreen = nouveau_screen(pscreen);
161 uint32_t flags = nouveau_screen_map_flags(usage);
162 int ret;
163
164 if (nscreen->pre_pipebuffer_map_callback) {
165 ret = nscreen->pre_pipebuffer_map_callback(pscreen, pb, usage);
166 if (ret) {
167 debug_printf("pre_pipebuffer_map_callback failed %d\n",
168 ret);
169 return NULL;
170 }
171 }
172
173 ret = nouveau_bo_map_range(bo, offset, length, flags);
174 if (ret) {
175 nouveau_bo_unmap(bo);
176 if (!(flags & NOUVEAU_BO_NOWAIT) || ret != -EBUSY)
177 debug_printf("map_range failed: %d\n", ret);
178 return NULL;
179 }
180
181 return (char *)bo->map - offset; /* why gallium? why? */
182 }
183
184 static void
185 nouveau_screen_bo_map_flush(struct pipe_screen *pscreen, struct pipe_buffer *pb,
186 unsigned offset, unsigned length)
187 {
188 struct nouveau_bo *bo = nouveau_bo(pb);
189
190 nouveau_bo_map_flush(bo, offset, length);
191 }
192
193 static void
194 nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct pipe_buffer *pb)
195 {
196 struct nouveau_bo *bo = nouveau_bo(pb);
197
198 nouveau_bo_unmap(bo);
199 }
200
201 static void
202 nouveau_screen_bo_del(struct pipe_buffer *pb)
203 {
204 struct nouveau_bo *bo = nouveau_bo(pb);
205
206 nouveau_bo_ref(NULL, &bo);
207 FREE(pb);
208 }
209
210 static void
211 nouveau_screen_fence_ref(struct pipe_screen *pscreen,
212 struct pipe_fence_handle **ptr,
213 struct pipe_fence_handle *pfence)
214 {
215 *ptr = pfence;
216 }
217
218 static int
219 nouveau_screen_fence_signalled(struct pipe_screen *screen,
220 struct pipe_fence_handle *pfence,
221 unsigned flags)
222 {
223 return 0;
224 }
225
226 static int
227 nouveau_screen_fence_finish(struct pipe_screen *screen,
228 struct pipe_fence_handle *pfence,
229 unsigned flags)
230 {
231 return 0;
232 }
233
234 int
235 nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
236 {
237 struct pipe_screen *pscreen = &screen->base;
238 int ret;
239
240 ret = nouveau_channel_alloc(dev, 0xbeef0201, 0xbeef0202,
241 &screen->channel);
242 if (ret)
243 return ret;
244 screen->device = dev;
245
246 pscreen->get_name = nouveau_screen_get_name;
247 pscreen->get_vendor = nouveau_screen_get_vendor;
248
249 pscreen->buffer_create = nouveau_screen_bo_new;
250 pscreen->user_buffer_create = nouveau_screen_bo_user;
251 pscreen->buffer_map = nouveau_screen_bo_map;
252 pscreen->buffer_map_range = nouveau_screen_bo_map_range;
253 pscreen->buffer_flush_mapped_range = nouveau_screen_bo_map_flush;
254 pscreen->buffer_unmap = nouveau_screen_bo_unmap;
255 pscreen->buffer_destroy = nouveau_screen_bo_del;
256
257 pscreen->fence_reference = nouveau_screen_fence_ref;
258 pscreen->fence_signalled = nouveau_screen_fence_signalled;
259 pscreen->fence_finish = nouveau_screen_fence_finish;
260
261 return 0;
262 }
263
264 void
265 nouveau_screen_fini(struct nouveau_screen *screen)
266 {
267 struct pipe_winsys *ws = screen->base.winsys;
268 nouveau_channel_free(&screen->channel);
269 ws->destroy(ws);
270 }
271