Minor r200 vertex program cleanups. Remove disabled leftovers from r300 vertex progra...
[mesa.git] / src / mesa / drivers / dri / i965 / brw_aub.c
1 /*
2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4 develop this 3D driver.
5
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:
13
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.
17
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.
25
26 **********************************************************************/
27 /*
28 * Authors:
29 * Keith Whitwell <keith@tungstengraphics.com>
30 */
31
32 #include "brw_context.h"
33 #include "brw_aub.h"
34 #include "intel_regions.h"
35 #include <stdio.h>
36
37 extern char *__progname;
38
39
40 /* Registers to control page table
41 */
42 #define PGETBL_CTL 0x2020
43 #define PGETBL_ENABLED 0x1
44
45 #define NR_GTT_ENTRIES 65536 /* 256 mb */
46
47 #define FAIL \
48 do { \
49 fprintf(stderr, "failed to write aub data at %s/%d\n", __FUNCTION__, __LINE__); \
50 exit(1); \
51 } while (0)
52
53
54 /* Emit the headers at the top of each aubfile. Initialize the GTT.
55 */
56 static void init_aubfile( FILE *aub_file )
57 {
58 struct aub_file_header fh;
59 struct aub_block_header bh;
60 unsigned int data;
61
62 /* Emit the aub header:
63 */
64 memset(&fh, 0, sizeof(fh));
65
66 fh.instruction_type = AUB_FILE_HEADER;
67 fh.minor = 0x0;
68 fh.major = 0x7;
69 memcpy(fh.application, __progname, sizeof(fh.application));
70 fh.day = 0x0;
71 fh.month = 0x0;
72 fh.year = 0x0;
73 fh.timezone = 0x0;
74 fh.second = 0x0;
75 fh.minute = 0x0;
76 fh.hour = 0x0;
77 fh.comment_length = 0x0;
78
79 if (fwrite(&fh, sizeof(fh), 1, aub_file) < 0)
80 FAIL;
81
82 /* Setup the GTT starting at main memory address zero (!):
83 */
84 memset(&bh, 0, sizeof(bh));
85
86 bh.instruction_type = AUB_BLOCK_HEADER;
87 bh.operation = BH_MMI0_WRITE32;
88 bh.type = 0x0;
89 bh.address_space = ADDR_GTT; /* ??? */
90 bh.general_state_type = 0x0;
91 bh.surface_state_type = 0x0;
92 bh.address = PGETBL_CTL;
93 bh.length = 0x4;
94
95 if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0)
96 FAIL;
97
98 data = 0x0 | PGETBL_ENABLED;
99
100 if (fwrite(&data, sizeof(data), 1, aub_file) < 0)
101 FAIL;
102 }
103
104
105 static void init_aub_gtt( struct brw_context *brw,
106 GLuint start_offset,
107 GLuint size )
108 {
109 FILE *aub_file = brw->intel.aub_file;
110 struct aub_block_header bh;
111 unsigned int i;
112
113 assert(start_offset + size < NR_GTT_ENTRIES * 4096);
114
115
116 memset(&bh, 0, sizeof(bh));
117
118 bh.instruction_type = AUB_BLOCK_HEADER;
119 bh.operation = BH_DATA_WRITE;
120 bh.type = 0x0;
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;
126
127 if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0)
128 FAIL;
129
130 for (i = 0; i < size / 4096; i++) {
131 GLuint data = brw->next_free_page | 1;
132
133 brw->next_free_page += 4096;
134
135 if (fwrite(&data, sizeof(data), 1, aub_file) < 0)
136 FAIL;
137 }
138
139 }
140
141 static void write_block_header( FILE *aub_file,
142 struct aub_block_header *bh,
143 const GLuint *data,
144 GLuint sz )
145 {
146 sz = (sz + 3) & ~3;
147
148 if (fwrite(bh, sizeof(*bh), 1, aub_file) < 0)
149 FAIL;
150
151 if (fwrite(data, sz, 1, aub_file) < 0)
152 FAIL;
153
154 fflush(aub_file);
155 }
156
157
158 static void write_dump_bmp( FILE *aub_file,
159 struct aub_dump_bmp *db )
160 {
161 if (fwrite(db, sizeof(*db), 1, aub_file) < 0)
162 FAIL;
163
164 fflush(aub_file);
165 }
166
167
168
169 static void brw_aub_gtt_data( struct intel_context *intel,
170 GLuint offset,
171 const void *data,
172 GLuint sz,
173 GLuint type,
174 GLuint state_type )
175 {
176 struct aub_block_header bh;
177
178 bh.instruction_type = AUB_BLOCK_HEADER;
179 bh.operation = BH_DATA_WRITE;
180 bh.type = type;
181 bh.address_space = ADDR_GTT;
182 bh.pad0 = 0;
183
184 if (type == DW_GENERAL_STATE) {
185 bh.general_state_type = state_type;
186 bh.surface_state_type = 0;
187 }
188 else {
189 bh.general_state_type = 0;
190 bh.surface_state_type = state_type;
191 }
192
193 bh.pad1 = 0;
194 bh.address = offset;
195 bh.length = sz;
196
197 write_block_header(intel->aub_file, &bh, data, sz);
198 }
199
200
201
202 static void brw_aub_gtt_cmds( struct intel_context *intel,
203 GLuint offset,
204 const void *data,
205 GLuint sz )
206 {
207 struct brw_context *brw = brw_context(&intel->ctx);
208 struct aub_block_header bh;
209 GLuint type = CW_PRIMARY_RING_A;
210
211
212 bh.instruction_type = AUB_BLOCK_HEADER;
213 bh.operation = BH_COMMAND_WRITE;
214 bh.type = type;
215 bh.address_space = ADDR_GTT;
216 bh.pad0 = 0;
217 bh.general_state_type = 0;
218 bh.surface_state_type = 0;
219 bh.pad1 = 0;
220 bh.address = offset;
221 bh.length = sz;
222
223 write_block_header(brw->intel.aub_file, &bh, data, sz);
224 }
225
226 static void brw_aub_dump_bmp( struct intel_context *intel,
227 GLuint buffer )
228 {
229 struct brw_context *brw = brw_context(&intel->ctx);
230 intelScreenPrivate *intelScreen = brw->intel.intelScreen;
231 struct aub_dump_bmp db;
232 GLuint format;
233
234 if (intelScreen->cpp == 4)
235 format = 0x7;
236 else
237 format = 0x3;
238
239
240 if (buffer == 0) {
241 db.instruction_type = AUB_DUMP_BMP;
242 db.xmin = 0;
243 db.ymin = 0;
244 db.format = format;
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 */
251
252 write_dump_bmp(brw->intel.aub_file, &db);
253 }
254 else {
255 db.instruction_type = AUB_DUMP_BMP;
256 db.xmin = 0;
257 db.ymin = 0;
258 db.format = format;
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;
265
266 write_dump_bmp(brw->intel.aub_file, &db);
267 }
268 }
269
270 /* Attempt to prevent monster aubfiles by closing and reopening when
271 * the state pools wrap.
272 */
273 void brw_aub_wrap( struct intel_context *intel )
274 {
275 struct brw_context *brw = brw_context(&intel->ctx);
276 if (intel->aub_file) {
277 brw_aub_destroy(brw);
278 brw_aub_init(brw);
279 }
280 brw->wrap = 1; /* ??? */
281 }
282
283
284 int brw_aub_init( struct brw_context *brw )
285 {
286 struct intel_context *intel = &brw->intel;
287 intelScreenPrivate *intelScreen = intel->intelScreen;
288 char filename[80];
289 int val;
290 static int i = 0;
291
292 i++;
293
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");
298 }
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");
303
304 _mesa_printf("--> Aub file: %s\n", filename);
305 brw->intel.aub_file = fopen(filename, "w");
306 }
307 else {
308 return 0;
309 }
310
311 if (!brw->intel.aub_file) {
312 _mesa_printf("couldn't open aubfile\n");
313 exit(1);
314 }
315
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;
320
321 init_aubfile(brw->intel.aub_file);
322
323 /* The GTT is located starting address zero in main memory. Pages
324 * to populate the gtt start after this point.
325 */
326 brw->next_free_page = (NR_GTT_ENTRIES * 4 + 4095) & ~4095;
327
328 /* More or less correspond with all the agp regions mapped by the
329 * driver:
330 */
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);
336
337 return 0;
338 }
339
340 void brw_aub_destroy( struct brw_context *brw )
341 {
342 if (brw->intel.aub_file) {
343 fclose(brw->intel.aub_file);
344 brw->intel.aub_file = NULL;
345 }
346 }