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 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include "brw_aub.h"
00035 #include "pipe/p_context.h"
00036 #include "pipe/p_state.h"
00037 #include "pipe/p_debug.h"
00038 #include "util/u_memory.h"
00039
00040
00041 struct brw_aubfile {
00042 FILE *file;
00043 unsigned next_free_page;
00044 };
00045
00046
00047 extern char *__progname;
00048
00049
00050 struct aub_file_header {
00051 unsigned int instruction_type;
00052 unsigned int pad0:16;
00053 unsigned int minor:8;
00054 unsigned int major:8;
00055 unsigned char application[8*4];
00056 unsigned int day:8;
00057 unsigned int month:8;
00058 unsigned int year:16;
00059 unsigned int timezone:8;
00060 unsigned int second:8;
00061 unsigned int minute:8;
00062 unsigned int hour:8;
00063 unsigned int comment_length:16;
00064 unsigned int pad1:16;
00065 };
00066
00067 struct aub_block_header {
00068 unsigned int instruction_type;
00069 unsigned int operation:8;
00070 unsigned int type:8;
00071 unsigned int address_space:8;
00072 unsigned int pad0:8;
00073 unsigned int general_state_type:8;
00074 unsigned int surface_state_type:8;
00075 unsigned int pad1:16;
00076 unsigned int address;
00077 unsigned int length;
00078 };
00079
00080 struct aub_dump_bmp {
00081 unsigned int instruction_type;
00082 unsigned int xmin:16;
00083 unsigned int ymin:16;
00084 unsigned int pitch:16;
00085 unsigned int bpp:8;
00086 unsigned int format:8;
00087 unsigned int xsize:16;
00088 unsigned int ysize:16;
00089 unsigned int addr;
00090 unsigned int unknown;
00091 };
00092
00093 enum bh_operation {
00094 BH_COMMENT,
00095 BH_DATA_WRITE,
00096 BH_COMMAND_WRITE,
00097 BH_MMI0_WRITE32,
00098 BH_END_SCENE,
00099 BH_CONFIG_MEMORY_MAP,
00100 BH_MAX_OPERATION
00101 };
00102
00103 enum command_write_type {
00104 CW_HWB_RING = 1,
00105 CW_PRIMARY_RING_A,
00106 CW_PRIMARY_RING_B,
00107 CW_PRIMARY_RING_C,
00108 CW_MAX_TYPE
00109 };
00110
00111 enum memory_map_type {
00112 MM_DEFAULT,
00113 MM_DYNAMIC,
00114 MM_MAX_TYPE
00115 };
00116
00117 enum address_space {
00118 ADDR_GTT,
00119 ADDR_LOCAL,
00120 ADDR_MAIN,
00121 ADDR_MAX
00122 };
00123
00124
00125 #define AUB_FILE_HEADER 0xe085000b
00126 #define AUB_BLOCK_HEADER 0xe0c10003
00127 #define AUB_DUMP_BMP 0xe09e0004
00128
00129
00130
00131 #define PGETBL_CTL 0x2020
00132 #define PGETBL_ENABLED 0x1
00133
00134 #define NR_GTT_ENTRIES 65536
00135
00136 #define FAIL \
00137 do { \
00138 fprintf(stderr, "failed to write aub data at %s/%d\n", __FUNCTION__, __LINE__); \
00139 exit(1); \
00140 } while (0)
00141
00142
00143
00144
00145 static void init_aubfile( FILE *aub_file )
00146 {
00147 struct aub_file_header fh;
00148 struct aub_block_header bh;
00149 unsigned int data;
00150
00151 static int nr;
00152
00153 nr++;
00154
00155
00156
00157 memset(&fh, 0, sizeof(fh));
00158
00159 fh.instruction_type = AUB_FILE_HEADER;
00160 fh.minor = 0x0;
00161 fh.major = 0x7;
00162 memcpy(fh.application, __progname, sizeof(fh.application));
00163 fh.day = (nr>>24) & 0xff;
00164 fh.month = 0x0;
00165 fh.year = 0x0;
00166 fh.timezone = 0x0;
00167 fh.second = nr & 0xff;
00168 fh.minute = (nr>>8) & 0xff;
00169 fh.hour = (nr>>16) & 0xff;
00170 fh.comment_length = 0x0;
00171
00172 if (fwrite(&fh, sizeof(fh), 1, aub_file) < 0)
00173 FAIL;
00174
00175
00176
00177 memset(&bh, 0, sizeof(bh));
00178
00179 bh.instruction_type = AUB_BLOCK_HEADER;
00180 bh.operation = BH_MMI0_WRITE32;
00181 bh.type = 0x0;
00182 bh.address_space = ADDR_GTT;
00183 bh.general_state_type = 0x0;
00184 bh.surface_state_type = 0x0;
00185 bh.address = PGETBL_CTL;
00186 bh.length = 0x4;
00187
00188 if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0)
00189 FAIL;
00190
00191 data = 0x0 | PGETBL_ENABLED;
00192
00193 if (fwrite(&data, sizeof(data), 1, aub_file) < 0)
00194 FAIL;
00195 }
00196
00197
00198 static void init_aub_gtt( struct brw_aubfile *aubfile,
00199 unsigned start_offset,
00200 unsigned size )
00201 {
00202 FILE *aub_file = aubfile->file;
00203 struct aub_block_header bh;
00204 unsigned int i;
00205
00206 assert(start_offset + size < NR_GTT_ENTRIES * 4096);
00207
00208
00209 memset(&bh, 0, sizeof(bh));
00210
00211 bh.instruction_type = AUB_BLOCK_HEADER;
00212 bh.operation = BH_DATA_WRITE;
00213 bh.type = 0x0;
00214 bh.address_space = ADDR_MAIN;
00215 bh.general_state_type = 0x0;
00216 bh.surface_state_type = 0x0;
00217 bh.address = start_offset / 4096 * 4;
00218 bh.length = size / 4096 * 4;
00219
00220 if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0)
00221 FAIL;
00222
00223 for (i = 0; i < size / 4096; i++) {
00224 unsigned data = aubfile->next_free_page | 1;
00225
00226 aubfile->next_free_page += 4096;
00227
00228 if (fwrite(&data, sizeof(data), 1, aub_file) < 0)
00229 FAIL;
00230 }
00231
00232 }
00233
00234 static void write_block_header( FILE *aub_file,
00235 struct aub_block_header *bh,
00236 const unsigned *data,
00237 unsigned sz )
00238 {
00239 sz = (sz + 3) & ~3;
00240
00241 if (fwrite(bh, sizeof(*bh), 1, aub_file) < 0)
00242 FAIL;
00243
00244 if (fwrite(data, sz, 1, aub_file) < 0)
00245 FAIL;
00246
00247 fflush(aub_file);
00248 }
00249
00250
00251 static void write_dump_bmp( FILE *aub_file,
00252 struct aub_dump_bmp *db )
00253 {
00254 if (fwrite(db, sizeof(*db), 1, aub_file) < 0)
00255 FAIL;
00256
00257 fflush(aub_file);
00258 }
00259
00260
00261
00262 void brw_aub_gtt_data( struct brw_aubfile *aubfile,
00263 unsigned offset,
00264 const void *data,
00265 unsigned sz,
00266 unsigned type,
00267 unsigned state_type )
00268 {
00269 struct aub_block_header bh;
00270
00271 bh.instruction_type = AUB_BLOCK_HEADER;
00272 bh.operation = BH_DATA_WRITE;
00273 bh.type = type;
00274 bh.address_space = ADDR_GTT;
00275 bh.pad0 = 0;
00276
00277 if (type == DW_GENERAL_STATE) {
00278 bh.general_state_type = state_type;
00279 bh.surface_state_type = 0;
00280 }
00281 else {
00282 bh.general_state_type = 0;
00283 bh.surface_state_type = state_type;
00284 }
00285
00286 bh.pad1 = 0;
00287 bh.address = offset;
00288 bh.length = sz;
00289
00290 write_block_header(aubfile->file, &bh, data, sz);
00291 }
00292
00293
00294
00295 void brw_aub_gtt_cmds( struct brw_aubfile *aubfile,
00296 unsigned offset,
00297 const void *data,
00298 unsigned sz )
00299 {
00300 struct aub_block_header bh;
00301 unsigned type = CW_PRIMARY_RING_A;
00302
00303
00304 bh.instruction_type = AUB_BLOCK_HEADER;
00305 bh.operation = BH_COMMAND_WRITE;
00306 bh.type = type;
00307 bh.address_space = ADDR_GTT;
00308 bh.pad0 = 0;
00309 bh.general_state_type = 0;
00310 bh.surface_state_type = 0;
00311 bh.pad1 = 0;
00312 bh.address = offset;
00313 bh.length = sz;
00314
00315 write_block_header(aubfile->file, &bh, data, sz);
00316 }
00317
00318 void brw_aub_dump_bmp( struct brw_aubfile *aubfile,
00319 struct pipe_surface *surface,
00320 unsigned gtt_offset )
00321 {
00322 struct aub_dump_bmp db;
00323 unsigned format;
00324
00325 assert(surface->block.width == 1);
00326 assert(surface->block.height == 1);
00327
00328 if (surface->block.size == 4)
00329 format = 0x7;
00330 else
00331 format = 0x3;
00332
00333 db.instruction_type = AUB_DUMP_BMP;
00334 db.xmin = 0;
00335 db.ymin = 0;
00336 db.format = format;
00337 db.bpp = surface->block.size * 8;
00338 db.pitch = surface->stride/surface->block.size;
00339 db.xsize = surface->width;
00340 db.ysize = surface->height;
00341 db.addr = gtt_offset;
00342 db.unknown = 0x0;
00343
00344 write_dump_bmp(aubfile->file, &db);
00345 }
00346
00347
00348
00349 struct brw_aubfile *brw_aubfile_create( void )
00350 {
00351 struct brw_aubfile *aubfile = CALLOC_STRUCT(brw_aubfile);
00352 char filename[80];
00353 int val;
00354 static int i = 0;
00355
00356 i++;
00357
00358 if (getenv("INTEL_AUBFILE")) {
00359 val = snprintf(filename, sizeof(filename), "%s%d.aub", getenv("INTEL_AUBFILE"), i%4);
00360 debug_printf("--> Aub file: %s\n", filename);
00361 aubfile->file = fopen(filename, "w");
00362 }
00363 else {
00364 val = snprintf(filename, sizeof(filename), "%s.aub", __progname);
00365 if (val < 0 || val > sizeof(filename))
00366 strcpy(filename, "default.aub");
00367
00368 debug_printf("--> Aub file: %s\n", filename);
00369 aubfile->file = fopen(filename, "w");
00370 }
00371
00372 if (!aubfile->file) {
00373 debug_printf("couldn't open aubfile\n");
00374 exit(1);
00375 }
00376
00377 init_aubfile(aubfile->file);
00378
00379
00380
00381
00382 aubfile->next_free_page = (NR_GTT_ENTRIES * 4 + 4095) & ~4095;
00383
00384
00385
00386
00387 init_aub_gtt(aubfile, 0, 4096*4);
00388 init_aub_gtt(aubfile, AUB_BUF_START, AUB_BUF_SIZE);
00389
00390 return aubfile;
00391 }
00392
00393 void brw_aub_destroy( struct brw_aubfile *aubfile )
00394 {
00395 fclose(aubfile->file);
00396 FREE(aubfile);
00397 }