gallium: refactor/replace p_util.h with util/u_memory.h and util/u_math.h
[mesa.git] / src / gallium / winsys / xlib / 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 <stdio.h>
33 #include <stdlib.h>
34 #include "brw_aub.h"
35 #include "pipe/p_context.h"
36 #include "pipe/p_state.h"
37 #include "pipe/p_debug.h"
38
39
40 struct brw_aubfile {
41 FILE *file;
42 unsigned next_free_page;
43 };
44
45
46 extern char *__progname;
47
48
49 struct aub_file_header {
50 unsigned int instruction_type;
51 unsigned int pad0:16;
52 unsigned int minor:8;
53 unsigned int major:8;
54 unsigned char application[8*4];
55 unsigned int day:8;
56 unsigned int month:8;
57 unsigned int year:16;
58 unsigned int timezone:8;
59 unsigned int second:8;
60 unsigned int minute:8;
61 unsigned int hour:8;
62 unsigned int comment_length:16;
63 unsigned int pad1:16;
64 };
65
66 struct aub_block_header {
67 unsigned int instruction_type;
68 unsigned int operation:8;
69 unsigned int type:8;
70 unsigned int address_space:8;
71 unsigned int pad0:8;
72 unsigned int general_state_type:8;
73 unsigned int surface_state_type:8;
74 unsigned int pad1:16;
75 unsigned int address;
76 unsigned int length;
77 };
78
79 struct aub_dump_bmp {
80 unsigned int instruction_type;
81 unsigned int xmin:16;
82 unsigned int ymin:16;
83 unsigned int pitch:16;
84 unsigned int bpp:8;
85 unsigned int format:8;
86 unsigned int xsize:16;
87 unsigned int ysize:16;
88 unsigned int addr;
89 unsigned int unknown;
90 };
91
92 enum bh_operation {
93 BH_COMMENT,
94 BH_DATA_WRITE,
95 BH_COMMAND_WRITE,
96 BH_MMI0_WRITE32,
97 BH_END_SCENE,
98 BH_CONFIG_MEMORY_MAP,
99 BH_MAX_OPERATION
100 };
101
102 enum command_write_type {
103 CW_HWB_RING = 1,
104 CW_PRIMARY_RING_A,
105 CW_PRIMARY_RING_B, /* XXX - disagreement with listaub! */
106 CW_PRIMARY_RING_C,
107 CW_MAX_TYPE
108 };
109
110 enum memory_map_type {
111 MM_DEFAULT,
112 MM_DYNAMIC,
113 MM_MAX_TYPE
114 };
115
116 enum address_space {
117 ADDR_GTT,
118 ADDR_LOCAL,
119 ADDR_MAIN,
120 ADDR_MAX
121 };
122
123
124 #define AUB_FILE_HEADER 0xe085000b
125 #define AUB_BLOCK_HEADER 0xe0c10003
126 #define AUB_DUMP_BMP 0xe09e0004
127
128 /* Registers to control page table
129 */
130 #define PGETBL_CTL 0x2020
131 #define PGETBL_ENABLED 0x1
132
133 #define NR_GTT_ENTRIES 65536 /* 256 mb */
134
135 #define FAIL \
136 do { \
137 fprintf(stderr, "failed to write aub data at %s/%d\n", __FUNCTION__, __LINE__); \
138 exit(1); \
139 } while (0)
140
141
142 /* Emit the headers at the top of each aubfile. Initialize the GTT.
143 */
144 static void init_aubfile( FILE *aub_file )
145 {
146 struct aub_file_header fh;
147 struct aub_block_header bh;
148 unsigned int data;
149
150 static int nr;
151
152 nr++;
153
154 /* Emit the aub header:
155 */
156 memset(&fh, 0, sizeof(fh));
157
158 fh.instruction_type = AUB_FILE_HEADER;
159 fh.minor = 0x0;
160 fh.major = 0x7;
161 memcpy(fh.application, __progname, sizeof(fh.application));
162 fh.day = (nr>>24) & 0xff;
163 fh.month = 0x0;
164 fh.year = 0x0;
165 fh.timezone = 0x0;
166 fh.second = nr & 0xff;
167 fh.minute = (nr>>8) & 0xff;
168 fh.hour = (nr>>16) & 0xff;
169 fh.comment_length = 0x0;
170
171 if (fwrite(&fh, sizeof(fh), 1, aub_file) < 0)
172 FAIL;
173
174 /* Setup the GTT starting at main memory address zero (!):
175 */
176 memset(&bh, 0, sizeof(bh));
177
178 bh.instruction_type = AUB_BLOCK_HEADER;
179 bh.operation = BH_MMI0_WRITE32;
180 bh.type = 0x0;
181 bh.address_space = ADDR_GTT; /* ??? */
182 bh.general_state_type = 0x0;
183 bh.surface_state_type = 0x0;
184 bh.address = PGETBL_CTL;
185 bh.length = 0x4;
186
187 if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0)
188 FAIL;
189
190 data = 0x0 | PGETBL_ENABLED;
191
192 if (fwrite(&data, sizeof(data), 1, aub_file) < 0)
193 FAIL;
194 }
195
196
197 static void init_aub_gtt( struct brw_aubfile *aubfile,
198 unsigned start_offset,
199 unsigned size )
200 {
201 FILE *aub_file = aubfile->file;
202 struct aub_block_header bh;
203 unsigned int i;
204
205 assert(start_offset + size < NR_GTT_ENTRIES * 4096);
206
207
208 memset(&bh, 0, sizeof(bh));
209
210 bh.instruction_type = AUB_BLOCK_HEADER;
211 bh.operation = BH_DATA_WRITE;
212 bh.type = 0x0;
213 bh.address_space = ADDR_MAIN;
214 bh.general_state_type = 0x0;
215 bh.surface_state_type = 0x0;
216 bh.address = start_offset / 4096 * 4;
217 bh.length = size / 4096 * 4;
218
219 if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0)
220 FAIL;
221
222 for (i = 0; i < size / 4096; i++) {
223 unsigned data = aubfile->next_free_page | 1;
224
225 aubfile->next_free_page += 4096;
226
227 if (fwrite(&data, sizeof(data), 1, aub_file) < 0)
228 FAIL;
229 }
230
231 }
232
233 static void write_block_header( FILE *aub_file,
234 struct aub_block_header *bh,
235 const unsigned *data,
236 unsigned sz )
237 {
238 sz = (sz + 3) & ~3;
239
240 if (fwrite(bh, sizeof(*bh), 1, aub_file) < 0)
241 FAIL;
242
243 if (fwrite(data, sz, 1, aub_file) < 0)
244 FAIL;
245
246 fflush(aub_file);
247 }
248
249
250 static void write_dump_bmp( FILE *aub_file,
251 struct aub_dump_bmp *db )
252 {
253 if (fwrite(db, sizeof(*db), 1, aub_file) < 0)
254 FAIL;
255
256 fflush(aub_file);
257 }
258
259
260
261 void brw_aub_gtt_data( struct brw_aubfile *aubfile,
262 unsigned offset,
263 const void *data,
264 unsigned sz,
265 unsigned type,
266 unsigned state_type )
267 {
268 struct aub_block_header bh;
269
270 bh.instruction_type = AUB_BLOCK_HEADER;
271 bh.operation = BH_DATA_WRITE;
272 bh.type = type;
273 bh.address_space = ADDR_GTT;
274 bh.pad0 = 0;
275
276 if (type == DW_GENERAL_STATE) {
277 bh.general_state_type = state_type;
278 bh.surface_state_type = 0;
279 }
280 else {
281 bh.general_state_type = 0;
282 bh.surface_state_type = state_type;
283 }
284
285 bh.pad1 = 0;
286 bh.address = offset;
287 bh.length = sz;
288
289 write_block_header(aubfile->file, &bh, data, sz);
290 }
291
292
293
294 void brw_aub_gtt_cmds( struct brw_aubfile *aubfile,
295 unsigned offset,
296 const void *data,
297 unsigned sz )
298 {
299 struct aub_block_header bh;
300 unsigned type = CW_PRIMARY_RING_A;
301
302
303 bh.instruction_type = AUB_BLOCK_HEADER;
304 bh.operation = BH_COMMAND_WRITE;
305 bh.type = type;
306 bh.address_space = ADDR_GTT;
307 bh.pad0 = 0;
308 bh.general_state_type = 0;
309 bh.surface_state_type = 0;
310 bh.pad1 = 0;
311 bh.address = offset;
312 bh.length = sz;
313
314 write_block_header(aubfile->file, &bh, data, sz);
315 }
316
317 void brw_aub_dump_bmp( struct brw_aubfile *aubfile,
318 struct pipe_surface *surface,
319 unsigned gtt_offset )
320 {
321 struct aub_dump_bmp db;
322 unsigned format;
323
324 assert(surface->block.width == 1);
325 assert(surface->block.height == 1);
326
327 if (surface->block.size == 4)
328 format = 0x7;
329 else
330 format = 0x3;
331
332 db.instruction_type = AUB_DUMP_BMP;
333 db.xmin = 0;
334 db.ymin = 0;
335 db.format = format;
336 db.bpp = surface->block.size * 8;
337 db.pitch = surface->stride/surface->block.size;
338 db.xsize = surface->width;
339 db.ysize = surface->height;
340 db.addr = gtt_offset;
341 db.unknown = /* surface->tiled ? 0x4 : */ 0x0;
342
343 write_dump_bmp(aubfile->file, &db);
344 }
345
346
347
348 struct brw_aubfile *brw_aubfile_create( void )
349 {
350 struct brw_aubfile *aubfile = CALLOC_STRUCT(brw_aubfile);
351 char filename[80];
352 int val;
353 static int i = 0;
354
355 i++;
356
357 if (getenv("INTEL_AUBFILE")) {
358 val = snprintf(filename, sizeof(filename), "%s%d.aub", getenv("INTEL_AUBFILE"), i%4);
359 debug_printf("--> Aub file: %s\n", filename);
360 aubfile->file = fopen(filename, "w");
361 }
362 else {
363 val = snprintf(filename, sizeof(filename), "%s.aub", __progname);
364 if (val < 0 || val > sizeof(filename))
365 strcpy(filename, "default.aub");
366
367 debug_printf("--> Aub file: %s\n", filename);
368 aubfile->file = fopen(filename, "w");
369 }
370
371 if (!aubfile->file) {
372 debug_printf("couldn't open aubfile\n");
373 exit(1);
374 }
375
376 init_aubfile(aubfile->file);
377
378 /* The GTT is located starting address zero in main memory. Pages
379 * to populate the gtt start after this point.
380 */
381 aubfile->next_free_page = (NR_GTT_ENTRIES * 4 + 4095) & ~4095;
382
383 /* More or less correspond with all the agp regions mapped by the
384 * driver:
385 */
386 init_aub_gtt(aubfile, 0, 4096*4);
387 init_aub_gtt(aubfile, AUB_BUF_START, AUB_BUF_SIZE);
388
389 return aubfile;
390 }
391
392 void brw_aub_destroy( struct brw_aubfile *aubfile )
393 {
394 fclose(aubfile->file);
395 FREE(aubfile);
396 }