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
;
62 /* Emit the aub header:
64 memset(&fh
, 0, sizeof(fh
));
66 fh
.instruction_type
= AUB_FILE_HEADER
;
69 memcpy(fh
.application
, __progname
, sizeof(fh
.application
));
77 fh
.comment_length
= 0x0;
79 if (fwrite(&fh
, sizeof(fh
), 1, aub_file
) < 0)
82 /* Setup the GTT starting at main memory address zero (!):
84 memset(&bh
, 0, sizeof(bh
));
86 bh
.instruction_type
= AUB_BLOCK_HEADER
;
87 bh
.operation
= BH_MMI0_WRITE32
;
89 bh
.address_space
= ADDR_GTT
; /* ??? */
90 bh
.general_state_type
= 0x0;
91 bh
.surface_state_type
= 0x0;
92 bh
.address
= PGETBL_CTL
;
95 if (fwrite(&bh
, sizeof(bh
), 1, aub_file
) < 0)
98 data
= 0x0 | PGETBL_ENABLED
;
100 if (fwrite(&data
, sizeof(data
), 1, aub_file
) < 0)
105 static void init_aub_gtt( struct brw_context
*brw
,
109 FILE *aub_file
= brw
->intel
.aub_file
;
110 struct aub_block_header bh
;
113 assert(start_offset
+ size
< NR_GTT_ENTRIES
* 4096);
116 memset(&bh
, 0, sizeof(bh
));
118 bh
.instruction_type
= AUB_BLOCK_HEADER
;
119 bh
.operation
= BH_DATA_WRITE
;
121 bh
.address_space
= ADDR_MAIN
;
122 bh
.general_state_type
= 0x0;
123 bh
.surface_state_type
= 0x0;
124 bh
.address
= start_offset
/ 4096 * 4;
125 bh
.length
= size
/ 4096 * 4;
127 if (fwrite(&bh
, sizeof(bh
), 1, aub_file
) < 0)
130 for (i
= 0; i
< size
/ 4096; i
++) {
131 GLuint data
= brw
->next_free_page
| 1;
133 brw
->next_free_page
+= 4096;
135 if (fwrite(&data
, sizeof(data
), 1, aub_file
) < 0)
141 static void write_block_header( FILE *aub_file
,
142 struct aub_block_header
*bh
,
148 if (fwrite(bh
, sizeof(*bh
), 1, aub_file
) < 0)
151 if (fwrite(data
, sz
, 1, aub_file
) < 0)
158 static void write_dump_bmp( FILE *aub_file
,
159 struct aub_dump_bmp
*db
)
161 if (fwrite(db
, sizeof(*db
), 1, aub_file
) < 0)
169 static void brw_aub_gtt_data( struct intel_context
*intel
,
176 struct aub_block_header bh
;
178 bh
.instruction_type
= AUB_BLOCK_HEADER
;
179 bh
.operation
= BH_DATA_WRITE
;
181 bh
.address_space
= ADDR_GTT
;
184 if (type
== DW_GENERAL_STATE
) {
185 bh
.general_state_type
= state_type
;
186 bh
.surface_state_type
= 0;
189 bh
.general_state_type
= 0;
190 bh
.surface_state_type
= state_type
;
197 write_block_header(intel
->aub_file
, &bh
, data
, sz
);
202 static void brw_aub_gtt_cmds( struct intel_context
*intel
,
207 struct brw_context
*brw
= brw_context(&intel
->ctx
);
208 struct aub_block_header bh
;
209 GLuint type
= CW_PRIMARY_RING_A
;
212 bh
.instruction_type
= AUB_BLOCK_HEADER
;
213 bh
.operation
= BH_COMMAND_WRITE
;
215 bh
.address_space
= ADDR_GTT
;
217 bh
.general_state_type
= 0;
218 bh
.surface_state_type
= 0;
223 write_block_header(brw
->intel
.aub_file
, &bh
, data
, sz
);
226 static void brw_aub_dump_bmp( struct intel_context
*intel
,
229 struct brw_context
*brw
= brw_context(&intel
->ctx
);
230 intelScreenPrivate
*intelScreen
= brw
->intel
.intelScreen
;
231 struct aub_dump_bmp db
;
234 if (intelScreen
->cpp
== 4)
241 db
.instruction_type
= AUB_DUMP_BMP
;
245 db
.bpp
= intelScreen
->cpp
* 8;
246 db
.pitch
= intelScreen
->front
.pitch
/ intelScreen
->cpp
;
247 db
.xsize
= intelScreen
->width
;
248 db
.ysize
= intelScreen
->height
;
249 db
.addr
= intelScreen
->front
.offset
;
250 db
.unknown
= 0x0; /* 4: xmajor tiled, 0: not tiled */
252 write_dump_bmp(brw
->intel
.aub_file
, &db
);
255 db
.instruction_type
= AUB_DUMP_BMP
;
259 db
.bpp
= intel
->back_region
->cpp
* 8;
260 db
.pitch
= intel
->back_region
->pitch
;
261 db
.xsize
= intel
->back_region
->pitch
;
262 db
.ysize
= intel
->back_region
->height
;
263 db
.addr
= intelScreen
->back
.offset
;
264 db
.unknown
= intel
->back_region
->tiled
? 0x4 : 0x0;
266 write_dump_bmp(brw
->intel
.aub_file
, &db
);
270 /* Attempt to prevent monster aubfiles by closing and reopening when
271 * the state pools wrap.
273 void brw_aub_wrap( struct intel_context
*intel
)
275 struct brw_context
*brw
= brw_context(&intel
->ctx
);
276 if (intel
->aub_file
) {
277 brw_aub_destroy(brw
);
280 brw
->wrap
= 1; /* ??? */
284 int brw_aub_init( struct brw_context
*brw
)
286 struct intel_context
*intel
= &brw
->intel
;
287 intelScreenPrivate
*intelScreen
= intel
->intelScreen
;
294 if (_mesa_getenv("INTEL_AUBFILE")) {
295 val
= snprintf(filename
, sizeof(filename
), "%s%d.aub", _mesa_getenv("INTEL_AUBFILE"), i
%4);
296 _mesa_printf("--> Aub file: %s\n", filename
);
297 brw
->intel
.aub_file
= fopen(filename
, "w");
299 else if (_mesa_getenv("INTEL_AUB")) {
300 val
= snprintf(filename
, sizeof(filename
), "%s.aub", __progname
);
301 if (val
< 0 || val
> sizeof(filename
))
302 strcpy(filename
, "default.aub");
304 _mesa_printf("--> Aub file: %s\n", filename
);
305 brw
->intel
.aub_file
= fopen(filename
, "w");
311 if (!brw
->intel
.aub_file
) {
312 _mesa_printf("couldn't open aubfile\n");
316 brw
->intel
.vtbl
.aub_commands
= brw_aub_gtt_cmds
;
317 brw
->intel
.vtbl
.aub_dump_bmp
= brw_aub_dump_bmp
;
318 brw
->intel
.vtbl
.aub_gtt_data
= brw_aub_gtt_data
;
319 brw
->intel
.vtbl
.aub_wrap
= brw_aub_wrap
;
321 init_aubfile(brw
->intel
.aub_file
);
323 /* The GTT is located starting address zero in main memory. Pages
324 * to populate the gtt start after this point.
326 brw
->next_free_page
= (NR_GTT_ENTRIES
* 4 + 4095) & ~4095;
328 /* More or less correspond with all the agp regions mapped by the
331 init_aub_gtt(brw
, 0, 4096*4); /* so new fulsim doesn't crash */
332 init_aub_gtt(brw
, intelScreen
->front
.offset
, intelScreen
->back
.size
);
333 init_aub_gtt(brw
, intelScreen
->back
.offset
, intelScreen
->back
.size
);
334 init_aub_gtt(brw
, intelScreen
->depth
.offset
, intelScreen
->back
.size
);
335 init_aub_gtt(brw
, intelScreen
->tex
.offset
, intelScreen
->tex
.size
);
340 void brw_aub_destroy( struct brw_context
*brw
)
342 if (brw
->intel
.aub_file
) {
343 fclose(brw
->intel
.aub_file
);
344 brw
->intel
.aub_file
= NULL
;