00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "glxheader.h"
00037 #include "xmesaP.h"
00038
00039 #include "pipe/p_winsys.h"
00040 #include "pipe/p_inlines.h"
00041 #include "util/u_math.h"
00042 #include "util/u_memory.h"
00043 #include "i965simple/brw_winsys.h"
00044 #include "i965simple/brw_screen.h"
00045 #include "brw_aub.h"
00046 #include "xm_winsys_aub.h"
00047
00048
00049
00050 struct aub_buffer {
00051 char *data;
00052 unsigned offset;
00053 unsigned size;
00054 unsigned refcount;
00055 unsigned map_count;
00056 boolean dump_on_unmap;
00057 };
00058
00059
00060
00061 struct aub_pipe_winsys {
00062 struct pipe_winsys winsys;
00063
00064 struct brw_aubfile *aubfile;
00065
00066
00067
00068 char *pool;
00069 unsigned size;
00070 unsigned used;
00071 };
00072
00073
00074
00075
00076 static inline struct aub_pipe_winsys *
00077 aub_pipe_winsys( struct pipe_winsys *winsys )
00078 {
00079 return (struct aub_pipe_winsys *)winsys;
00080 }
00081
00082
00083
00084 static INLINE struct aub_buffer *
00085 aub_bo( struct pipe_buffer *bo )
00086 {
00087 return (struct aub_buffer *)bo;
00088 }
00089
00090 static INLINE struct pipe_buffer *
00091 pipe_bo( struct aub_buffer *bo )
00092 {
00093 return (struct pipe_buffer *)bo;
00094 }
00095
00096
00097
00098
00099 static void *aub_buffer_map(struct pipe_winsys *winsys,
00100 struct pipe_buffer *buf,
00101 unsigned flags )
00102 {
00103 struct aub_buffer *sbo = aub_bo(buf);
00104
00105 assert(sbo->data);
00106
00107 if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
00108 sbo->dump_on_unmap = 1;
00109
00110 sbo->map_count++;
00111 return sbo->data;
00112 }
00113
00114 static void aub_buffer_unmap(struct pipe_winsys *winsys,
00115 struct pipe_buffer *buf)
00116 {
00117 struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys);
00118 struct aub_buffer *sbo = aub_bo(buf);
00119
00120 sbo->map_count--;
00121
00122 if (sbo->map_count == 0 &&
00123 sbo->dump_on_unmap) {
00124
00125 sbo->dump_on_unmap = 0;
00126
00127 brw_aub_gtt_data( iws->aubfile,
00128 sbo->offset,
00129 sbo->data,
00130 sbo->size,
00131 0,
00132 0);
00133 }
00134 }
00135
00136
00137 static void
00138 aub_buffer_destroy(struct pipe_winsys *winsys,
00139 struct pipe_buffer *buf)
00140 {
00141 free(buf);
00142 }
00143
00144
00145 void xmesa_buffer_subdata_aub(struct pipe_winsys *winsys,
00146 struct pipe_buffer *buf,
00147 unsigned long offset,
00148 unsigned long size,
00149 const void *data,
00150 unsigned aub_type,
00151 unsigned aub_sub_type)
00152 {
00153 struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys);
00154 struct aub_buffer *sbo = aub_bo(buf);
00155
00156 assert(sbo->size > offset + size);
00157 memcpy(sbo->data + offset, data, size);
00158
00159 brw_aub_gtt_data( iws->aubfile,
00160 sbo->offset + offset,
00161 sbo->data + offset,
00162 size,
00163 aub_type,
00164 aub_sub_type );
00165 }
00166
00167 void xmesa_commands_aub(struct pipe_winsys *winsys,
00168 unsigned *cmds,
00169 unsigned nr_dwords)
00170 {
00171 struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys);
00172 unsigned size = nr_dwords * 4;
00173
00174 assert(iws->used + size < iws->size);
00175
00176 brw_aub_gtt_cmds( iws->aubfile,
00177 AUB_BUF_START + iws->used,
00178 cmds,
00179 nr_dwords * sizeof(int) );
00180
00181 iws->used += align(size, 4096);
00182 }
00183
00184
00185 static struct aub_pipe_winsys *global_winsys = NULL;
00186
00187 void xmesa_display_aub(
00188 struct pipe_surface *surface )
00189 {
00190
00191 brw_aub_dump_bmp( global_winsys->aubfile,
00192 surface,
00193 aub_bo(surface->buffer)->offset );
00194 }
00195
00196
00197
00198
00199
00200
00201 static struct pipe_buffer *
00202 aub_buffer_create(struct pipe_winsys *winsys,
00203 unsigned alignment,
00204 unsigned usage,
00205 unsigned size)
00206 {
00207 struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys);
00208 struct aub_buffer *sbo = CALLOC_STRUCT(aub_buffer);
00209
00210 sbo->refcount = 1;
00211
00212
00213
00214
00215 assert(iws->used + size < iws->size);
00216 sbo->data = iws->pool + iws->used;
00217 sbo->offset = AUB_BUF_START + iws->used;
00218 iws->used += align(size, 4096);
00219
00220 sbo->size = size;
00221
00222 return pipe_bo(sbo);
00223 }
00224
00225
00226 static struct pipe_buffer *
00227 aub_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes)
00228 {
00229 struct aub_buffer *sbo;
00230
00231
00232
00233 sbo = aub_bo(aub_buffer_create( winsys, 0, 0, 0 ));
00234
00235 sbo->data = ptr;
00236 sbo->size = bytes;
00237
00238 return pipe_bo(sbo);
00239 }
00240
00241
00242
00243
00244
00245
00246 static void
00247 aub_flush_frontbuffer( struct pipe_winsys *winsys,
00248 struct pipe_surface *surf,
00249 void *context_private)
00250 {
00251 xmesa_display_aub( surf );
00252 }
00253
00254 static struct pipe_surface *
00255 aub_i915_surface_alloc(struct pipe_winsys *winsys)
00256 {
00257 struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface);
00258 if (surf) {
00259 surf->refcount = 1;
00260 surf->winsys = winsys;
00261 }
00262 return surf;
00263 }
00264
00265
00269 static INLINE unsigned
00270 round_up(unsigned n, unsigned multiple)
00271 {
00272 return (n + multiple - 1) & ~(multiple - 1);
00273 }
00274
00275 static int
00276 aub_i915_surface_alloc_storage(struct pipe_winsys *winsys,
00277 struct pipe_surface *surf,
00278 unsigned width, unsigned height,
00279 enum pipe_format format,
00280 unsigned flags,
00281 unsigned tex_usage)
00282 {
00283 const unsigned alignment = 64;
00284
00285 surf->width = width;
00286 surf->height = height;
00287 surf->format = format;
00288 pf_get_block(format, &surf->block);
00289 surf->nblocksx = pf_get_nblocksx(&surf->block, width);
00290 surf->nblocksy = pf_get_nblocksy(&surf->block, height);
00291 surf->stride = round_up(surf->nblocksx * surf->block.size, alignment);
00292 surf->usage = flags;
00293
00294 assert(!surf->buffer);
00295 surf->buffer = winsys->buffer_create(winsys, alignment,
00296 PIPE_BUFFER_USAGE_PIXEL,
00297 surf->stride * surf->nblocksy);
00298 if(!surf->buffer)
00299 return -1;
00300
00301 return 0;
00302 }
00303
00304 static void
00305 aub_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
00306 {
00307 struct pipe_surface *surf = *s;
00308 surf->refcount--;
00309 if (surf->refcount == 0) {
00310 if (surf->buffer)
00311 winsys_buffer_reference(winsys, &surf->buffer, NULL);
00312 free(surf);
00313 }
00314 *s = NULL;
00315 }
00316
00317
00318
00319 static const char *
00320 aub_get_name( struct pipe_winsys *winsys )
00321 {
00322 return "Aub/xlib";
00323 }
00324
00325 struct pipe_winsys *
00326 xmesa_create_pipe_winsys_aub( void )
00327 {
00328 struct aub_pipe_winsys *iws = CALLOC_STRUCT( aub_pipe_winsys );
00329
00330
00331
00332
00333
00334
00335
00336
00337 iws->winsys.buffer_create = aub_buffer_create;
00338 iws->winsys.user_buffer_create = aub_user_buffer_create;
00339 iws->winsys.buffer_map = aub_buffer_map;
00340 iws->winsys.buffer_unmap = aub_buffer_unmap;
00341 iws->winsys.buffer_destroy = aub_buffer_destroy;
00342 iws->winsys.flush_frontbuffer = aub_flush_frontbuffer;
00343 iws->winsys.get_name = aub_get_name;
00344
00345 iws->winsys.surface_alloc = aub_i915_surface_alloc;
00346 iws->winsys.surface_alloc_storage = aub_i915_surface_alloc_storage;
00347 iws->winsys.surface_release = aub_i915_surface_release;
00348
00349 iws->aubfile = brw_aubfile_create();
00350 iws->size = AUB_BUF_SIZE;
00351 iws->pool = malloc(AUB_BUF_SIZE);
00352
00353
00354
00355 assert(global_winsys == NULL);
00356 global_winsys = iws;
00357
00358 return &iws->winsys;
00359 }
00360
00361
00362 void
00363 xmesa_destroy_pipe_winsys_aub( struct pipe_winsys *winsys )
00364
00365 {
00366 struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys);
00367 brw_aub_destroy(iws->aubfile);
00368 free(iws->pool);
00369 free(iws);
00370 }
00371
00372
00373
00374
00375
00376
00377
00378 #define IWS_BATCHBUFFER_SIZE 1024
00379
00380 struct aub_brw_winsys {
00381 struct brw_winsys winsys;
00382 struct aub_context *aub;
00383
00384 struct pipe_winsys *pipe_winsys;
00385
00386 unsigned batch_data[IWS_BATCHBUFFER_SIZE];
00387 unsigned batch_nr;
00388 unsigned batch_size;
00389 unsigned batch_alloc;
00390 };
00391
00392
00393
00394
00395 static inline struct aub_brw_winsys *
00396 aub_brw_winsys( struct brw_winsys *sws )
00397 {
00398 return (struct aub_brw_winsys *)sws;
00399 }
00400
00401
00402
00403
00404
00405 static unsigned *aub_i965_batch_start( struct brw_winsys *sws,
00406 unsigned dwords,
00407 unsigned relocs )
00408 {
00409 struct aub_brw_winsys *iws = aub_brw_winsys(sws);
00410
00411 if (iws->batch_size < iws->batch_nr + dwords)
00412 return NULL;
00413
00414 iws->batch_alloc = iws->batch_nr + dwords;
00415 return (void *)1;
00416 }
00417
00418 static void aub_i965_batch_dword( struct brw_winsys *sws,
00419 unsigned dword )
00420 {
00421 struct aub_brw_winsys *iws = aub_brw_winsys(sws);
00422
00423 assert(iws->batch_nr < iws->batch_alloc);
00424 iws->batch_data[iws->batch_nr++] = dword;
00425 }
00426
00427 static void aub_i965_batch_reloc( struct brw_winsys *sws,
00428 struct pipe_buffer *buf,
00429 unsigned access_flags,
00430 unsigned delta )
00431 {
00432 struct aub_brw_winsys *iws = aub_brw_winsys(sws);
00433
00434 assert(iws->batch_nr < iws->batch_alloc);
00435 iws->batch_data[iws->batch_nr++] = aub_bo(buf)->offset + delta;
00436 }
00437
00438 static unsigned aub_i965_get_buffer_offset( struct brw_winsys *sws,
00439 struct pipe_buffer *buf,
00440 unsigned access_flags )
00441 {
00442 return aub_bo(buf)->offset;
00443 }
00444
00445 static void aub_i965_batch_end( struct brw_winsys *sws )
00446 {
00447 struct aub_brw_winsys *iws = aub_brw_winsys(sws);
00448
00449 assert(iws->batch_nr <= iws->batch_alloc);
00450 iws->batch_alloc = 0;
00451 }
00452
00453 static void aub_i965_batch_flush( struct brw_winsys *sws,
00454 struct pipe_fence_handle **fence )
00455 {
00456 struct aub_brw_winsys *iws = aub_brw_winsys(sws);
00457 assert(iws->batch_nr <= iws->batch_size);
00458
00459 if (iws->batch_nr) {
00460 xmesa_commands_aub( iws->pipe_winsys,
00461 iws->batch_data,
00462 iws->batch_nr );
00463 }
00464
00465 iws->batch_nr = 0;
00466 }
00467
00468
00469
00470 static void aub_i965_buffer_subdata_typed(struct brw_winsys *winsys,
00471 struct pipe_buffer *buf,
00472 unsigned long offset,
00473 unsigned long size,
00474 const void *data,
00475 unsigned data_type)
00476 {
00477 struct aub_brw_winsys *iws = aub_brw_winsys(winsys);
00478 unsigned aub_type = DW_GENERAL_STATE;
00479 unsigned aub_sub_type;
00480
00481 switch (data_type) {
00482 case BRW_CC_VP:
00483 aub_sub_type = DWGS_COLOR_CALC_VIEWPORT_STATE;
00484 break;
00485 case BRW_CC_UNIT:
00486 aub_sub_type = DWGS_COLOR_CALC_STATE;
00487 break;
00488 case BRW_WM_PROG:
00489 aub_sub_type = DWGS_KERNEL_INSTRUCTIONS;
00490 break;
00491 case BRW_SAMPLER_DEFAULT_COLOR:
00492 aub_sub_type = DWGS_SAMPLER_DEFAULT_COLOR;
00493 break;
00494 case BRW_SAMPLER:
00495 aub_sub_type = DWGS_SAMPLER_STATE;
00496 break;
00497 case BRW_WM_UNIT:
00498 aub_sub_type = DWGS_WINDOWER_IZ_STATE;
00499 break;
00500 case BRW_SF_PROG:
00501 aub_sub_type = DWGS_KERNEL_INSTRUCTIONS;
00502 break;
00503 case BRW_SF_VP:
00504 aub_sub_type = DWGS_STRIPS_FANS_VIEWPORT_STATE;
00505 break;
00506 case BRW_SF_UNIT:
00507 aub_sub_type = DWGS_STRIPS_FANS_STATE;
00508 break;
00509 case BRW_VS_UNIT:
00510 aub_sub_type = DWGS_VERTEX_SHADER_STATE;
00511 break;
00512 case BRW_VS_PROG:
00513 aub_sub_type = DWGS_KERNEL_INSTRUCTIONS;
00514 break;
00515 case BRW_GS_UNIT:
00516 aub_sub_type = DWGS_GEOMETRY_SHADER_STATE;
00517 break;
00518 case BRW_GS_PROG:
00519 aub_sub_type = DWGS_KERNEL_INSTRUCTIONS;
00520 break;
00521 case BRW_CLIP_VP:
00522 aub_sub_type = DWGS_CLIPPER_VIEWPORT_STATE;
00523 break;
00524 case BRW_CLIP_UNIT:
00525 aub_sub_type = DWGS_CLIPPER_STATE;
00526 break;
00527 case BRW_CLIP_PROG:
00528 aub_sub_type = DWGS_KERNEL_INSTRUCTIONS;
00529 break;
00530 case BRW_SS_SURFACE:
00531 aub_type = DW_SURFACE_STATE;
00532 aub_sub_type = DWSS_SURFACE_STATE;
00533 break;
00534 case BRW_SS_SURF_BIND:
00535 aub_type = DW_SURFACE_STATE;
00536 aub_sub_type = DWSS_BINDING_TABLE_STATE;
00537 break;
00538 case BRW_CONSTANT_BUFFER:
00539 aub_type = DW_CONSTANT_URB_ENTRY;
00540 aub_sub_type = 0;
00541 break;
00542
00543 default:
00544 assert(0);
00545 break;
00546 }
00547
00548 xmesa_buffer_subdata_aub( iws->pipe_winsys,
00549 buf,
00550 offset,
00551 size,
00552 data,
00553 aub_type,
00554 aub_sub_type );
00555 }
00556
00560 struct pipe_context *
00561 xmesa_create_i965simple( struct pipe_winsys *winsys )
00562 {
00563 struct aub_brw_winsys *iws = CALLOC_STRUCT( aub_brw_winsys );
00564 struct pipe_screen *screen = brw_create_screen(winsys, 0);
00565
00566
00567
00568
00569 iws->winsys.batch_start = aub_i965_batch_start;
00570 iws->winsys.batch_dword = aub_i965_batch_dword;
00571 iws->winsys.batch_reloc = aub_i965_batch_reloc;
00572 iws->winsys.batch_end = aub_i965_batch_end;
00573 iws->winsys.batch_flush = aub_i965_batch_flush;
00574 iws->winsys.buffer_subdata_typed = aub_i965_buffer_subdata_typed;
00575 iws->winsys.get_buffer_offset = aub_i965_get_buffer_offset;
00576
00577 iws->pipe_winsys = winsys;
00578
00579 iws->batch_size = IWS_BATCHBUFFER_SIZE;
00580
00581
00582
00583 return brw_create( screen,
00584 &iws->winsys,
00585 0 );
00586 }