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_winsys.h"
43 #include "i965/brw_winsys.h"
44 #include "i965/brw_screen.h"
45 #include "i965/brw_reg.h"
46 #include "i965/brw_structs_dump.h"
48 #define MAX_VRAM (128*1024*1024)
52 extern int brw_disasm (FILE *file
,
53 const struct brw_instruction
*inst
,
56 extern int intel_decode(const uint32_t *data
,
61 struct xlib_brw_buffer
63 struct brw_winsys_buffer base
;
73 * Subclass of brw_winsys_screen for Xlib winsys
75 struct xlib_brw_winsys
77 struct brw_winsys_screen base
;
78 struct brw_chipset chipset
;
84 static struct xlib_brw_winsys
*
85 xlib_brw_winsys( struct brw_winsys_screen
*screen
)
87 return (struct xlib_brw_winsys
*)screen
;
91 static struct xlib_brw_buffer
*
92 xlib_brw_buffer( struct brw_winsys_buffer
*buffer
)
94 return (struct xlib_brw_buffer
*)buffer
;
99 const char *names
[BRW_BUFFER_TYPE_MAX
] = {
114 const char *usages
[BRW_USAGE_MAX
] = {
127 const char *data_types
[BRW_DATA_MAX
] =
132 "GS: SAMPLER_DEFAULT_COLOR",
153 static enum pipe_error
154 xlib_brw_bo_alloc( struct brw_winsys_screen
*sws
,
155 enum brw_buffer_type type
,
158 struct brw_winsys_buffer
**bo_out
)
160 struct xlib_brw_winsys
*xbw
= xlib_brw_winsys(sws
);
161 struct xlib_brw_buffer
*buf
;
163 if (BRW_DEBUG
& DEBUG_WINSYS
)
164 debug_printf("%s type %s sz %d align %d\n",
165 __FUNCTION__
, names
[type
], size
, alignment
);
167 buf
= CALLOC_STRUCT(xlib_brw_buffer
);
169 return PIPE_ERROR_OUT_OF_MEMORY
;
171 pipe_reference_init(&buf
->base
.reference
, 1);
173 buf
->offset
= align(xbw
->used
, alignment
);
175 buf
->virtual = MALLOC(size
);
176 buf
->base
.size
= size
;
179 xbw
->used
= align(xbw
->used
, alignment
) + size
;
180 if (xbw
->used
> MAX_VRAM
)
183 /* XXX: possibly rentrant call to bo_destroy:
185 bo_reference(bo_out
, &buf
->base
);
192 return PIPE_ERROR_OUT_OF_MEMORY
;
196 xlib_brw_bo_destroy( struct brw_winsys_buffer
*buffer
)
198 struct xlib_brw_buffer
*buf
= xlib_brw_buffer(buffer
);
204 xlib_brw_bo_emit_reloc( struct brw_winsys_buffer
*buffer
,
205 enum brw_buffer_usage usage
,
208 struct brw_winsys_buffer
*buffer2
)
210 struct xlib_brw_buffer
*buf
= xlib_brw_buffer(buffer
);
211 struct xlib_brw_buffer
*buf2
= xlib_brw_buffer(buffer2
);
213 if (BRW_DEBUG
& DEBUG_WINSYS
)
214 debug_printf("%s buf %p offset %x val %x + %x buf2 %p/%s/%s\n",
215 __FUNCTION__
, (void *)buffer
, offset
,
217 (void *)buffer2
, names
[buf2
->type
], usages
[usage
]);
219 *(uint32_t *)(buf
->virtual + offset
) = buf2
->offset
+ delta
;
225 xlib_brw_bo_exec( struct brw_winsys_buffer
*buffer
,
226 unsigned bytes_used
)
228 if (BRW_DEBUG
& DEBUG_WINSYS
)
229 debug_printf("execute buffer %p, bytes %d\n", (void *)buffer
, bytes_used
);
238 xlib_brw_bo_subdata(struct brw_winsys_buffer
*buffer
,
239 enum brw_buffer_data_type data_type
,
243 const struct brw_winsys_reloc
*reloc
,
246 struct xlib_brw_buffer
*buf
= xlib_brw_buffer(buffer
);
247 struct xlib_brw_winsys
*xbw
= xlib_brw_winsys(buffer
->sws
);
250 if (BRW_DEBUG
& DEBUG_WINSYS
)
251 debug_printf("%s buf %p off %d sz %d %s relocs: %d\n",
253 (void *)buffer
, offset
, size
,
254 data_types
[data_type
],
257 assert(buf
->base
.size
>= offset
+ size
);
258 memcpy(buf
->virtual + offset
, data
, size
);
260 /* Apply the relocations:
262 for (i
= 0; i
< nr_relocs
; i
++) {
263 if (BRW_DEBUG
& DEBUG_WINSYS
)
264 debug_printf("\treloc[%d] usage %s off %d value %x+%x\n",
265 i
, usages
[reloc
[i
].usage
], reloc
[i
].offset
,
266 xlib_brw_buffer(reloc
[i
].bo
)->offset
, reloc
[i
].delta
);
268 *(unsigned *)(buf
->virtual + offset
+ reloc
[i
].offset
) =
269 xlib_brw_buffer(reloc
[i
].bo
)->offset
+ reloc
[i
].delta
;
273 brw_dump_data( xbw
->chipset
.pci_id
,
275 buf
->offset
+ offset
,
276 buf
->virtual + offset
, size
);
284 xlib_brw_bo_is_busy(struct brw_winsys_buffer
*buffer
)
286 if (BRW_DEBUG
& DEBUG_WINSYS
)
287 debug_printf("%s %p\n", __FUNCTION__
, (void *)buffer
);
292 xlib_brw_bo_references(struct brw_winsys_buffer
*a
,
293 struct brw_winsys_buffer
*b
)
295 if (BRW_DEBUG
& DEBUG_WINSYS
)
296 debug_printf("%s %p %p\n", __FUNCTION__
, (void *)a
, (void *)b
);
300 static enum pipe_error
301 xlib_brw_check_aperture_space( struct brw_winsys_screen
*iws
,
302 struct brw_winsys_buffer
**buffers
,
305 unsigned tot_size
= 0;
308 for (i
= 0; i
< count
; i
++)
309 tot_size
+= buffers
[i
]->size
;
311 if (BRW_DEBUG
& DEBUG_WINSYS
)
312 debug_printf("%s %d bufs, tot_size: %d kb\n",
314 (tot_size
+ 1023) / 1024);
320 xlib_brw_bo_map(struct brw_winsys_buffer
*buffer
,
321 enum brw_buffer_data_type data_type
,
328 struct xlib_brw_buffer
*buf
= xlib_brw_buffer(buffer
);
330 if (BRW_DEBUG
& DEBUG_WINSYS
)
331 debug_printf("%s %p %s %s\n", __FUNCTION__
, (void *)buffer
,
332 write
? "read/write" : "read",
333 write
? data_types
[data_type
] : "");
344 xlib_brw_bo_flush_range( struct brw_winsys_buffer
*buffer
,
352 xlib_brw_bo_unmap(struct brw_winsys_buffer
*buffer
)
354 struct xlib_brw_buffer
*buf
= xlib_brw_buffer(buffer
);
356 if (BRW_DEBUG
& DEBUG_WINSYS
)
357 debug_printf("%s %p\n", __FUNCTION__
, (void *)buffer
);
360 assert(buf
->map_count
>= 0);
362 if (buf
->map_count
== 0 &&
367 /* Consider dumping new buffer contents here, using the
368 * flush-range info to minimize verbosity.
375 xlib_brw_bo_wait_idle( struct brw_winsys_buffer
*buffer
)
381 xlib_brw_winsys_destroy( struct brw_winsys_screen
*sws
)
383 struct xlib_brw_winsys
*xbw
= xlib_brw_winsys(sws
);
388 static struct brw_winsys_screen
*
389 xlib_create_brw_winsys_screen( void )
391 struct xlib_brw_winsys
*ws
;
393 ws
= CALLOC_STRUCT(xlib_brw_winsys
);
399 ws
->base
.destroy
= xlib_brw_winsys_destroy
;
400 ws
->base
.bo_alloc
= xlib_brw_bo_alloc
;
401 ws
->base
.bo_destroy
= xlib_brw_bo_destroy
;
402 ws
->base
.bo_emit_reloc
= xlib_brw_bo_emit_reloc
;
403 ws
->base
.bo_exec
= xlib_brw_bo_exec
;
404 ws
->base
.bo_subdata
= xlib_brw_bo_subdata
;
405 ws
->base
.bo_is_busy
= xlib_brw_bo_is_busy
;
406 ws
->base
.bo_references
= xlib_brw_bo_references
;
407 ws
->base
.check_aperture_space
= xlib_brw_check_aperture_space
;
408 ws
->base
.bo_map
= xlib_brw_bo_map
;
409 ws
->base
.bo_flush_range
= xlib_brw_bo_flush_range
;
410 ws
->base
.bo_unmap
= xlib_brw_bo_unmap
;
411 ws
->base
.bo_wait_idle
= xlib_brw_bo_wait_idle
;
417 /***********************************************************************
418 * Implementation of Xlib co-state-tracker's winsys interface
422 xlib_i965_display_surface(struct xmesa_buffer
*xm_buffer
,
423 struct pipe_surface
*surf
)
425 struct brw_surface
*surface
= brw_surface(surf
);
426 struct xlib_brw_buffer
*bo
= xlib_brw_buffer(surface
->bo
);
428 if (BRW_DEBUG
& DEBUG_WINSYS
)
429 debug_printf("%s offset %x+%x sz %dx%d\n", __FUNCTION__
,
431 surface
->draw_offset
,
437 xlib_i965_flush_frontbuffer(struct pipe_screen
*screen
,
438 struct pipe_surface
*surf
,
439 void *context_private
)
441 xlib_i965_display_surface(NULL
, surf
);
445 static struct pipe_screen
*
446 xlib_create_i965_screen( void )
448 struct brw_winsys_screen
*winsys
;
449 struct pipe_screen
*screen
;
451 winsys
= xlib_create_brw_winsys_screen();
455 screen
= brw_create_screen(winsys
, PCI_CHIP_GM45_GM
);
459 xlib_brw_winsys(winsys
)->chipset
= brw_screen(screen
)->chipset
;
461 screen
->flush_frontbuffer
= xlib_i965_flush_frontbuffer
;
466 winsys
->destroy( winsys
);
475 struct xm_driver xlib_i965_driver
=
477 .create_pipe_screen
= xlib_create_i965_screen
,
478 .display_surface
= xlib_i965_display_surface
482 /* Register this driver at library load:
484 static void _init( void ) __attribute__((constructor
));
485 static void _init( void )
487 xmesa_set_driver( &xlib_i965_driver
);
492 /***********************************************************************
494 * Butt-ugly hack to convince the linker not to throw away public GL
495 * symbols (they are all referenced from getprocaddress, I guess).
497 extern void (*linker_foo(const unsigned char *procName
))();
498 extern void (*glXGetProcAddress(const unsigned char *procName
))();
500 extern void (*linker_foo(const unsigned char *procName
))()
502 return glXGetProcAddress(procName
);