i965g: add missing buffer functions
[mesa.git] / src / gallium / winsys / drm / i965 / xlib / xlib_i965.c
1 /**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 *
26 *
27 **************************************************************************/
28
29 /*
30 * Authors:
31 * Keith Whitwell
32 * Brian Paul
33 */
34
35
36 #include "util/u_memory.h"
37 #include "util/u_math.h"
38 #include "pipe/p_context.h"
39
40 #include "xm_winsys.h"
41
42 #include "i965/brw_winsys.h"
43 #include "i965/brw_screen.h"
44 #include "i965/brw_reg.h"
45
46 #define MAX_VRAM (128*1024*1024)
47
48 struct xlib_brw_buffer
49 {
50 struct brw_winsys_buffer base;
51 unsigned offset;
52 unsigned type;
53 char *virtual;
54 unsigned cheesy_refcount;
55 int map_count;
56 };
57
58
59 /**
60 * Subclass of brw_winsys_screen for Xlib winsys
61 */
62 struct xlib_brw_winsys
63 {
64 struct brw_winsys_screen base;
65 unsigned offset;
66 };
67
68 static struct xlib_brw_winsys *
69 xlib_brw_winsys( struct brw_winsys_screen *screen )
70 {
71 return (struct xlib_brw_winsys *)screen;
72 }
73
74
75 static struct xlib_brw_buffer *
76 xlib_brw_buffer( struct brw_winsys_buffer *buffer )
77 {
78 return (struct xlib_brw_buffer *)buffer;
79 }
80
81
82
83 const char *names[BRW_BUFFER_TYPE_MAX] = {
84 "texture",
85 "scanout",
86 "vertex",
87 "curbe",
88 "query",
89 "shader_constants",
90 "wm_scratch",
91 "batch",
92 "state_cache",
93 "pixel",
94 "generic",
95 };
96
97 const char *usages[BRW_USAGE_MAX] = {
98 "state",
99 "query_result",
100 "render_target",
101 "depth_buffer",
102 "blit_source",
103 "blit_dest",
104 "sampler",
105 "vertex",
106 "scratch"
107 };
108
109 static struct brw_winsys_buffer *
110 xlib_brw_bo_alloc( struct brw_winsys_screen *sws,
111 enum brw_buffer_type type,
112 unsigned size,
113 unsigned alignment )
114 {
115 struct xlib_brw_winsys *xbw = xlib_brw_winsys(sws);
116 struct xlib_brw_buffer *buf;
117
118 debug_printf("%s type %d sz %d align %d\n",
119 __FUNCTION__, type, size, alignment );
120
121 buf = CALLOC_STRUCT(xlib_brw_buffer);
122 if (!buf)
123 return NULL;
124
125 buf->offset = align(xbw->offset, alignment);
126 buf->type = type;
127 buf->virtual = MALLOC(size);
128 buf->base.offset = &buf->offset; /* hmm, cheesy */
129 buf->base.size = size;
130
131 xbw->offset = align(xbw->offset, alignment) + size;
132 if (xbw->offset > MAX_VRAM)
133 goto err;
134
135 return &buf->base;
136
137 err:
138 assert(0);
139 FREE(buf);
140 return NULL;
141 }
142
143 static void
144 xlib_brw_bo_reference( struct brw_winsys_buffer *buffer )
145 {
146 struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
147
148 buf->cheesy_refcount++;
149 }
150
151 static void
152 xlib_brw_bo_unreference( struct brw_winsys_buffer *buffer )
153 {
154 struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
155
156 if (--buf->cheesy_refcount == 0) {
157 FREE(buffer);
158 }
159 }
160
161 static int
162 xlib_brw_bo_emit_reloc( struct brw_winsys_buffer *buffer,
163 enum brw_buffer_usage usage,
164 unsigned delta,
165 unsigned offset,
166 struct brw_winsys_buffer *buffer2)
167 {
168 struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
169 struct xlib_brw_buffer *buf2 = xlib_brw_buffer(buffer2);
170
171 debug_printf("%s buf %p offset %x val %x + %x buf2 %p/%s/%s\n",
172 __FUNCTION__, (void *)buffer, offset,
173 buf2->offset, delta,
174 (void *)buffer2, names[buf2->type], usages[usage]);
175
176 *(uint32_t *)(buf->virtual + offset) = buf2->offset + delta;
177
178 return 0;
179 }
180
181 static int
182 xlib_brw_bo_exec( struct brw_winsys_buffer *buffer,
183 unsigned bytes_used )
184 {
185 debug_printf("execute buffer %p, bytes %d\n", (void *)buffer, bytes_used);
186
187 return 0;
188 }
189
190 static int
191 xlib_brw_bo_subdata(struct brw_winsys_buffer *buffer,
192 size_t offset,
193 size_t size,
194 const void *data)
195 {
196 struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
197
198 debug_printf("%s buf %p off %d sz %d data %p\n",
199 __FUNCTION__,
200 (void *)buffer, offset, size, data);
201
202 memcpy(buf->virtual + offset, data, size);
203 return 0;
204 }
205
206
207 static boolean
208 xlib_brw_bo_is_busy(struct brw_winsys_buffer *buffer)
209 {
210 debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
211 return TRUE;
212 }
213
214 static boolean
215 xlib_brw_bo_references(struct brw_winsys_buffer *a,
216 struct brw_winsys_buffer *b)
217 {
218 debug_printf("%s %p %p\n", __FUNCTION__, (void *)a, (void *)b);
219 return TRUE;
220 }
221
222 static boolean
223 xlib_brw_check_aperture_space( struct brw_winsys_screen *iws,
224 struct brw_winsys_buffer **buffers,
225 unsigned count )
226 {
227 unsigned tot_size = 0;
228 unsigned i;
229
230 for (i = 0; i < count; i++)
231 tot_size += buffers[i]->size;
232
233 debug_printf("%s %d bufs, tot_size: %d kb\n",
234 __FUNCTION__, count,
235 (tot_size + 1023) / 1024);
236
237 return TRUE;
238 }
239
240 static void *
241 xlib_brw_bo_map(struct brw_winsys_buffer *buffer,
242 boolean write)
243 {
244 struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
245
246 debug_printf("%s %p %s\n", __FUNCTION__, (void *)buffer,
247 write ? "read/write" : "read");
248
249 buf->map_count++;
250 return buf->virtual;
251 }
252
253 static void
254 xlib_brw_bo_unmap(struct brw_winsys_buffer *buffer)
255 {
256 struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
257
258 debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
259
260 --buf->map_count;
261 assert(buf->map_count >= 0);
262 }
263
264
265 static void
266 xlib_brw_winsys_destroy( struct brw_winsys_screen *screen )
267 {
268 /* XXX: free all buffers */
269 FREE(screen);
270 }
271
272 static struct brw_winsys_screen *
273 xlib_create_brw_winsys_screen( void )
274 {
275 struct xlib_brw_winsys *ws;
276
277 ws = CALLOC_STRUCT(xlib_brw_winsys);
278 if (!ws)
279 return NULL;
280
281 ws->base.destroy = xlib_brw_winsys_destroy;
282 ws->base.bo_alloc = xlib_brw_bo_alloc;
283 ws->base.bo_reference = xlib_brw_bo_reference;
284 ws->base.bo_unreference = xlib_brw_bo_unreference;
285 ws->base.bo_emit_reloc = xlib_brw_bo_emit_reloc;
286 ws->base.bo_exec = xlib_brw_bo_exec;
287 ws->base.bo_subdata = xlib_brw_bo_subdata;
288 ws->base.bo_is_busy = xlib_brw_bo_is_busy;
289 ws->base.bo_references = xlib_brw_bo_references;
290 ws->base.check_aperture_space = xlib_brw_check_aperture_space;
291 ws->base.bo_map = xlib_brw_bo_map;
292 ws->base.bo_unmap = xlib_brw_bo_unmap;
293
294 return &ws->base;
295 }
296
297
298 /***********************************************************************
299 * Implementation of Xlib co-state-tracker's winsys interface
300 */
301
302 static struct pipe_screen *
303 xlib_create_i965_screen( void )
304 {
305 struct brw_winsys_screen *winsys;
306 struct pipe_screen *screen;
307
308 winsys = xlib_create_brw_winsys_screen();
309 if (winsys == NULL)
310 return NULL;
311
312 screen = brw_create_screen(winsys,
313 PCI_CHIP_GM45_GM);
314 if (screen == NULL)
315 goto fail;
316
317 return screen;
318
319 fail:
320 if (winsys)
321 winsys->destroy( winsys );
322
323 return NULL;
324 }
325
326
327 static struct pipe_context *
328 xlib_create_i965_context( struct pipe_screen *screen,
329 void *context_private )
330 {
331 struct pipe_context *pipe;
332
333 pipe = brw_create_context(screen);
334 if (pipe == NULL)
335 goto fail;
336
337 pipe->priv = context_private;
338 return pipe;
339
340 fail:
341 /* Free stuff here */
342 return NULL;
343 }
344
345
346 static void
347 xlib_i965_display_surface(struct xmesa_buffer *xm_buffer,
348 struct pipe_surface *surf)
349 {
350 /* struct brw_texture *texture = brw_texture(surf->texture); */
351
352 debug_printf("%s tex %p, sz %dx%d\n", __FUNCTION__,
353 (void *)surf->texture,
354 surf->texture->width[0],
355 surf->texture->height[0]);
356 }
357
358
359 struct xm_driver xlib_i965_driver =
360 {
361 .create_pipe_screen = xlib_create_i965_screen,
362 .create_pipe_context = xlib_create_i965_context,
363 .display_surface = xlib_i965_display_surface
364 };
365
366
367 /* Register this driver at library load:
368 */
369 static void _init( void ) __attribute__((constructor));
370 static void _init( void )
371 {
372 xmesa_set_driver( &xlib_i965_driver );
373 }
374
375
376
377 /***********************************************************************
378 *
379 * Butt-ugly hack to convince the linker not to throw away public GL
380 * symbols (they are all referenced from getprocaddress, I guess).
381 */
382 extern void (*linker_foo(const unsigned char *procName))();
383 extern void (*glXGetProcAddress(const unsigned char *procName))();
384
385 extern void (*linker_foo(const unsigned char *procName))()
386 {
387 return glXGetProcAddress(procName);
388 }