gallium: fix more missing includes from various places
[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;
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 flags |= NOUVEAU_BO_TILED;
81 if (usage & NOUVEAU_BUFFER_USAGE_ZETA)
82 flags |= NOUVEAU_BO_ZTILE;
83 }
84 }
85
86 ret = nouveau_bo_new(dev, flags, alignment, size, &bo);
87 if (ret)
88 return NULL;
89
90 return nouveau_screen_bo_skel(pscreen, bo, alignment, usage, size);
91 }
92
93 static struct pipe_buffer *
94 nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes)
95 {
96 struct nouveau_device *dev = nouveau_screen(pscreen)->device;
97 struct nouveau_bo *bo = NULL;
98 int ret;
99
100 ret = nouveau_bo_user(dev, ptr, bytes, &bo);
101 if (ret)
102 return NULL;
103
104 return nouveau_screen_bo_skel(pscreen, bo, 0, 0, bytes);
105 }
106
107 static inline uint32_t
108 nouveau_screen_map_flags(unsigned pipe)
109 {
110 uint32_t flags = 0;
111
112 if (pipe & PIPE_BUFFER_USAGE_CPU_READ)
113 flags |= NOUVEAU_BO_RD;
114 if (pipe & PIPE_BUFFER_USAGE_CPU_WRITE)
115 flags |= NOUVEAU_BO_WR;
116 if (pipe & PIPE_BUFFER_USAGE_DISCARD)
117 flags |= NOUVEAU_BO_INVAL;
118 if (pipe & PIPE_BUFFER_USAGE_DONTBLOCK)
119 flags |= NOUVEAU_BO_NOWAIT;
120 else
121 if (pipe & 0 /*PIPE_BUFFER_USAGE_UNSYNCHRONIZED*/)
122 flags |= NOUVEAU_BO_NOSYNC;
123
124 return flags;
125 }
126
127 static void *
128 nouveau_screen_bo_map(struct pipe_screen *pscreen, struct pipe_buffer *pb,
129 unsigned usage)
130 {
131 struct nouveau_bo *bo = nouveau_bo(pb);
132 struct nouveau_screen *nscreen = nouveau_screen(pscreen);
133 int ret;
134
135 if (nscreen->pre_pipebuffer_map_callback) {
136 ret = nscreen->pre_pipebuffer_map_callback(pscreen, pb, usage);
137 if (ret) {
138 debug_printf("pre_pipebuffer_map_callback failed %d\n",
139 ret);
140 return NULL;
141 }
142 }
143
144 ret = nouveau_bo_map(bo, nouveau_screen_map_flags(usage));
145 if (ret) {
146 debug_printf("map failed: %d\n", ret);
147 return NULL;
148 }
149
150 return bo->map;
151 }
152
153 static void *
154 nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct pipe_buffer *pb,
155 unsigned offset, unsigned length, unsigned usage)
156 {
157 struct nouveau_bo *bo = nouveau_bo(pb);
158 struct nouveau_screen *nscreen = nouveau_screen(pscreen);
159 uint32_t flags = nouveau_screen_map_flags(usage);
160 int ret;
161
162 if (nscreen->pre_pipebuffer_map_callback) {
163 ret = nscreen->pre_pipebuffer_map_callback(pscreen, pb, usage);
164 if (ret) {
165 debug_printf("pre_pipebuffer_map_callback failed %d\n",
166 ret);
167 return NULL;
168 }
169 }
170
171 ret = nouveau_bo_map_range(bo, offset, length, flags);
172 if (ret) {
173 nouveau_bo_unmap(bo);
174 if (!(flags & NOUVEAU_BO_NOWAIT) || ret != -EBUSY)
175 debug_printf("map_range failed: %d\n", ret);
176 return NULL;
177 }
178
179 return (char *)bo->map - offset; /* why gallium? why? */
180 }
181
182 static void
183 nouveau_screen_bo_map_flush(struct pipe_screen *pscreen, struct pipe_buffer *pb,
184 unsigned offset, unsigned length)
185 {
186 struct nouveau_bo *bo = nouveau_bo(pb);
187
188 nouveau_bo_map_flush(bo, offset, length);
189 }
190
191 static void
192 nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct pipe_buffer *pb)
193 {
194 struct nouveau_bo *bo = nouveau_bo(pb);
195
196 nouveau_bo_unmap(bo);
197 }
198
199 static void
200 nouveau_screen_bo_del(struct pipe_buffer *pb)
201 {
202 struct nouveau_bo *bo = nouveau_bo(pb);
203
204 nouveau_bo_ref(NULL, &bo);
205 FREE(pb);
206 }
207
208 static void
209 nouveau_screen_fence_ref(struct pipe_screen *pscreen,
210 struct pipe_fence_handle **ptr,
211 struct pipe_fence_handle *pfence)
212 {
213 *ptr = pfence;
214 }
215
216 static int
217 nouveau_screen_fence_signalled(struct pipe_screen *screen,
218 struct pipe_fence_handle *pfence,
219 unsigned flags)
220 {
221 return 0;
222 }
223
224 static int
225 nouveau_screen_fence_finish(struct pipe_screen *screen,
226 struct pipe_fence_handle *pfence,
227 unsigned flags)
228 {
229 return 0;
230 }
231
232 int
233 nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
234 {
235 struct pipe_screen *pscreen = &screen->base;
236 int ret;
237
238 ret = nouveau_channel_alloc(dev, 0xbeef0201, 0xbeef0202,
239 &screen->channel);
240 if (ret)
241 return ret;
242 screen->device = dev;
243
244 pscreen->get_name = nouveau_screen_get_name;
245 pscreen->get_vendor = nouveau_screen_get_vendor;
246
247 pscreen->buffer_create = nouveau_screen_bo_new;
248 pscreen->user_buffer_create = nouveau_screen_bo_user;
249 pscreen->buffer_map = nouveau_screen_bo_map;
250 pscreen->buffer_map_range = nouveau_screen_bo_map_range;
251 pscreen->buffer_flush_mapped_range = nouveau_screen_bo_map_flush;
252 pscreen->buffer_unmap = nouveau_screen_bo_unmap;
253 pscreen->buffer_destroy = nouveau_screen_bo_del;
254
255 pscreen->fence_reference = nouveau_screen_fence_ref;
256 pscreen->fence_signalled = nouveau_screen_fence_signalled;
257 pscreen->fence_finish = nouveau_screen_fence_finish;
258
259 return 0;
260 }
261
262 void
263 nouveau_screen_fini(struct nouveau_screen *screen)
264 {
265 struct pipe_winsys *ws = screen->base.winsys;
266 nouveau_channel_free(&screen->channel);
267 ws->destroy(ws);
268 }
269