~ubuntu-branches/ubuntu/quantal/mesa-glw/quantal

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/i965/brw_aub.c

  • Committer: Bazaar Package Importer
  • Author(s): Morten Kjeldgaard
  • Date: 2008-05-06 16:19:15 UTC
  • Revision ID: james.westby@ubuntu.com-20080506161915-uynz7nftmfixu6bq
Tags: upstream-7.0.3
ImportĀ upstreamĀ versionĀ 7.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
   static int nr;
 
63
   
 
64
   nr++;
 
65
 
 
66
   /* Emit the aub header:
 
67
    */
 
68
   memset(&fh, 0, sizeof(fh));
 
69
 
 
70
   fh.instruction_type = AUB_FILE_HEADER;
 
71
   fh.minor = 0x0;
 
72
   fh.major = 0x7;
 
73
   memcpy(fh.application, __progname, sizeof(fh.application));
 
74
   fh.day = (nr>>24) & 0xff;
 
75
   fh.month = 0x0;
 
76
   fh.year = 0x0;
 
77
   fh.timezone = 0x0;
 
78
   fh.second = nr & 0xff;
 
79
   fh.minute = (nr>>8) & 0xff;
 
80
   fh.hour = (nr>>16) & 0xff;
 
81
   fh.comment_length = 0x0;   
 
82
 
 
83
   if (fwrite(&fh, sizeof(fh), 1, aub_file) < 1) 
 
84
      FAIL;
 
85
         
 
86
   /* Setup the GTT starting at main memory address zero (!):
 
87
    */
 
88
   memset(&bh, 0, sizeof(bh));
 
89
   
 
90
   bh.instruction_type = AUB_BLOCK_HEADER;
 
91
   bh.operation = BH_MMI0_WRITE32;
 
92
   bh.type = 0x0;
 
93
   bh.address_space = ADDR_GTT; /* ??? */
 
94
   bh.general_state_type = 0x0;
 
95
   bh.surface_state_type = 0x0;
 
96
   bh.address = PGETBL_CTL;
 
97
   bh.length = 0x4;
 
98
 
 
99
   if (fwrite(&bh, sizeof(bh), 1, aub_file) < 1) 
 
100
      FAIL;
 
101
 
 
102
   data = 0x0 | PGETBL_ENABLED;
 
103
 
 
104
   if (fwrite(&data, sizeof(data), 1, aub_file) < 1) 
 
105
      FAIL;
 
106
}
 
107
 
 
108
 
 
109
static void init_aub_gtt( struct brw_context *brw,
 
110
                          GLuint start_offset, 
 
111
                          GLuint size )
 
112
{
 
113
   FILE *aub_file = brw->intel.aub_file;
 
114
   struct aub_block_header bh;
 
115
   unsigned int i;
 
116
 
 
117
   assert(start_offset + size < NR_GTT_ENTRIES * 4096);
 
118
 
 
119
 
 
120
   memset(&bh, 0, sizeof(bh));
 
121
   
 
122
   bh.instruction_type = AUB_BLOCK_HEADER;
 
123
   bh.operation = BH_DATA_WRITE;
 
124
   bh.type = 0x0;
 
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;
 
130
 
 
131
   if (fwrite(&bh, sizeof(bh), 1, aub_file) < 1) 
 
132
      FAIL;
 
133
 
 
134
   for (i = 0; i < size / 4096; i++) {
 
135
      GLuint data = brw->next_free_page | 1;
 
136
 
 
137
      brw->next_free_page += 4096;
 
138
 
 
139
      if (fwrite(&data, sizeof(data), 1, aub_file) < 1) 
 
140
         FAIL;
 
141
   }
 
142
 
 
143
}
 
144
 
 
145
static void write_block_header( FILE *aub_file,
 
146
                                struct aub_block_header *bh,
 
147
                                const GLuint *data,
 
148
                                GLuint sz )
 
149
{
 
150
   sz = (sz + 3) & ~3;
 
151
 
 
152
   if (fwrite(bh, sizeof(*bh), 1, aub_file) < 1) 
 
153
      FAIL;
 
154
 
 
155
   if (fwrite(data, sz, 1, aub_file) < 1) 
 
156
      FAIL;
 
157
 
 
158
   fflush(aub_file);
 
159
}
 
160
 
 
161
 
 
162
static void write_dump_bmp( FILE *aub_file,
 
163
                            struct aub_dump_bmp *db )
 
164
{
 
165
   if (fwrite(db, sizeof(*db), 1, aub_file) < 1) 
 
166
      FAIL;
 
167
 
 
168
   fflush(aub_file);
 
169
}
 
170
 
 
171
 
 
172
 
 
173
static void brw_aub_gtt_data( struct intel_context *intel,
 
174
                              GLuint offset,
 
175
                              const void *data,
 
176
                              GLuint sz,
 
177
                              GLuint type,
 
178
                              GLuint state_type )
 
179
{
 
180
   struct aub_block_header bh;
 
181
 
 
182
   bh.instruction_type = AUB_BLOCK_HEADER;
 
183
   bh.operation = BH_DATA_WRITE;
 
184
   bh.type = type;
 
185
   bh.address_space = ADDR_GTT;
 
186
   bh.pad0 = 0;
 
187
 
 
188
   if (type == DW_GENERAL_STATE) {
 
189
      bh.general_state_type = state_type;
 
190
      bh.surface_state_type = 0;
 
191
   }
 
192
   else {
 
193
      bh.general_state_type = 0;
 
194
      bh.surface_state_type = state_type;
 
195
   }
 
196
 
 
197
   bh.pad1 = 0;
 
198
   bh.address = offset;
 
199
   bh.length = sz;
 
200
 
 
201
   write_block_header(intel->aub_file, &bh, data, sz);
 
202
}
 
203
 
 
204
 
 
205
 
 
206
static void brw_aub_gtt_cmds( struct intel_context *intel,
 
207
                              GLuint offset,
 
208
                              const void *data,
 
209
                              GLuint sz )
 
210
{
 
211
   struct brw_context *brw = brw_context(&intel->ctx);
 
212
   struct aub_block_header bh;   
 
213
   GLuint type = CW_PRIMARY_RING_A;
 
214
   
 
215
 
 
216
   bh.instruction_type = AUB_BLOCK_HEADER;
 
217
   bh.operation = BH_COMMAND_WRITE;
 
218
   bh.type = type;
 
219
   bh.address_space = ADDR_GTT;
 
220
   bh.pad0 = 0;
 
221
   bh.general_state_type = 0;
 
222
   bh.surface_state_type = 0;
 
223
   bh.pad1 = 0;
 
224
   bh.address = offset;
 
225
   bh.length = sz;
 
226
 
 
227
   write_block_header(brw->intel.aub_file, &bh, data, sz);
 
228
}
 
229
 
 
230
static void brw_aub_dump_bmp( struct intel_context *intel,
 
231
                              GLuint buffer )
 
232
{
 
233
   struct brw_context *brw = brw_context(&intel->ctx);
 
234
   intelScreenPrivate *intelScreen = brw->intel.intelScreen;
 
235
   struct aub_dump_bmp db;
 
236
   GLuint format;
 
237
 
 
238
   if (intelScreen->cpp == 4)
 
239
      format = 0x7;
 
240
   else
 
241
      format = 0x3;
 
242
 
 
243
 
 
244
   if (buffer == 0) {
 
245
      db.instruction_type = AUB_DUMP_BMP;
 
246
      db.xmin = 0;
 
247
      db.ymin = 0;
 
248
      db.format = format;
 
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 */
 
255
 
 
256
      write_dump_bmp(brw->intel.aub_file, &db);
 
257
   }
 
258
   else {
 
259
      db.instruction_type = AUB_DUMP_BMP;
 
260
      db.xmin = 0;
 
261
      db.ymin = 0;
 
262
      db.format = format;
 
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;
 
269
 
 
270
      write_dump_bmp(brw->intel.aub_file, &db);
 
271
   }
 
272
}
 
273
 
 
274
/* Attempt to prevent monster aubfiles by closing and reopening when
 
275
 * the state pools wrap.
 
276
 */
 
277
static void brw_aub_wrap( struct intel_context *intel )
 
278
{
 
279
   struct brw_context *brw = brw_context(&intel->ctx);   
 
280
   if (intel->aub_file) {
 
281
      brw_aub_destroy(brw);
 
282
      brw_aub_init(brw);
 
283
   }
 
284
   brw->wrap = 1;               /* ??? */
 
285
}
 
286
 
 
287
 
 
288
int brw_aub_init( struct brw_context *brw )
 
289
{
 
290
   struct intel_context *intel = &brw->intel;
 
291
   intelScreenPrivate *intelScreen = intel->intelScreen;
 
292
   char filename[80];
 
293
   int val;
 
294
   static int i = 0;
 
295
 
 
296
   i++;
 
297
 
 
298
   if (_mesa_getenv("INTEL_REPLAY"))
 
299
      return 0;
 
300
 
 
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");
 
305
   }
 
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");   
 
310
   
 
311
      _mesa_printf("--> Aub file: %s\n", filename);
 
312
      brw->intel.aub_file = fopen(filename, "w");
 
313
   }
 
314
   else {
 
315
      return 0;
 
316
   }
 
317
 
 
318
   if (!brw->intel.aub_file) {
 
319
      _mesa_printf("couldn't open aubfile\n");
 
320
      exit(1);
 
321
   }
 
322
 
 
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;
 
327
   
 
328
   init_aubfile(brw->intel.aub_file);
 
329
 
 
330
   /* The GTT is located starting address zero in main memory.  Pages
 
331
    * to populate the gtt start after this point.
 
332
    */
 
333
   brw->next_free_page = (NR_GTT_ENTRIES * 4 + 4095) & ~4095;
 
334
 
 
335
   /* More or less correspond with all the agp regions mapped by the
 
336
    * driver:
 
337
    */
 
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);
 
343
 
 
344
   return 0;
 
345
}
 
346
 
 
347
void brw_aub_destroy( struct brw_context *brw )
 
348
{
 
349
   if (brw->intel.aub_file) {
 
350
      fclose(brw->intel.aub_file);
 
351
      brw->intel.aub_file = NULL;
 
352
   }
 
353
}