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 "state_trackers/xlib/glxheader.h"
37 //#include "state_trackers/xlib/xmesaP.h"
39 #include "pipe/p_winsys.h"
40 #include "pipe/p_inlines.h"
41 #include "util/u_math.h"
42 #include "util/u_memory.h"
43 #include "i965simple/brw_winsys.h"
44 #include "i965simple/brw_screen.h"
46 #include "xlib_brw_aub.h"
58 boolean dump_on_unmap
;
63 struct aub_pipe_winsys
{
64 struct pipe_winsys winsys
;
66 struct brw_aubfile
*aubfile
;
68 /* This is simple, isn't it:
76 /* Turn a pipe winsys into an aub/pipe winsys:
78 static inline struct aub_pipe_winsys
*
79 aub_pipe_winsys( struct pipe_winsys
*winsys
)
81 return (struct aub_pipe_winsys
*)winsys
;
86 static INLINE
struct aub_buffer
*
87 aub_bo( struct pipe_buffer
*bo
)
89 return (struct aub_buffer
*)bo
;
92 static INLINE
struct pipe_buffer
*
93 pipe_bo( struct aub_buffer
*bo
)
95 return (struct pipe_buffer
*)bo
;
101 static void *aub_buffer_map(struct pipe_winsys
*winsys
,
102 struct pipe_buffer
*buf
,
105 struct aub_buffer
*sbo
= aub_bo(buf
);
109 if (flags
& PIPE_BUFFER_USAGE_CPU_WRITE
)
110 sbo
->dump_on_unmap
= 1;
116 static void aub_buffer_unmap(struct pipe_winsys
*winsys
,
117 struct pipe_buffer
*buf
)
119 struct aub_pipe_winsys
*iws
= aub_pipe_winsys(winsys
);
120 struct aub_buffer
*sbo
= aub_bo(buf
);
124 if (sbo
->map_count
== 0 &&
125 sbo
->dump_on_unmap
) {
127 sbo
->dump_on_unmap
= 0;
129 brw_aub_gtt_data( iws
->aubfile
,
140 aub_buffer_destroy(struct pipe_winsys
*winsys
,
141 struct pipe_buffer
*buf
)
148 void xlib_brw_commands_aub(struct pipe_winsys
*winsys
,
152 struct aub_pipe_winsys
*iws
= aub_pipe_winsys(winsys
);
153 unsigned size
= nr_dwords
* 4;
155 assert(iws
->used
+ size
< iws
->size
);
157 brw_aub_gtt_cmds( iws
->aubfile
,
158 AUB_BUF_START
+ iws
->used
,
160 nr_dwords
* sizeof(int) );
162 iws
->used
+= align(size
, 4096);
168 static struct aub_pipe_winsys
*global_winsys
= NULL
;
173 /* Pipe has no concept of pools. We choose the tex/region pool
176 static struct pipe_buffer
*
177 aub_buffer_create(struct pipe_winsys
*winsys
,
182 struct aub_pipe_winsys
*iws
= aub_pipe_winsys(winsys
);
183 struct aub_buffer
*sbo
= CALLOC_STRUCT(aub_buffer
);
187 /* Could reuse buffers that are not referenced in current
188 * batchbuffer. Can't do that atm, so always reallocate:
190 assert(iws
->used
+ size
< iws
->size
);
191 sbo
->data
= iws
->pool
+ iws
->used
;
192 sbo
->offset
= AUB_BUF_START
+ iws
->used
;
193 iws
->used
+= align(size
, 4096);
201 static struct pipe_buffer
*
202 aub_user_buffer_create(struct pipe_winsys
*winsys
, void *ptr
, unsigned bytes
)
204 struct aub_buffer
*sbo
;
206 /* Lets hope this is meant for upload, not as a result!
208 sbo
= aub_bo(aub_buffer_create( winsys
, 0, 0, 0 ));
217 /* The state tracker (should!) keep track of whether the fake
218 * frontbuffer has been touched by any rendering since the last time
219 * we copied its contents to the real frontbuffer. Our task is easy:
222 aub_flush_frontbuffer( struct pipe_winsys
*winsys
,
223 struct pipe_surface
*surface
,
224 void *context_private
)
226 // struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys);
227 brw_aub_dump_bmp( global_winsys
->aubfile
,
229 aub_bo(surface
->buffer
)->offset
);
232 static struct pipe_surface
*
233 aub_i915_surface_alloc(struct pipe_winsys
*winsys
)
235 struct pipe_surface
*surf
= CALLOC_STRUCT(pipe_surface
);
238 surf
->winsys
= winsys
;
245 * Round n up to next multiple.
247 static INLINE
unsigned
248 round_up(unsigned n
, unsigned multiple
)
250 return (n
+ multiple
- 1) & ~(multiple
- 1);
254 aub_i915_surface_alloc_storage(struct pipe_winsys
*winsys
,
255 struct pipe_surface
*surf
,
256 unsigned width
, unsigned height
,
257 enum pipe_format format
,
261 const unsigned alignment
= 64;
264 surf
->height
= height
;
265 surf
->format
= format
;
266 pf_get_block(format
, &surf
->block
);
267 surf
->nblocksx
= pf_get_nblocksx(&surf
->block
, width
);
268 surf
->nblocksy
= pf_get_nblocksy(&surf
->block
, height
);
269 surf
->stride
= round_up(surf
->nblocksx
* surf
->block
.size
, alignment
);
272 assert(!surf
->buffer
);
273 surf
->buffer
= winsys
->buffer_create(winsys
, alignment
,
274 PIPE_BUFFER_USAGE_PIXEL
,
275 surf
->stride
* surf
->nblocksy
);
283 aub_i915_surface_release(struct pipe_winsys
*winsys
, struct pipe_surface
**s
)
285 struct pipe_surface
*surf
= *s
;
287 if (surf
->refcount
== 0) {
289 winsys_buffer_reference(winsys
, &surf
->buffer
, NULL
);
298 aub_get_name( struct pipe_winsys
*winsys
)
304 xlib_brw_destroy_pipe_winsys_aub( struct pipe_winsys
*winsys
)
307 struct aub_pipe_winsys
*iws
= aub_pipe_winsys(winsys
);
308 brw_aub_destroy(iws
->aubfile
);
315 static struct pipe_winsys
*
316 xlib_create_brw_winsys( void )
318 struct aub_pipe_winsys
*iws
= CALLOC_STRUCT( aub_pipe_winsys
);
320 /* Fill in this struct with callbacks that pipe will need to
321 * communicate with the window system, buffer manager, etc.
323 * Pipe would be happy with a malloc based memory manager, but
324 * the SwapBuffers implementation in this winsys driver requires
325 * that rendering be done to an appropriate _DriBufferObject.
327 iws
->winsys
.buffer_create
= aub_buffer_create
;
328 iws
->winsys
.user_buffer_create
= aub_user_buffer_create
;
329 iws
->winsys
.buffer_map
= aub_buffer_map
;
330 iws
->winsys
.buffer_unmap
= aub_buffer_unmap
;
331 iws
->winsys
.buffer_destroy
= aub_buffer_destroy
;
332 iws
->winsys
.flush_frontbuffer
= aub_flush_frontbuffer
;
333 iws
->winsys
.get_name
= aub_get_name
;
334 iws
->winsys
.destroy
= xlib_brw_destroy_pipe_winsys_aub
;
336 iws
->winsys
.surface_alloc
= aub_i915_surface_alloc
;
337 iws
->winsys
.surface_alloc_storage
= aub_i915_surface_alloc_storage
;
338 iws
->winsys
.surface_release
= aub_i915_surface_release
;
340 iws
->aubfile
= brw_aubfile_create();
341 iws
->size
= AUB_BUF_SIZE
;
342 iws
->pool
= malloc(AUB_BUF_SIZE
);
344 /* HACK: static copy of this pointer:
346 assert(global_winsys
== NULL
);
353 static struct pipe_screen
*
354 xlib_create_brw_screen( struct pipe_winsys
*winsys
)
356 return brw_create_screen(winsys
, 0/* XXX pci_id */);
360 /* These per-screen functions are acually made available to the driver
361 * through the brw_winsys (per-context) entity.
363 unsigned xlib_brw_get_buffer_offset( struct pipe_winsys
*pws
,
364 struct pipe_buffer
*buf
,
365 unsigned access_flags
)
367 return aub_bo(buf
)->offset
;
370 void xlib_brw_buffer_subdata_typed( struct pipe_winsys
*pws
,
371 struct pipe_buffer
*buf
,
372 unsigned long offset
,
377 unsigned aub_type
= DW_GENERAL_STATE
;
378 unsigned aub_sub_type
;
382 aub_sub_type
= DWGS_COLOR_CALC_VIEWPORT_STATE
;
385 aub_sub_type
= DWGS_COLOR_CALC_STATE
;
388 aub_sub_type
= DWGS_KERNEL_INSTRUCTIONS
;
390 case BRW_SAMPLER_DEFAULT_COLOR
:
391 aub_sub_type
= DWGS_SAMPLER_DEFAULT_COLOR
;
394 aub_sub_type
= DWGS_SAMPLER_STATE
;
397 aub_sub_type
= DWGS_WINDOWER_IZ_STATE
;
400 aub_sub_type
= DWGS_KERNEL_INSTRUCTIONS
;
403 aub_sub_type
= DWGS_STRIPS_FANS_VIEWPORT_STATE
;
406 aub_sub_type
= DWGS_STRIPS_FANS_STATE
;
409 aub_sub_type
= DWGS_VERTEX_SHADER_STATE
;
412 aub_sub_type
= DWGS_KERNEL_INSTRUCTIONS
;
415 aub_sub_type
= DWGS_GEOMETRY_SHADER_STATE
;
418 aub_sub_type
= DWGS_KERNEL_INSTRUCTIONS
;
421 aub_sub_type
= DWGS_CLIPPER_VIEWPORT_STATE
;
424 aub_sub_type
= DWGS_CLIPPER_STATE
;
427 aub_sub_type
= DWGS_KERNEL_INSTRUCTIONS
;
430 aub_type
= DW_SURFACE_STATE
;
431 aub_sub_type
= DWSS_SURFACE_STATE
;
433 case BRW_SS_SURF_BIND
:
434 aub_type
= DW_SURFACE_STATE
;
435 aub_sub_type
= DWSS_BINDING_TABLE_STATE
;
437 case BRW_CONSTANT_BUFFER
:
438 aub_type
= DW_CONSTANT_URB_ENTRY
;
448 struct aub_pipe_winsys
*iws
= aub_pipe_winsys(pws
);
449 struct aub_buffer
*sbo
= aub_bo(buf
);
451 assert(sbo
->size
> offset
+ size
);
452 memcpy(sbo
->data
+ offset
, data
, size
);
454 brw_aub_gtt_data( iws
->aubfile
,
455 sbo
->offset
+ offset
,
465 xlib_brw_display_surface(struct xmesa_buffer
*b
,
466 struct pipe_surface
*surf
)
468 brw_aub_dump_bmp( global_winsys
->aubfile
,
470 aub_bo(surf
->buffer
)->offset
);
474 struct xm_driver xlib_brw_driver
=
476 .create_pipe_winsys
= xlib_create_brw_winsys
,
477 .create_pipe_screen
= xlib_create_brw_screen
,
478 .create_pipe_context
= xlib_create_brw_context
,
479 .display_surface
= xlib_brw_display_surface
,