1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
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:
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.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
27 **************************************************************************/
36 #include "util/u_memory.h"
37 #include "util/u_math.h"
38 #include "pipe/p_error.h"
39 #include "pipe/p_context.h"
41 #include "xm_public.h"
43 #include "i965/brw_winsys.h"
44 #include "i965/brw_screen.h"
45 #include "i965/brw_resource.h"
46 #include "i965/brw_reg.h"
47 #include "i965/brw_structs_dump.h"
49 #define MAX_VRAM (128*1024*1024)
53 extern int brw_disasm (FILE *file,
54 const struct brw_instruction *inst,
57 extern int intel_decode(const uint32_t *data,
62 struct xlib_brw_buffer
64 struct brw_winsys_buffer base;
74 * Subclass of brw_winsys_screen for Xlib winsys
76 struct xlib_brw_winsys
78 struct brw_winsys_screen base;
79 struct brw_chipset chipset;
85 static struct xlib_brw_winsys *
86 xlib_brw_winsys( struct brw_winsys_screen *screen )
88 return (struct xlib_brw_winsys *)screen;
92 static struct xlib_brw_buffer *
93 xlib_brw_buffer( struct brw_winsys_buffer *buffer )
95 return (struct xlib_brw_buffer *)buffer;
100 const char *names[BRW_BUFFER_TYPE_MAX] = {
115 const char *usages[BRW_USAGE_MAX] = {
128 const char *data_types[BRW_DATA_MAX] =
133 "GS: SAMPLER_DEFAULT_COLOR",
154 static enum pipe_error
155 xlib_brw_bo_alloc( struct brw_winsys_screen *sws,
156 enum brw_buffer_type type,
159 struct brw_winsys_buffer **bo_out )
161 struct xlib_brw_winsys *xbw = xlib_brw_winsys(sws);
162 struct xlib_brw_buffer *buf;
164 if (BRW_DEBUG & DEBUG_WINSYS)
165 debug_printf("%s type %s sz %d align %d\n",
166 __FUNCTION__, names[type], size, alignment );
168 buf = CALLOC_STRUCT(xlib_brw_buffer);
170 return PIPE_ERROR_OUT_OF_MEMORY;
172 pipe_reference_init(&buf->base.reference, 1);
174 buf->offset = align(xbw->used, alignment);
176 buf->virtual = MALLOC(size);
177 buf->base.size = size;
180 xbw->used = align(xbw->used, alignment) + size;
181 if (xbw->used > MAX_VRAM)
184 /* XXX: possibly rentrant call to bo_destroy:
186 bo_reference(bo_out, &buf->base);
193 return PIPE_ERROR_OUT_OF_MEMORY;
197 xlib_brw_bo_destroy( struct brw_winsys_buffer *buffer )
199 struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
205 xlib_brw_bo_emit_reloc( struct brw_winsys_buffer *buffer,
206 enum brw_buffer_usage usage,
209 struct brw_winsys_buffer *buffer2)
211 struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
212 struct xlib_brw_buffer *buf2 = xlib_brw_buffer(buffer2);
214 if (BRW_DEBUG & DEBUG_WINSYS)
215 debug_printf("%s buf %p offset %x val %x + %x buf2 %p/%s/%s\n",
216 __FUNCTION__, (void *)buffer, offset,
218 (void *)buffer2, names[buf2->type], usages[usage]);
220 *(uint32_t *)(buf->virtual + offset) = buf2->offset + delta;
226 xlib_brw_bo_exec( struct brw_winsys_buffer *buffer,
227 unsigned bytes_used )
229 if (BRW_DEBUG & DEBUG_WINSYS)
230 debug_printf("execute buffer %p, bytes %d\n", (void *)buffer, bytes_used);
239 xlib_brw_bo_subdata(struct brw_winsys_buffer *buffer,
240 enum brw_buffer_data_type data_type,
244 const struct brw_winsys_reloc *reloc,
247 struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
248 struct xlib_brw_winsys *xbw = xlib_brw_winsys(buffer->sws);
251 if (BRW_DEBUG & DEBUG_WINSYS)
252 debug_printf("%s buf %p off %d sz %d %s relocs: %d\n",
254 (void *)buffer, offset, size,
255 data_types[data_type],
258 assert(buf->base.size >= offset + size);
259 memcpy(buf->virtual + offset, data, size);
261 /* Apply the relocations:
263 for (i = 0; i < nr_relocs; i++) {
264 if (BRW_DEBUG & DEBUG_WINSYS)
265 debug_printf("\treloc[%d] usage %s off %d value %x+%x\n",
266 i, usages[reloc[i].usage], reloc[i].offset,
267 xlib_brw_buffer(reloc[i].bo)->offset, reloc[i].delta);
269 *(unsigned *)(buf->virtual + offset + reloc[i].offset) =
270 xlib_brw_buffer(reloc[i].bo)->offset + reloc[i].delta;
274 brw_dump_data( xbw->chipset.pci_id,
276 buf->offset + offset,
277 buf->virtual + offset, size );
285 xlib_brw_bo_is_busy(struct brw_winsys_buffer *buffer)
287 if (BRW_DEBUG & DEBUG_WINSYS)
288 debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
293 xlib_brw_bo_references(struct brw_winsys_buffer *a,
294 struct brw_winsys_buffer *b)
296 if (BRW_DEBUG & DEBUG_WINSYS)
297 debug_printf("%s %p %p\n", __FUNCTION__, (void *)a, (void *)b);
301 static enum pipe_error
302 xlib_brw_check_aperture_space( struct brw_winsys_screen *iws,
303 struct brw_winsys_buffer **buffers,
306 unsigned tot_size = 0;
309 for (i = 0; i < count; i++)
310 tot_size += buffers[i]->size;
312 if (BRW_DEBUG & DEBUG_WINSYS)
313 debug_printf("%s %d bufs, tot_size: %d kb\n",
315 (tot_size + 1023) / 1024);
321 xlib_brw_bo_map(struct brw_winsys_buffer *buffer,
322 enum brw_buffer_data_type data_type,
329 struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
331 if (BRW_DEBUG & DEBUG_WINSYS)
332 debug_printf("%s %p %s %s\n", __FUNCTION__, (void *)buffer,
333 write ? "read/write" : "read",
334 write ? data_types[data_type] : "");
345 xlib_brw_bo_flush_range( struct brw_winsys_buffer *buffer,
353 xlib_brw_bo_unmap(struct brw_winsys_buffer *buffer)
355 struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
357 if (BRW_DEBUG & DEBUG_WINSYS)
358 debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
361 assert(buf->map_count >= 0);
363 if (buf->map_count == 0 &&
368 /* Consider dumping new buffer contents here, using the
369 * flush-range info to minimize verbosity.
376 xlib_brw_bo_wait_idle( struct brw_winsys_buffer *buffer )
382 xlib_brw_winsys_destroy( struct brw_winsys_screen *sws )
384 struct xlib_brw_winsys *xbw = xlib_brw_winsys(sws);
389 static struct brw_winsys_screen *
390 xlib_create_brw_winsys_screen( void )
392 struct xlib_brw_winsys *ws;
394 ws = CALLOC_STRUCT(xlib_brw_winsys);
399 ws->base.pci_id = PCI_CHIP_GM45_GM;
401 ws->base.destroy = xlib_brw_winsys_destroy;
402 ws->base.bo_alloc = xlib_brw_bo_alloc;
403 ws->base.bo_destroy = xlib_brw_bo_destroy;
404 ws->base.bo_emit_reloc = xlib_brw_bo_emit_reloc;
405 ws->base.bo_exec = xlib_brw_bo_exec;
406 ws->base.bo_subdata = xlib_brw_bo_subdata;
407 ws->base.bo_is_busy = xlib_brw_bo_is_busy;
408 ws->base.bo_references = xlib_brw_bo_references;
409 ws->base.check_aperture_space = xlib_brw_check_aperture_space;
410 ws->base.bo_map = xlib_brw_bo_map;
411 ws->base.bo_flush_range = xlib_brw_bo_flush_range;
412 ws->base.bo_unmap = xlib_brw_bo_unmap;
413 ws->base.bo_wait_idle = xlib_brw_bo_wait_idle;
419 /***********************************************************************
420 * Implementation of Xlib co-state-tracker's winsys interface
424 xlib_i965_display_surface(struct xmesa_buffer *xm_buffer,
425 struct pipe_resource *resource,
426 unsigned level, unsigned layer)
428 struct brw_texture *tex = brw_texture(resource);
429 struct xlib_brw_buffer *bo = xlib_brw_buffer(tex->bo);
430 /* not sure if the resource is really useful here but
431 since it was never implemented anyway... */
432 if (BRW_DEBUG & DEBUG_WINSYS)
433 debug_printf("%s level %u layer %u offset %x base sz %dx%d\n", __FUNCTION__,
441 xlib_i965_flush_frontbuffer(struct pipe_screen *screen,
442 struct pipe_resource *resource,
443 unsigned level, unsigned layer,
444 void *context_private)
446 xlib_i965_display_surface(NULL, resource, level, layer);
450 static struct pipe_screen *
451 xlib_create_i965_screen( void )
453 struct brw_winsys_screen *winsys;
454 struct pipe_screen *screen;
456 winsys = xlib_create_brw_winsys_screen();
460 screen = brw_create_screen(winsys);
464 xlib_brw_winsys(winsys)->chipset = brw_screen(screen)->chipset;
466 screen->flush_frontbuffer = xlib_i965_flush_frontbuffer;
471 winsys->destroy( winsys );
480 struct xm_driver xlib_i965_driver =
482 .create_pipe_screen = xlib_create_i965_screen,
483 .display_surface = xlib_i965_display_surface
487 /* Register this driver at library load:
489 static void _init( void ) __attribute__((constructor));
490 static void _init( void )
492 xmesa_set_driver( &xlib_i965_driver );
497 /***********************************************************************
499 * Butt-ugly hack to convince the linker not to throw away public GL
500 * symbols (they are all referenced from getprocaddress, I guess).
502 extern void (*linker_foo(const unsigned char *procName))();
503 extern void (*glXGetProcAddress(const unsigned char *procName))();
505 extern void (*linker_foo(const unsigned char *procName))()
507 return glXGetProcAddress(procName);