2
Copyright (C) Intel Corp. 2006. All Rights Reserved.
3
Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4
develop this 3D driver.
6
Permission is hereby granted, free of charge, to any person obtaining
7
a 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, sublicense, 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 above copyright notice and this permission notice (including the
15
next paragraph) shall be included in all copies or substantial
16
portions of the Software.
18
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
**********************************************************************/
29
* Keith Whitwell <keith@tungstengraphics.com>
32
#include "brw_context.h"
34
#include "intel_regions.h"
37
extern char *__progname;
40
/* Registers to control page table
42
#define PGETBL_CTL 0x2020
43
#define PGETBL_ENABLED 0x1
45
#define NR_GTT_ENTRIES 65536 /* 256 mb */
49
fprintf(stderr, "failed to write aub data at %s/%d\n", __FUNCTION__, __LINE__); \
54
/* Emit the headers at the top of each aubfile. Initialize the GTT.
56
static void init_aubfile( FILE *aub_file )
58
struct aub_file_header fh;
59
struct aub_block_header bh;
66
/* Emit the aub header:
68
memset(&fh, 0, sizeof(fh));
70
fh.instruction_type = AUB_FILE_HEADER;
73
memcpy(fh.application, __progname, sizeof(fh.application));
74
fh.day = (nr>>24) & 0xff;
78
fh.second = nr & 0xff;
79
fh.minute = (nr>>8) & 0xff;
80
fh.hour = (nr>>16) & 0xff;
81
fh.comment_length = 0x0;
83
if (fwrite(&fh, sizeof(fh), 1, aub_file) < 1)
86
/* Setup the GTT starting at main memory address zero (!):
88
memset(&bh, 0, sizeof(bh));
90
bh.instruction_type = AUB_BLOCK_HEADER;
91
bh.operation = BH_MMI0_WRITE32;
93
bh.address_space = ADDR_GTT; /* ??? */
94
bh.general_state_type = 0x0;
95
bh.surface_state_type = 0x0;
96
bh.address = PGETBL_CTL;
99
if (fwrite(&bh, sizeof(bh), 1, aub_file) < 1)
102
data = 0x0 | PGETBL_ENABLED;
104
if (fwrite(&data, sizeof(data), 1, aub_file) < 1)
109
static void init_aub_gtt( struct brw_context *brw,
113
FILE *aub_file = brw->intel.aub_file;
114
struct aub_block_header bh;
117
assert(start_offset + size < NR_GTT_ENTRIES * 4096);
120
memset(&bh, 0, sizeof(bh));
122
bh.instruction_type = AUB_BLOCK_HEADER;
123
bh.operation = BH_DATA_WRITE;
125
bh.address_space = ADDR_MAIN;
126
bh.general_state_type = 0x0;
127
bh.surface_state_type = 0x0;
128
bh.address = start_offset / 4096 * 4;
129
bh.length = size / 4096 * 4;
131
if (fwrite(&bh, sizeof(bh), 1, aub_file) < 1)
134
for (i = 0; i < size / 4096; i++) {
135
GLuint data = brw->next_free_page | 1;
137
brw->next_free_page += 4096;
139
if (fwrite(&data, sizeof(data), 1, aub_file) < 1)
145
static void write_block_header( FILE *aub_file,
146
struct aub_block_header *bh,
152
if (fwrite(bh, sizeof(*bh), 1, aub_file) < 1)
155
if (fwrite(data, sz, 1, aub_file) < 1)
162
static void write_dump_bmp( FILE *aub_file,
163
struct aub_dump_bmp *db )
165
if (fwrite(db, sizeof(*db), 1, aub_file) < 1)
173
static void brw_aub_gtt_data( struct intel_context *intel,
180
struct aub_block_header bh;
182
bh.instruction_type = AUB_BLOCK_HEADER;
183
bh.operation = BH_DATA_WRITE;
185
bh.address_space = ADDR_GTT;
188
if (type == DW_GENERAL_STATE) {
189
bh.general_state_type = state_type;
190
bh.surface_state_type = 0;
193
bh.general_state_type = 0;
194
bh.surface_state_type = state_type;
201
write_block_header(intel->aub_file, &bh, data, sz);
206
static void brw_aub_gtt_cmds( struct intel_context *intel,
211
struct brw_context *brw = brw_context(&intel->ctx);
212
struct aub_block_header bh;
213
GLuint type = CW_PRIMARY_RING_A;
216
bh.instruction_type = AUB_BLOCK_HEADER;
217
bh.operation = BH_COMMAND_WRITE;
219
bh.address_space = ADDR_GTT;
221
bh.general_state_type = 0;
222
bh.surface_state_type = 0;
227
write_block_header(brw->intel.aub_file, &bh, data, sz);
230
static void brw_aub_dump_bmp( struct intel_context *intel,
233
struct brw_context *brw = brw_context(&intel->ctx);
234
intelScreenPrivate *intelScreen = brw->intel.intelScreen;
235
struct aub_dump_bmp db;
238
if (intelScreen->cpp == 4)
245
db.instruction_type = AUB_DUMP_BMP;
249
db.bpp = intelScreen->cpp * 8;
250
db.pitch = intelScreen->front.pitch / intelScreen->cpp;
251
db.xsize = intelScreen->width;
252
db.ysize = intelScreen->height;
253
db.addr = intelScreen->front.offset;
254
db.unknown = 0x0; /* 4: xmajor tiled, 0: not tiled */
256
write_dump_bmp(brw->intel.aub_file, &db);
259
db.instruction_type = AUB_DUMP_BMP;
263
db.bpp = intel->back_region->cpp * 8;
264
db.pitch = intel->back_region->pitch;
265
db.xsize = intel->back_region->pitch;
266
db.ysize = intel->back_region->height;
267
db.addr = intelScreen->back.offset;
268
db.unknown = intel->back_region->tiled ? 0x4 : 0x0;
270
write_dump_bmp(brw->intel.aub_file, &db);
274
/* Attempt to prevent monster aubfiles by closing and reopening when
275
* the state pools wrap.
277
static void brw_aub_wrap( struct intel_context *intel )
279
struct brw_context *brw = brw_context(&intel->ctx);
280
if (intel->aub_file) {
281
brw_aub_destroy(brw);
284
brw->wrap = 1; /* ??? */
288
int brw_aub_init( struct brw_context *brw )
290
struct intel_context *intel = &brw->intel;
291
intelScreenPrivate *intelScreen = intel->intelScreen;
298
if (_mesa_getenv("INTEL_REPLAY"))
301
if (_mesa_getenv("INTEL_AUBFILE")) {
302
val = snprintf(filename, sizeof(filename), "%s%d.aub", _mesa_getenv("INTEL_AUBFILE"), i%4);
303
_mesa_printf("--> Aub file: %s\n", filename);
304
brw->intel.aub_file = fopen(filename, "w");
306
else if (_mesa_getenv("INTEL_AUB")) {
307
val = snprintf(filename, sizeof(filename), "%s.aub", __progname);
308
if (val < 0 || val > sizeof(filename))
309
strcpy(filename, "default.aub");
311
_mesa_printf("--> Aub file: %s\n", filename);
312
brw->intel.aub_file = fopen(filename, "w");
318
if (!brw->intel.aub_file) {
319
_mesa_printf("couldn't open aubfile\n");
323
brw->intel.vtbl.aub_commands = brw_aub_gtt_cmds;
324
brw->intel.vtbl.aub_dump_bmp = brw_aub_dump_bmp;
325
brw->intel.vtbl.aub_gtt_data = brw_aub_gtt_data;
326
brw->intel.vtbl.aub_wrap = brw_aub_wrap;
328
init_aubfile(brw->intel.aub_file);
330
/* The GTT is located starting address zero in main memory. Pages
331
* to populate the gtt start after this point.
333
brw->next_free_page = (NR_GTT_ENTRIES * 4 + 4095) & ~4095;
335
/* More or less correspond with all the agp regions mapped by the
338
init_aub_gtt(brw, 0, 4096*4); /* so new fulsim doesn't crash */
339
init_aub_gtt(brw, intelScreen->front.offset, intelScreen->back.size);
340
init_aub_gtt(brw, intelScreen->back.offset, intelScreen->back.size);
341
init_aub_gtt(brw, intelScreen->depth.offset, intelScreen->back.size);
342
init_aub_gtt(brw, intelScreen->tex.offset, intelScreen->tex.size);
347
void brw_aub_destroy( struct brw_context *brw )
349
if (brw->intel.aub_file) {
350
fclose(brw->intel.aub_file);
351
brw->intel.aub_file = NULL;