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

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/i915tex/i915_tex_layout.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-02-21 12:44:07 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: james.westby@ubuntu.com-20070221124407-rgcacs32mycrtadl
ImportĀ upstreamĀ versionĀ 6.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
 * 
 
3
 * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
 
4
 * All Rights Reserved.
 
5
 * 
 
6
 * Permission is hereby granted, free of charge, to any person obtaining a
 
7
 * 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, sub license, 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 portions
 
16
 * of the Software.
 
17
 * 
 
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
19
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
20
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 
21
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
 
22
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 
23
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 
24
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
25
 * 
 
26
 **************************************************************************/
 
27
 
 
28
/* Code to layout images in a mipmap tree for i915 and i945
 
29
 * respectively.
 
30
 */
 
31
 
 
32
#include "intel_mipmap_tree.h"
 
33
#include "macros.h"
 
34
#include "intel_context.h"
 
35
 
 
36
#define FILE_DEBUG_FLAG DEBUG_TEXTURE
 
37
 
 
38
static GLint initial_offsets[6][2] = { {0, 0},
 
39
{0, 2},
 
40
{1, 0},
 
41
{1, 2},
 
42
{1, 1},
 
43
{1, 3}
 
44
};
 
45
 
 
46
 
 
47
static GLint step_offsets[6][2] = { {0, 2},
 
48
{0, 2},
 
49
{-1, 2},
 
50
{-1, 2},
 
51
{-1, 1},
 
52
{-1, 1}
 
53
};
 
54
 
 
55
static GLuint
 
56
minify(GLuint d)
 
57
{
 
58
   return MAX2(1, d >> 1);
 
59
}
 
60
 
 
61
GLboolean
 
62
i915_miptree_layout(struct intel_mipmap_tree * mt)
 
63
{
 
64
   GLint level;
 
65
 
 
66
   switch (mt->target) {
 
67
   case GL_TEXTURE_CUBE_MAP:{
 
68
         const GLuint dim = mt->width0;
 
69
         GLuint face;
 
70
 
 
71
         /* double pitch for cube layouts */
 
72
         mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp;
 
73
         mt->total_height = dim * 4;
 
74
 
 
75
         for (level = mt->first_level; level <= mt->last_level; level++)
 
76
            intel_miptree_set_level_info(mt, level, 6,
 
77
                                         0, 0,
 
78
                                         mt->pitch, mt->total_height, 1);
 
79
 
 
80
         for (face = 0; face < 6; face++) {
 
81
            GLuint x = initial_offsets[face][0] * dim;
 
82
            GLuint y = initial_offsets[face][1] * dim;
 
83
            GLuint d = dim;
 
84
 
 
85
            for (level = mt->first_level; level <= mt->last_level; level++) {
 
86
               intel_miptree_set_image_offset(mt, level, face, x, y);
 
87
 
 
88
               if (d == 0)
 
89
                  _mesa_printf("cube mipmap %d/%d (%d..%d) is 0x0\n",
 
90
                               face, level, mt->first_level, mt->last_level);
 
91
 
 
92
               d >>= 1;
 
93
               x += step_offsets[face][0] * d;
 
94
               y += step_offsets[face][1] * d;
 
95
            }
 
96
         }
 
97
         break;
 
98
      }
 
99
   case GL_TEXTURE_3D:{
 
100
         GLuint width = mt->width0;
 
101
         GLuint height = mt->height0;
 
102
         GLuint depth = mt->depth0;
 
103
         GLuint stack_height = 0;
 
104
 
 
105
         /* Calculate the size of a single slice. 
 
106
          */
 
107
         mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
 
108
 
 
109
         /* XXX: hardware expects/requires 9 levels at minimum.
 
110
          */
 
111
         for (level = mt->first_level; level <= MAX2(8, mt->last_level);
 
112
              level++) {
 
113
            intel_miptree_set_level_info(mt, level, 1, 0, mt->total_height,
 
114
                                         width, height, depth);
 
115
 
 
116
 
 
117
            stack_height += MAX2(2, height);
 
118
 
 
119
            width = minify(width);
 
120
            height = minify(height);
 
121
            depth = minify(depth);
 
122
         }
 
123
 
 
124
         /* Fixup depth image_offsets: 
 
125
          */
 
126
         depth = mt->depth0;
 
127
         for (level = mt->first_level; level <= mt->last_level; level++) {
 
128
            GLuint i;
 
129
            for (i = 0; i < depth; i++) 
 
130
               intel_miptree_set_image_offset(mt, level, i,
 
131
                                              0, i * stack_height);
 
132
 
 
133
            depth = minify(depth);
 
134
         }
 
135
 
 
136
 
 
137
         /* Multiply slice size by texture depth for total size.  It's
 
138
          * remarkable how wasteful of memory the i915 texture layouts
 
139
          * are.  They are largely fixed in the i945.
 
140
          */
 
141
         mt->total_height = stack_height * mt->depth0;
 
142
         break;
 
143
      }
 
144
 
 
145
   default:{
 
146
         GLuint width = mt->width0;
 
147
         GLuint height = mt->height0;
 
148
         GLuint img_height;
 
149
 
 
150
         mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
 
151
         mt->total_height = 0;
 
152
 
 
153
         for (level = mt->first_level; level <= mt->last_level; level++) {
 
154
            intel_miptree_set_level_info(mt, level, 1,
 
155
                                         0, mt->total_height,
 
156
                                         width, height, 1);
 
157
 
 
158
            if (mt->compressed)
 
159
               img_height = MAX2(1, height / 4);
 
160
            else
 
161
               img_height = MAX2(2, height);
 
162
 
 
163
            mt->total_height += img_height;
 
164
            mt->total_height += 1;
 
165
            mt->total_height &= ~1;
 
166
 
 
167
            width = minify(width);
 
168
            height = minify(height);
 
169
         }
 
170
         break;
 
171
      }
 
172
   }
 
173
   DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
 
174
       mt->pitch,
 
175
       mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp);
 
176
 
 
177
   return GL_TRUE;
 
178
}
 
179
 
 
180
 
 
181
GLboolean
 
182
i945_miptree_layout(struct intel_mipmap_tree * mt)
 
183
{
 
184
   GLint level;
 
185
 
 
186
   switch (mt->target) {
 
187
   case GL_TEXTURE_CUBE_MAP:{
 
188
         const GLuint dim = mt->width0;
 
189
         GLuint face;
 
190
 
 
191
         /* Depending on the size of the largest images, pitch can be
 
192
          * determined either by the old-style packing of cubemap faces,
 
193
          * or the final row of 4x4, 2x2 and 1x1 faces below this. 
 
194
          */
 
195
         if (dim > 32)
 
196
            mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp;
 
197
         else
 
198
            mt->pitch = 14 * 8;
 
199
 
 
200
         mt->total_height = dim * 4 + 4;
 
201
 
 
202
         /* Set all the levels to effectively occupy the whole rectangular region. 
 
203
          */
 
204
         for (level = mt->first_level; level <= mt->last_level; level++)
 
205
            intel_miptree_set_level_info(mt, level, 6,
 
206
                                         0, 0,
 
207
                                         mt->pitch, mt->total_height, 1);
 
208
 
 
209
 
 
210
 
 
211
         for (face = 0; face < 6; face++) {
 
212
            GLuint x = initial_offsets[face][0] * dim;
 
213
            GLuint y = initial_offsets[face][1] * dim;
 
214
            GLuint d = dim;
 
215
 
 
216
            if (dim == 4 && face >= 4) {
 
217
               y = mt->total_height - 4;
 
218
               x = (face - 4) * 8;
 
219
            }
 
220
            else if (dim < 4) {
 
221
               y = mt->total_height - 4;
 
222
               x = face * 8;
 
223
            }
 
224
 
 
225
            for (level = mt->first_level; level <= mt->last_level; level++) {
 
226
               intel_miptree_set_image_offset(mt, level, face, x, y);
 
227
 
 
228
               d >>= 1;
 
229
 
 
230
               switch (d) {
 
231
               case 4:
 
232
                  switch (face) {
 
233
                  case FACE_POS_X:
 
234
                  case FACE_NEG_X:
 
235
                     x += step_offsets[face][0] * d;
 
236
                     y += step_offsets[face][1] * d;
 
237
                     break;
 
238
                  case FACE_POS_Y:
 
239
                  case FACE_NEG_Y:
 
240
                     y += 12;
 
241
                     x -= 8;
 
242
                     break;
 
243
                  case FACE_POS_Z:
 
244
                  case FACE_NEG_Z:
 
245
                     y = mt->total_height - 4;
 
246
                     x = (face - 4) * 8;
 
247
                     break;
 
248
                  }
 
249
 
 
250
               case 2:
 
251
                  y = mt->total_height - 4;
 
252
                  x = 16 + face * 8;
 
253
                  break;
 
254
 
 
255
               case 1:
 
256
                  x += 48;
 
257
                  break;
 
258
 
 
259
               default:
 
260
                  x += step_offsets[face][0] * d;
 
261
                  y += step_offsets[face][1] * d;
 
262
                  break;
 
263
               }
 
264
            }
 
265
         }
 
266
         break;
 
267
      }
 
268
   case GL_TEXTURE_3D:{
 
269
         GLuint width = mt->width0;
 
270
         GLuint height = mt->height0;
 
271
         GLuint depth = mt->depth0;
 
272
         GLuint pack_x_pitch, pack_x_nr;
 
273
         GLuint pack_y_pitch;
 
274
         GLuint level;
 
275
 
 
276
         mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
 
277
         mt->total_height = 0;
 
278
 
 
279
         pack_y_pitch = MAX2(mt->height0, 2);
 
280
         pack_x_pitch = mt->pitch;
 
281
         pack_x_nr = 1;
 
282
 
 
283
         for (level = mt->first_level; level <= mt->last_level; level++) {
 
284
            GLuint nr_images = mt->target == GL_TEXTURE_3D ? depth : 6;
 
285
            GLint x = 0;
 
286
            GLint y = 0;
 
287
            GLint q, j;
 
288
 
 
289
            intel_miptree_set_level_info(mt, level, nr_images,
 
290
                                         0, mt->total_height,
 
291
                                         width, height, depth);
 
292
 
 
293
            for (q = 0; q < nr_images;) {
 
294
               for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
 
295
                  intel_miptree_set_image_offset(mt, level, q, x, y);
 
296
                  x += pack_x_pitch;
 
297
               }
 
298
 
 
299
               x = 0;
 
300
               y += pack_y_pitch;
 
301
            }
 
302
 
 
303
 
 
304
            mt->total_height += y;
 
305
 
 
306
            if (pack_x_pitch > 4) {
 
307
               pack_x_pitch >>= 1;
 
308
               pack_x_nr <<= 1;
 
309
               assert(pack_x_pitch * pack_x_nr <= mt->pitch);
 
310
            }
 
311
 
 
312
            if (pack_y_pitch > 2) {
 
313
               pack_y_pitch >>= 1;
 
314
            }
 
315
 
 
316
            width = minify(width);
 
317
            height = minify(height);
 
318
            depth = minify(depth);
 
319
         }
 
320
         break;
 
321
      }
 
322
 
 
323
   case GL_TEXTURE_1D:
 
324
   case GL_TEXTURE_2D:
 
325
   case GL_TEXTURE_RECTANGLE_ARB:{
 
326
         GLuint x = 0;
 
327
         GLuint y = 0;
 
328
         GLuint width = mt->width0;
 
329
         GLuint height = mt->height0;
 
330
         GLint align_h = 2;
 
331
 
 
332
         mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
 
333
         mt->total_height = 0;
 
334
 
 
335
         for (level = mt->first_level; level <= mt->last_level; level++) {
 
336
            GLuint img_height;
 
337
 
 
338
            intel_miptree_set_level_info(mt, level, 1,
 
339
                                         x, y, 
 
340
                                         width, 
 
341
                                         mt->compressed ? height/4 : height, 1);
 
342
 
 
343
 
 
344
            if (mt->compressed)
 
345
               img_height = MAX2(1, height / 4);
 
346
            else
 
347
               img_height = MAX2(align_h, height);
 
348
 
 
349
            /* LPT change: step right after second mipmap.
 
350
             */
 
351
            if (level == mt->first_level + 1) {
 
352
               x += mt->pitch / 2;
 
353
               x = (x + 3) & ~3;
 
354
            }
 
355
            else {
 
356
               y += img_height;
 
357
               y += align_h - 1;
 
358
               y &= ~(align_h - 1);
 
359
            }
 
360
 
 
361
            /* Because the images are packed better, the final offset
 
362
             * might not be the maximal one:
 
363
             */
 
364
            mt->total_height = MAX2(mt->total_height, y);
 
365
 
 
366
            width = minify(width);
 
367
            height = minify(height);
 
368
         }
 
369
         break;
 
370
      }
 
371
   default:
 
372
      _mesa_problem(NULL, "Unexpected tex target in i945_miptree_layout()");
 
373
   }
 
374
 
 
375
   DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
 
376
       mt->pitch,
 
377
       mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp);
 
378
 
 
379
   return GL_TRUE;
 
380
}