fix compiler warnings
[mesa.git] / src / mesa / drivers / dri / i915tex / i915_tex_layout.c
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 }