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