~ubuntu-branches/ubuntu/natty/mesa/natty-proposed

« back to all changes in this revision

Viewing changes to src/gallium/drivers/i965/brw_screen_tex_layout.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Hooker, Robert Hooker, Christopher James Halse Rogers
  • Date: 2010-09-14 08:55:40 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100914085540-m4fpl0hdjlfd4jgz
Tags: 7.9~git20100909-0ubuntu1
[ Robert Hooker ]
* New upstream git snapshot up to commit 94118fe2d4b1e5 (LP: #631413)
* New features include ATI HD5xxx series support in r600, and a vastly
  improved glsl compiler.
* Remove pre-generated .pc's, use the ones generated at build time
  instead.
* Remove all references to mesa-utils now that its no longer shipped
  with the mesa source.
* Disable the experimental ARB_fragment_shader option by default on
  i915, it exposes incomplete functionality that breaks KDE compositing
  among other things. It can be enabled via driconf still. (LP: #628930).

[ Christopher James Halse Rogers ]
* debian/patches/04_osmesa_version.diff:
  - Refresh for new upstream
* Bugs fixed in this release:
  - Fixes severe rendering corruption in Unity on radeon (LP: #628727,
    LP: #596292, LP: #599741, LP: #630315, LP: #613694, LP: #599741).
  - Also fixes rendering in gnome-shell (LP: #578619).
  - Flickering in OpenGL apps on radeon (LP: #626943, LP: #610541).
  - Provides preliminary support for new intel chips (LP: #601052).
* debian/rules:
  - Update configure flags to match upstream reshuffling.
  - Explicitly remove gallium DRI drivers that we don't want to ship.
* Update debian/gbp.conf for this Maverick-specific packaging
* libegl1-mesa-dri-x11,kms: There are no longer separate kms or x11 drivers
  for EGL, libegl1-mesa-drivers now contains a single driver that provides
  both backends.

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
 
#include "pipe/p_format.h"
29
 
 
30
 
#include "util/u_math.h"
31
 
#include "util/u_memory.h"
32
 
 
33
 
#include "brw_screen.h"
34
 
#include "brw_debug.h"
35
 
#include "brw_winsys.h"
36
 
 
37
 
/* Code to layout images in a mipmap tree for i965.
38
 
 */
39
 
 
40
 
static int 
41
 
brw_tex_pitch_align (struct brw_texture *tex,
42
 
                     int pitch)
43
 
{
44
 
   if (!tex->compressed) {
45
 
      int pitch_align;
46
 
 
47
 
      switch (tex->tiling) {
48
 
      case BRW_TILING_X:
49
 
         pitch_align = 512;
50
 
         break;
51
 
      case BRW_TILING_Y:
52
 
         pitch_align = 128;
53
 
         break;
54
 
      default:
55
 
         /* XXX: Untiled pitch alignment of 64 bytes for now to allow
56
 
          * render-to-texture to work in all cases. This should
57
 
          * probably be replaced at some point by some scheme to only
58
 
          * do this when really necessary, for example standalone
59
 
          * render target views.
60
 
          */
61
 
         pitch_align = 64;
62
 
         break;
63
 
      }
64
 
 
65
 
      pitch = align(pitch * tex->cpp, pitch_align);
66
 
      pitch /= tex->cpp;
67
 
   }
68
 
 
69
 
   return pitch;
70
 
}
71
 
 
72
 
 
73
 
static void 
74
 
brw_tex_alignment_unit(enum pipe_format pf, 
75
 
                       GLuint *w, GLuint *h)
76
 
{
77
 
    switch (pf) {
78
 
    case PIPE_FORMAT_DXT1_RGB:
79
 
    case PIPE_FORMAT_DXT1_RGBA:
80
 
    case PIPE_FORMAT_DXT3_RGBA:
81
 
    case PIPE_FORMAT_DXT5_RGBA:
82
 
    case PIPE_FORMAT_DXT1_SRGB:
83
 
    case PIPE_FORMAT_DXT1_SRGBA:
84
 
    case PIPE_FORMAT_DXT3_SRGBA:
85
 
    case PIPE_FORMAT_DXT5_SRGBA:
86
 
        *w = 4;
87
 
        *h = 4;
88
 
        break;
89
 
 
90
 
    default:
91
 
        *w = 4;
92
 
        *h = 2;
93
 
        break;
94
 
    }
95
 
}
96
 
 
97
 
 
98
 
static void 
99
 
brw_tex_set_level_info(struct brw_texture *tex,
100
 
                       GLuint level,
101
 
                       GLuint nr_images,
102
 
                       GLuint x, GLuint y,
103
 
                       GLuint w, GLuint h, GLuint d)
104
 
{
105
 
 
106
 
   if (BRW_DEBUG & DEBUG_TEXTURE)
107
 
      debug_printf("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
108
 
                   level, w, h, d, x, y, tex->level_offset[level]);
109
 
 
110
 
   assert(tex->image_offset[level] == NULL);
111
 
   assert(nr_images >= 1);
112
 
 
113
 
   tex->level_offset[level] = (x + y * tex->pitch) * tex->cpp;
114
 
   tex->nr_images[level] = nr_images;
115
 
 
116
 
   tex->image_offset[level] = MALLOC(nr_images * sizeof(GLuint));
117
 
   tex->image_offset[level][0] = 0;
118
 
}
119
 
 
120
 
 
121
 
static void
122
 
brw_tex_set_image_offset(struct brw_texture *tex,
123
 
                         GLuint level, GLuint img,
124
 
                         GLuint x, GLuint y, 
125
 
                         GLuint offset)
126
 
{
127
 
   assert((x == 0 && y == 0) || img != 0 || level != 0);
128
 
   assert(img < tex->nr_images[level]);
129
 
 
130
 
   if (BRW_DEBUG & DEBUG_TEXTURE)
131
 
      debug_printf("%s level %d img %d pos %d,%d image_offset %x\n",
132
 
                   __FUNCTION__, level, img, x, y, 
133
 
                   tex->image_offset[level][img]);
134
 
 
135
 
   tex->image_offset[level][img] = (x + y * tex->pitch) * tex->cpp + offset;
136
 
}
137
 
 
138
 
 
139
 
 
140
 
static void brw_layout_2d( struct brw_texture *tex )
141
 
{
142
 
   GLuint align_h = 2, align_w = 4;
143
 
   GLuint level;
144
 
   GLuint x = 0;
145
 
   GLuint y = 0;
146
 
   GLuint width = tex->base.width0;
147
 
   GLuint height = tex->base.height0;
148
 
 
149
 
   tex->pitch = tex->base.width0;
150
 
   brw_tex_alignment_unit(tex->base.format, &align_w, &align_h);
151
 
 
152
 
   if (tex->compressed) {
153
 
       tex->pitch = align(tex->base.width0, align_w);
154
 
   }
155
 
 
156
 
   /* May need to adjust pitch to accomodate the placement of
157
 
    * the 2nd mipmap.  This occurs when the alignment
158
 
    * constraints of mipmap placement push the right edge of the
159
 
    * 2nd mipmap out past the width of its parent.
160
 
    */
161
 
   if (tex->base.last_level > 0) {
162
 
       GLuint mip1_width;
163
 
 
164
 
       if (tex->compressed) {
165
 
          mip1_width = (align(u_minify(tex->base.width0, 1), align_w) + 
166
 
                        align(u_minify(tex->base.width0, 2), align_w));
167
 
       } else {
168
 
          mip1_width = (align(u_minify(tex->base.width0, 1), align_w) + 
169
 
                        u_minify(tex->base.width0, 2));
170
 
       }
171
 
 
172
 
       if (mip1_width > tex->pitch) {
173
 
           tex->pitch = mip1_width;
174
 
       }
175
 
   }
176
 
 
177
 
   /* Pitch must be a whole number of dwords, even though we
178
 
    * express it in texels.
179
 
    */
180
 
   tex->pitch = brw_tex_pitch_align (tex, tex->pitch);
181
 
   tex->total_height = 0;
182
 
 
183
 
   for ( level = 0 ; level <= tex->base.last_level ; level++ ) {
184
 
      GLuint img_height;
185
 
 
186
 
      brw_tex_set_level_info(tex, level, 1, x, y, width, height, 1);
187
 
 
188
 
      if (tex->compressed)
189
 
         img_height = MAX2(1, height/4);
190
 
      else
191
 
         img_height = align(height, align_h);
192
 
 
193
 
 
194
 
      /* Because the images are packed better, the final offset
195
 
       * might not be the maximal one:
196
 
       */
197
 
      tex->total_height = MAX2(tex->total_height, y + img_height);
198
 
 
199
 
      /* Layout_below: step right after second mipmap.
200
 
       */
201
 
      if (level == 1) {
202
 
         x += align(width, align_w);
203
 
      }
204
 
      else {
205
 
         y += img_height;
206
 
      }
207
 
 
208
 
      width  = u_minify(width, 1);
209
 
      height = u_minify(height, 1);
210
 
   }
211
 
}
212
 
 
213
 
 
214
 
static boolean 
215
 
brw_layout_cubemap_idgng( struct brw_texture *tex )
216
 
{
217
 
   GLuint align_h = 2, align_w = 4;
218
 
   GLuint level;
219
 
   GLuint x = 0;
220
 
   GLuint y = 0;
221
 
   GLuint width = tex->base.width0;
222
 
   GLuint height = tex->base.height0;
223
 
   GLuint qpitch = 0;
224
 
   GLuint y_pitch = 0;
225
 
 
226
 
   tex->pitch = tex->base.width0;
227
 
   brw_tex_alignment_unit(tex->base.format, &align_w, &align_h);
228
 
   y_pitch = align(height, align_h);
229
 
 
230
 
   if (tex->compressed) {
231
 
      tex->pitch = align(tex->base.width0, align_w);
232
 
   }
233
 
 
234
 
   if (tex->base.last_level != 0) {
235
 
      GLuint mip1_width;
236
 
 
237
 
      if (tex->compressed) {
238
 
         mip1_width = (align(u_minify(tex->base.width0, 1), align_w) +
239
 
                       align(u_minify(tex->base.width0, 2), align_w));
240
 
      } else {
241
 
         mip1_width = (align(u_minify(tex->base.width0, 1), align_w) +
242
 
                       u_minify(tex->base.width0, 2));
243
 
      }
244
 
 
245
 
      if (mip1_width > tex->pitch) {
246
 
         tex->pitch = mip1_width;
247
 
      }
248
 
   }
249
 
 
250
 
   tex->pitch = brw_tex_pitch_align(tex, tex->pitch);
251
 
 
252
 
   if (tex->compressed) {
253
 
      qpitch = ((y_pitch + 
254
 
                 align(u_minify(y_pitch, 1), align_h) +
255
 
                 11 * align_h) / 4) * tex->pitch * tex->cpp;
256
 
 
257
 
      tex->total_height = ((y_pitch + 
258
 
                            align(u_minify(y_pitch, 1), align_h) + 
259
 
                            11 * align_h) / 4) * 6;
260
 
   } else {
261
 
      qpitch = (y_pitch + 
262
 
                align(u_minify(y_pitch, 1), align_h) + 
263
 
                11 * align_h) * tex->pitch * tex->cpp;
264
 
 
265
 
      tex->total_height = (y_pitch +
266
 
                           align(u_minify(y_pitch, 1), align_h) +
267
 
                           11 * align_h) * 6;
268
 
   }
269
 
 
270
 
   for (level = 0; level <= tex->base.last_level; level++) {
271
 
      GLuint img_height;
272
 
      GLuint nr_images = 6;
273
 
      GLuint q = 0;
274
 
 
275
 
      brw_tex_set_level_info(tex, level, nr_images, x, y, width, height, 1);
276
 
 
277
 
      for (q = 0; q < nr_images; q++)
278
 
         brw_tex_set_image_offset(tex, level, q, x, y, q * qpitch);
279
 
 
280
 
      if (tex->compressed)
281
 
         img_height = MAX2(1, height/4);
282
 
      else
283
 
         img_height = align(height, align_h);
284
 
 
285
 
      if (level == 1) {
286
 
         x += align(width, align_w);
287
 
      }
288
 
      else {
289
 
         y += img_height;
290
 
      }
291
 
 
292
 
      width  = u_minify(width, 1);
293
 
      height = u_minify(height, 1);
294
 
   }
295
 
 
296
 
   return TRUE;
297
 
}
298
 
 
299
 
 
300
 
static boolean
301
 
brw_layout_3d_cube( struct brw_texture *tex )
302
 
{
303
 
   GLuint width  = tex->base.width0;
304
 
   GLuint height = tex->base.height0;
305
 
   GLuint depth = tex->base.depth0;
306
 
   GLuint pack_x_pitch, pack_x_nr;
307
 
   GLuint pack_y_pitch;
308
 
   GLuint level;
309
 
   GLuint align_h = 2;
310
 
   GLuint align_w = 4;
311
 
 
312
 
   tex->total_height = 0;
313
 
   brw_tex_alignment_unit(tex->base.format, &align_w, &align_h);
314
 
 
315
 
   if (tex->compressed) {
316
 
      tex->pitch = align(width, align_w);
317
 
      pack_y_pitch = (height + 3) / 4;
318
 
   } else {
319
 
      tex->pitch = brw_tex_pitch_align(tex, tex->base.width0);
320
 
      pack_y_pitch = align(tex->base.height0, align_h);
321
 
   }
322
 
 
323
 
   pack_x_pitch = width;
324
 
   pack_x_nr = 1;
325
 
 
326
 
   for (level = 0 ; level <= tex->base.last_level ; level++) {
327
 
      GLuint nr_images = tex->base.target == PIPE_TEXTURE_3D ? depth : 6;
328
 
      GLint x = 0;
329
 
      GLint y = 0;
330
 
      GLint q, j;
331
 
 
332
 
      brw_tex_set_level_info(tex, level, nr_images,
333
 
                                   0, tex->total_height,
334
 
                                   width, height, depth);
335
 
 
336
 
      for (q = 0; q < nr_images;) {
337
 
         for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
338
 
            brw_tex_set_image_offset(tex, level, q, x, y, 0);
339
 
            x += pack_x_pitch;
340
 
         }
341
 
 
342
 
         x = 0;
343
 
         y += pack_y_pitch;
344
 
      }
345
 
 
346
 
 
347
 
      tex->total_height += y;
348
 
      width  = u_minify(width, 1);
349
 
      height = u_minify(height, 1);
350
 
      depth  = u_minify(depth, 1);
351
 
 
352
 
      if (tex->compressed) {
353
 
         pack_y_pitch = (height + 3) / 4;
354
 
 
355
 
         if (pack_x_pitch > align(width, align_w)) {
356
 
            pack_x_pitch = align(width, align_w);
357
 
            pack_x_nr <<= 1;
358
 
         }
359
 
      } else {
360
 
         if (pack_x_pitch > 4) {
361
 
            pack_x_pitch >>= 1;
362
 
            pack_x_nr <<= 1;
363
 
            assert(pack_x_pitch * pack_x_nr <= tex->pitch);
364
 
         }
365
 
 
366
 
         if (pack_y_pitch > 2) {
367
 
            pack_y_pitch >>= 1;
368
 
            pack_y_pitch = align(pack_y_pitch, align_h);
369
 
         }
370
 
      }
371
 
   }
372
 
 
373
 
   /* The 965's sampler lays cachelines out according to how accesses
374
 
    * in the texture surfaces run, so they may be "vertical" through
375
 
    * memory.  As a result, the docs say in Surface Padding Requirements:
376
 
    * Sampling Engine Surfaces that two extra rows of padding are required.
377
 
    */
378
 
   if (tex->base.target == PIPE_TEXTURE_CUBE)
379
 
      tex->total_height += 2;
380
 
 
381
 
   return TRUE;
382
 
}
383
 
 
384
 
 
385
 
 
386
 
GLboolean brw_texture_layout(struct brw_screen *brw_screen,
387
 
                             struct brw_texture *tex )
388
 
{
389
 
   switch (tex->base.target) {
390
 
   case PIPE_TEXTURE_CUBE:
391
 
      if (brw_screen->chipset.is_igdng)
392
 
         brw_layout_cubemap_idgng( tex );
393
 
      else
394
 
         brw_layout_3d_cube( tex );
395
 
      break;
396
 
            
397
 
   case PIPE_TEXTURE_3D:
398
 
      brw_layout_3d_cube( tex );
399
 
      break;
400
 
 
401
 
   default:
402
 
      brw_layout_2d( tex );
403
 
      break;
404
 
   }
405
 
 
406
 
   if (BRW_DEBUG & DEBUG_TEXTURE)
407
 
      debug_printf("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
408
 
                   tex->pitch,
409
 
                   tex->total_height,
410
 
                   tex->cpp,
411
 
                   tex->pitch * tex->total_height * tex->cpp );
412
 
 
413
 
   return GL_TRUE;
414
 
}