remove unused vars
[mesa.git] / src / mesa / drivers / dri / r300 / r300_texstate.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r300/r300_texstate.c,v 1.3 2003/02/15 22:18:47 dawes Exp $ */
2 /*
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4
5 The Weather Channel (TM) funded Tungsten Graphics to develop the
6 initial release of the Radeon 8500 driver under the XFree86 license.
7 This notice must be preserved.
8
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial
19 portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29 **************************************************************************/
30
31 /*
32 * Authors:
33 * Keith Whitwell <keith@tungstengraphics.com>
34 */
35
36 #include "glheader.h"
37 #include "imports.h"
38 #include "context.h"
39 #include "macros.h"
40 #include "texformat.h"
41 #include "enums.h"
42
43 #include "r300_context.h"
44 #include "r300_state.h"
45 #include "r300_ioctl.h"
46 #include "radeon_ioctl.h"
47 #include "r300_tex.h"
48 #include "r300_reg.h"
49
50
51 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5 \
52 || ((f) >= MESA_FORMAT_RGBA_FLOAT32 && \
53 (f) <= MESA_FORMAT_INTENSITY_FLOAT16)) \
54 && tx_table_le[f].flag )
55
56 #define _ASSIGN(entry, format) \
57 [ MESA_FORMAT_ ## entry ] = { format, 0, 1}
58
59 static const struct {
60 GLuint format, filter, flag;
61 } tx_table_be[] = {
62 /*
63 * Note that the _REV formats are the same as the non-REV formats.
64 * This is because the REV and non-REV formats are identical as a
65 * byte string, but differ when accessed as 16-bit or 32-bit words
66 * depending on the endianness of the host. Since the textures are
67 * transferred to the R300 as a byte string (i.e. without any
68 * byte-swapping), the R300 sees the REV and non-REV formats
69 * identically. -- paulus
70 */
71 _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
72 _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
73 _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
74 _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
75 _ASSIGN(RGB888, 0xffffffff),
76 _ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
77 _ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
78 _ASSIGN(ARGB4444, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
79 _ASSIGN(ARGB4444_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
80 _ASSIGN(ARGB1555, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
81 _ASSIGN(ARGB1555_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
82 _ASSIGN(AL88, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
83 _ASSIGN(AL88_REV, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
84 _ASSIGN(RGB332, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z3Y3X2)),
85 _ASSIGN(A8, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8)),
86 _ASSIGN(L8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8)),
87 _ASSIGN(I8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
88 _ASSIGN(CI8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
89 _ASSIGN(YCBCR, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8)|R300_TX_FORMAT_YUV_MODE ),
90 _ASSIGN(YCBCR_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8)|R300_TX_FORMAT_YUV_MODE),
91 _ASSIGN(RGB_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1)),
92 _ASSIGN(RGBA_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1)),
93 _ASSIGN(RGBA_DXT3, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3)),
94 _ASSIGN(RGBA_DXT5, R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5)),
95 _ASSIGN(RGBA_FLOAT32, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R32G32B32A32)),
96 _ASSIGN(RGBA_FLOAT16, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R16G16B16A16)),
97 _ASSIGN(RGB_FLOAT32, 0xffffffff),
98 _ASSIGN(RGB_FLOAT16, 0xffffffff),
99 _ASSIGN(ALPHA_FLOAT32, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I32)),
100 _ASSIGN(ALPHA_FLOAT16, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I16)),
101 _ASSIGN(LUMINANCE_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I32)),
102 _ASSIGN(LUMINANCE_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I16)),
103 _ASSIGN(LUMINANCE_ALPHA_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I32A32)),
104 _ASSIGN(LUMINANCE_ALPHA_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16)),
105 _ASSIGN(INTENSITY_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, X, FL_I32)),
106 _ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)),
107 };
108
109 static const struct {
110 GLuint format, filter, flag;
111 } tx_table_le[] = {
112 _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
113 _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
114 _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
115 _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
116 _ASSIGN(RGB888, 0xffffffff),
117 _ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
118 _ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
119 _ASSIGN(ARGB4444, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
120 _ASSIGN(ARGB4444_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
121 _ASSIGN(ARGB1555, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
122 _ASSIGN(ARGB1555_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
123 _ASSIGN(AL88, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
124 _ASSIGN(AL88_REV, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
125 _ASSIGN(RGB332, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z3Y3X2)),
126 _ASSIGN(A8, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8)),
127 _ASSIGN(L8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8)),
128 _ASSIGN(I8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
129 _ASSIGN(CI8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
130 _ASSIGN(YCBCR, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8)|R300_TX_FORMAT_YUV_MODE ),
131 _ASSIGN(YCBCR_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8)|R300_TX_FORMAT_YUV_MODE),
132 _ASSIGN(RGB_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1)),
133 _ASSIGN(RGBA_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1)),
134 _ASSIGN(RGBA_DXT3, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3)),
135 _ASSIGN(RGBA_DXT5, R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5)),
136 _ASSIGN(RGBA_FLOAT32, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R32G32B32A32)),
137 _ASSIGN(RGBA_FLOAT16, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R16G16B16A16)),
138 _ASSIGN(RGB_FLOAT32, 0xffffffff),
139 _ASSIGN(RGB_FLOAT16, 0xffffffff),
140 _ASSIGN(ALPHA_FLOAT32, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I32)),
141 _ASSIGN(ALPHA_FLOAT16, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I16)),
142 _ASSIGN(LUMINANCE_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I32)),
143 _ASSIGN(LUMINANCE_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I16)),
144 _ASSIGN(LUMINANCE_ALPHA_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I32A32)),
145 _ASSIGN(LUMINANCE_ALPHA_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16)),
146 _ASSIGN(INTENSITY_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, X, FL_I32)),
147 _ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)),
148 };
149
150 #undef _ASSIGN
151
152
153 /**
154 * This function computes the number of bytes of storage needed for
155 * the given texture object (all mipmap levels, all cube faces).
156 * The \c image[face][level].x/y/width/height parameters for upload/blitting
157 * are computed here. \c filter, \c format, etc. will be set here
158 * too.
159 *
160 * \param rmesa Context pointer
161 * \param tObj GL texture object whose images are to be posted to
162 * hardware state.
163 */
164 static void r300SetTexImages(r300ContextPtr rmesa,
165 struct gl_texture_object *tObj)
166 {
167 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
168 const struct gl_texture_image *baseImage =
169 tObj->Image[0][tObj->BaseLevel];
170 GLint curOffset, blitWidth;
171 GLint i, texelBytes;
172 GLint numLevels;
173 GLint log2Width, log2Height, log2Depth;
174
175 /* Set the hardware texture format
176 */
177 if (VALID_FORMAT(baseImage->TexFormat->MesaFormat)) {
178 if (_mesa_little_endian()) {
179 t->format =
180 tx_table_le[baseImage->TexFormat->MesaFormat].format;
181 t->filter |=
182 tx_table_le[baseImage->TexFormat->MesaFormat].filter;
183 } else {
184 t->format =
185 tx_table_be[baseImage->TexFormat->MesaFormat].format;
186 t->filter |=
187 tx_table_be[baseImage->TexFormat->MesaFormat].filter;
188 }
189 } else {
190 _mesa_problem(NULL, "unexpected texture format in %s",
191 __FUNCTION__);
192 return;
193 }
194
195 texelBytes = baseImage->TexFormat->TexelBytes;
196
197 /* Compute which mipmap levels we really want to send to the hardware.
198 */
199 driCalculateTextureFirstLastLevel((driTextureObject *) t);
200 log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
201 log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
202 log2Depth = tObj->Image[0][t->base.firstLevel]->DepthLog2;
203
204 numLevels = t->base.lastLevel - t->base.firstLevel + 1;
205
206 assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS);
207
208 /* Calculate mipmap offsets and dimensions for blitting (uploading)
209 * The idea is that we lay out the mipmap levels within a block of
210 * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
211 */
212 curOffset = 0;
213 blitWidth = R300_BLIT_WIDTH_BYTES;
214 t->tile_bits = 0;
215
216 /* figure out if this texture is suitable for tiling. */
217 #if 0 /* Disabled for now */
218 if (texelBytes) {
219 if (rmesa->texmicrotile && (tObj->Target != GL_TEXTURE_RECTANGLE_NV) &&
220 /* texrect might be able to use micro tiling too in theory? */
221 (baseImage->Height > 1)) {
222
223 /* allow 32 (bytes) x 1 mip (which will use two times the space
224 the non-tiled version would use) max if base texture is large enough */
225 if ((numLevels == 1) ||
226 (((baseImage->Width * texelBytes / baseImage->Height) <= 32) &&
227 (baseImage->Width * texelBytes > 64)) ||
228 ((baseImage->Width * texelBytes / baseImage->Height) <= 16)) {
229 t->tile_bits |= R300_TXO_MICRO_TILE;
230 }
231 }
232
233 if (tObj->Target != GL_TEXTURE_RECTANGLE_NV) {
234 /* we can set macro tiling even for small textures, they will be untiled anyway */
235 t->tile_bits |= R300_TXO_MACRO_TILE;
236 }
237 }
238 #endif
239
240 for (i = 0; i < numLevels; i++) {
241 const struct gl_texture_image *texImage;
242 GLuint size;
243
244 texImage = tObj->Image[0][i + t->base.firstLevel];
245 if (!texImage)
246 break;
247
248 /* find image size in bytes */
249 if (texImage->IsCompressed) {
250 if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1) {
251 // fprintf(stderr,"DXT 1 %d %08X\n", texImage->Width, t->format);
252 if ((texImage->Width + 3) < 8) /* width one block */
253 size = texImage->CompressedSize * 4;
254 else if ((texImage->Width + 3) < 16)
255 size = texImage->CompressedSize * 2;
256 else size = texImage->CompressedSize;
257 }
258 else /* DXT3/5, 16 bytes per block */
259 {
260 WARN_ONCE("DXT 3/5 suffers from multitexturing problems!\n");
261 // fprintf(stderr,"DXT 3/5 %d\n", texImage->Width);
262 if ((texImage->Width + 3) < 8)
263 size = texImage->CompressedSize * 2;
264 else size = texImage->CompressedSize;
265 }
266
267 } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
268 size = ((texImage->Width * texelBytes + 63) & ~63) * texImage->Height;
269 blitWidth = 64 / texelBytes;
270 } else if (t->tile_bits & R300_TXO_MICRO_TILE) {
271 /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
272 though the actual offset may be different (if texture is less than
273 32 bytes width) to the untiled case */
274 int w = (texImage->Width * texelBytes * 2 + 31) & ~31;
275 size = (w * ((texImage->Height + 1) / 2)) * texImage->Depth;
276 blitWidth = MAX2(texImage->Width, 64 / texelBytes);
277 } else {
278 int w = (texImage->Width * texelBytes + 31) & ~31;
279 size = w * texImage->Height * texImage->Depth;
280 blitWidth = MAX2(texImage->Width, 64 / texelBytes);
281 }
282 assert(size > 0);
283
284 if(0)
285 fprintf(stderr, "w=%d h=%d d=%d tb=%d intFormat=%d\n", texImage->Width, texImage->Height,
286 texImage->Depth, texImage->TexFormat->TexelBytes,
287 texImage->InternalFormat);
288
289 /* Align to 32-byte offset. It is faster to do this unconditionally
290 * (no branch penalty).
291 */
292
293 curOffset = (curOffset + 0x1f) & ~0x1f;
294
295 if (texelBytes) {
296 t->image[0][i].x = curOffset; /* fix x and y coords up later together with offset */
297 t->image[0][i].y = 0;
298 t->image[0][i].width = MIN2(size / texelBytes, blitWidth);
299 t->image[0][i].height = (size / texelBytes) / t->image[0][i].width;
300 } else {
301 t->image[0][i].x = curOffset % R300_BLIT_WIDTH_BYTES;
302 t->image[0][i].y = curOffset / R300_BLIT_WIDTH_BYTES;
303 t->image[0][i].width = MIN2(size, R300_BLIT_WIDTH_BYTES);
304 t->image[0][i].height = size / t->image[0][i].width;
305 }
306 #if 0
307 /* for debugging only and only applicable to non-rectangle targets */
308 assert(size % t->image[0][i].width == 0);
309 assert(t->image[0][i].x == 0
310 || (size < R300_BLIT_WIDTH_BYTES
311 && t->image[0][i].height == 1));
312 #endif
313
314 if (0)
315 fprintf(stderr,
316 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
317 i, texImage->Width, texImage->Height,
318 t->image[0][i].x, t->image[0][i].y,
319 t->image[0][i].width, t->image[0][i].height,
320 size, curOffset);
321
322 curOffset += size;
323
324 }
325
326 /* Align the total size of texture memory block.
327 */
328 t->base.totalSize =
329 (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
330
331 /* Setup remaining cube face blits, if needed */
332 if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
333 GLuint face;
334 for (face = 1; face < 6; face++) {
335 for (i = 0; i < numLevels; i++) {
336 t->image[face][i].x = t->image[0][i].x;
337 t->image[face][i].y = t->image[0][i].y;
338 t->image[face][i].width = t->image[0][i].width;
339 t->image[face][i].height =
340 t->image[0][i].height;
341 }
342 }
343 t->base.totalSize *= 6; /* total texmem needed */
344 }
345
346 /* Hardware state:
347 */
348 #if 0
349 t->format &= ~(R200_TXFORMAT_WIDTH_MASK |
350 R200_TXFORMAT_HEIGHT_MASK |
351 R200_TXFORMAT_CUBIC_MAP_ENABLE |
352 R200_TXFORMAT_F5_WIDTH_MASK |
353 R200_TXFORMAT_F5_HEIGHT_MASK);
354 t->format |= ((log2Width << R200_TXFORMAT_WIDTH_SHIFT) |
355 (log2Height << R200_TXFORMAT_HEIGHT_SHIFT));
356 #endif
357 #if 0
358 t->format_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK);
359 if (tObj->Target == GL_TEXTURE_3D) {
360 t->format_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT);
361 t->format_x |= R200_TEXCOORD_VOLUME;
362 } else if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
363 ASSERT(log2Width == log2Height);
364 t->format |= R300_TX_FORMAT_CUBIC_MAP;
365
366 t->format_x |= R200_TEXCOORD_CUBIC_ENV;
367 t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) |
368 (log2Height << R200_FACE_HEIGHT_1_SHIFT) |
369 (log2Width << R200_FACE_WIDTH_2_SHIFT) |
370 (log2Height << R200_FACE_HEIGHT_2_SHIFT) |
371 (log2Width << R200_FACE_WIDTH_3_SHIFT) |
372 (log2Height << R200_FACE_HEIGHT_3_SHIFT) |
373 (log2Width << R200_FACE_WIDTH_4_SHIFT) |
374 (log2Height << R200_FACE_HEIGHT_4_SHIFT));
375 }
376 #endif
377 if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
378 ASSERT(log2Width == log2Height);
379 t->format |= R300_TX_FORMAT_CUBIC_MAP;
380 }
381
382 t->size = (((tObj->Image[0][t->base.firstLevel]->Width - 1) << R300_TX_WIDTHMASK_SHIFT)
383 |((tObj->Image[0][t->base.firstLevel]->Height - 1) << R300_TX_HEIGHTMASK_SHIFT))
384 |((numLevels - 1) << R300_TX_MAX_MIP_LEVEL_SHIFT);
385
386 /* Only need to round to nearest 32 for textures, but the blitter
387 * requires 64-byte aligned pitches, and we may/may not need the
388 * blitter. NPOT only!
389 */
390 if (baseImage->IsCompressed) {
391 t->pitch =
392 (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63);
393 }
394 else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
395 unsigned int align = blitWidth - 1;
396 t->pitch = ((tObj->Image[0][t->base.firstLevel]->Width *
397 texelBytes) + 63) & ~(63);
398 t->size |= R300_TX_SIZE_TXPITCH_EN;
399 t->pitch_reg = (((tObj->Image[0][t->base.firstLevel]->Width) + align) & ~align) - 1;
400 }
401 else {
402 t->pitch =
403 ((tObj->Image[0][t->base.firstLevel]->Width *
404 texelBytes) + 63) & ~(63);
405 }
406
407 t->dirty_state = TEX_ALL;
408
409 /* FYI: r300UploadTexImages( rmesa, t ) used to be called here */
410 }
411
412
413 /* ================================================================
414 * Texture unit state management
415 */
416
417 static GLboolean enable_tex_2d(GLcontext * ctx, int unit)
418 {
419 r300ContextPtr rmesa = R300_CONTEXT(ctx);
420 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
421 struct gl_texture_object *tObj = texUnit->_Current;
422 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
423
424 ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D);
425
426 if (t->base.dirty_images[0]) {
427 R300_FIREVERTICES(rmesa);
428 r300SetTexImages(rmesa, tObj);
429 r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
430 if (!t->base.memBlock)
431 return GL_FALSE;
432 }
433
434 return GL_TRUE;
435 }
436
437 #if ENABLE_HW_3D_TEXTURE
438 static GLboolean enable_tex_3d(GLcontext * ctx, int unit)
439 {
440 r300ContextPtr rmesa = R300_CONTEXT(ctx);
441 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
442 struct gl_texture_object *tObj = texUnit->_Current;
443 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
444
445 /* Need to load the 3d images associated with this unit.
446 */
447 #if 0
448 if (t->format & R200_TXFORMAT_NON_POWER2) {
449 t->format &= ~R200_TXFORMAT_NON_POWER2;
450 t->base.dirty_images[0] = ~0;
451 }
452 #endif
453 ASSERT(tObj->Target == GL_TEXTURE_3D);
454
455 /* R100 & R200 do not support mipmaps for 3D textures.
456 */
457 if ((tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) {
458 return GL_FALSE;
459 }
460
461 if (t->base.dirty_images[0]) {
462 R300_FIREVERTICES(rmesa);
463 r300SetTexImages(rmesa, tObj);
464 r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
465 if (!t->base.memBlock)
466 return GL_FALSE;
467 }
468
469 return GL_TRUE;
470 }
471 #endif
472
473 static GLboolean enable_tex_cube(GLcontext * ctx, int unit)
474 {
475 r300ContextPtr rmesa = R300_CONTEXT(ctx);
476 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
477 struct gl_texture_object *tObj = texUnit->_Current;
478 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
479 GLuint face;
480
481 /* Need to load the 2d images associated with this unit.
482 */
483 #if 0
484 if (t->format & R200_TXFORMAT_NON_POWER2) {
485 t->format &= ~R200_TXFORMAT_NON_POWER2;
486 for (face = 0; face < 6; face++)
487 t->base.dirty_images[face] = ~0;
488 }
489 #endif
490 ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP);
491
492 if (t->base.dirty_images[0] || t->base.dirty_images[1] ||
493 t->base.dirty_images[2] || t->base.dirty_images[3] ||
494 t->base.dirty_images[4] || t->base.dirty_images[5]) {
495 /* flush */
496 R300_FIREVERTICES(rmesa);
497 /* layout memory space, once for all faces */
498 r300SetTexImages(rmesa, tObj);
499 }
500
501 /* upload (per face) */
502 for (face = 0; face < 6; face++) {
503 if (t->base.dirty_images[face]) {
504 r300UploadTexImages(rmesa,
505 (r300TexObjPtr) tObj->DriverData,
506 face);
507 }
508 }
509
510 if (!t->base.memBlock) {
511 /* texmem alloc failed, use s/w fallback */
512 return GL_FALSE;
513 }
514
515 return GL_TRUE;
516 }
517
518 static GLboolean enable_tex_rect(GLcontext * ctx, int unit)
519 {
520 r300ContextPtr rmesa = R300_CONTEXT(ctx);
521 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
522 struct gl_texture_object *tObj = texUnit->_Current;
523 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
524
525 ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);
526
527 if (t->base.dirty_images[0]) {
528 R300_FIREVERTICES(rmesa);
529 r300SetTexImages(rmesa, tObj);
530 r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
531 if (!t->base.memBlock && !rmesa->prefer_gart_client_texturing)
532 return GL_FALSE;
533 }
534
535 return GL_TRUE;
536 }
537
538 static GLboolean update_tex_common(GLcontext * ctx, int unit)
539 {
540 r300ContextPtr rmesa = R300_CONTEXT(ctx);
541 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
542 struct gl_texture_object *tObj = texUnit->_Current;
543 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
544
545 /* Fallback if there's a texture border */
546 if (tObj->Image[0][tObj->BaseLevel]->Border > 0)
547 return GL_FALSE;
548
549 /* Update state if this is a different texture object to last
550 * time.
551 */
552 if (rmesa->state.texture.unit[unit].texobj != t) {
553 if (rmesa->state.texture.unit[unit].texobj != NULL) {
554 /* The old texture is no longer bound to this texture unit.
555 * Mark it as such.
556 */
557
558 rmesa->state.texture.unit[unit].texobj->base.bound &=
559 ~(1UL << unit);
560 }
561
562 rmesa->state.texture.unit[unit].texobj = t;
563 t->base.bound |= (1UL << unit);
564 t->dirty_state |= 1 << unit;
565 driUpdateTextureLRU((driTextureObject *) t); /* XXX: should be locked! */
566 }
567
568 return !t->border_fallback;
569 }
570
571 static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit)
572 {
573 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
574
575 if (texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT)) {
576 return (enable_tex_rect(ctx, unit) &&
577 update_tex_common(ctx, unit));
578 } else if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) {
579 return (enable_tex_2d(ctx, unit) &&
580 update_tex_common(ctx, unit));
581 }
582 #if ENABLE_HW_3D_TEXTURE
583 else if (texUnit->_ReallyEnabled & (TEXTURE_3D_BIT)) {
584 return (enable_tex_3d(ctx, unit) &&
585 update_tex_common(ctx, unit));
586 }
587 #endif
588 else if (texUnit->_ReallyEnabled & (TEXTURE_CUBE_BIT)) {
589 return (enable_tex_cube(ctx, unit) &&
590 update_tex_common(ctx, unit));
591 } else if (texUnit->_ReallyEnabled) {
592 return GL_FALSE;
593 } else {
594 return GL_TRUE;
595 }
596 }
597
598 void r300UpdateTextureState(GLcontext * ctx)
599 {
600 GLboolean ok;
601
602 ok = (r300UpdateTextureUnit(ctx, 0) &&
603 r300UpdateTextureUnit(ctx, 1) &&
604 r300UpdateTextureUnit(ctx, 2) &&
605 r300UpdateTextureUnit(ctx, 3) &&
606 r300UpdateTextureUnit(ctx, 4) &&
607 r300UpdateTextureUnit(ctx, 5) &&
608 r300UpdateTextureUnit(ctx, 6) &&
609 r300UpdateTextureUnit(ctx, 7)
610 );
611 }