Merge branch 'master' into r500test
[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 * \file
32 *
33 * \author Keith Whitwell <keith@tungstengraphics.com>
34 *
35 * \todo Enable R300 texture tiling code?
36 */
37
38 #include "glheader.h"
39 #include "imports.h"
40 #include "context.h"
41 #include "macros.h"
42 #include "texformat.h"
43 #include "teximage.h"
44 #include "texobj.h"
45 #include "enums.h"
46
47 #include "r300_context.h"
48 #include "r300_state.h"
49 #include "r300_ioctl.h"
50 #include "radeon_ioctl.h"
51 #include "r300_tex.h"
52 #include "r300_reg.h"
53
54 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5 \
55 || ((f) >= MESA_FORMAT_RGBA_FLOAT32 && \
56 (f) <= MESA_FORMAT_INTENSITY_FLOAT16)) \
57 && tx_table[f].flag )
58
59 #define _ASSIGN(entry, format) \
60 [ MESA_FORMAT_ ## entry ] = { format, 0, 1}
61
62 /*
63 * Note that the _REV formats are the same as the non-REV formats. This is
64 * because the REV and non-REV formats are identical as a byte string, but
65 * differ when accessed as 16-bit or 32-bit words depending on the endianness of
66 * the host. Since the textures are transferred to the R300 as a byte string
67 * (i.e. without any byte-swapping), the R300 sees the REV and non-REV formats
68 * identically. -- paulus
69 */
70
71 static const struct tx_table {
72 GLuint format, filter, flag;
73 } tx_table[] = {
74 /* *INDENT-OFF* */
75 #ifdef MESA_LITTLE_ENDIAN
76 _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
77 _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
78 _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
79 _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
80 #else
81 _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
82 _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
83 _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
84 _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
85 #endif
86 _ASSIGN(RGB888, R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)),
87 _ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
88 _ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
89 _ASSIGN(ARGB4444, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
90 _ASSIGN(ARGB4444_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
91 _ASSIGN(ARGB1555, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
92 _ASSIGN(ARGB1555_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
93 _ASSIGN(AL88, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
94 _ASSIGN(AL88_REV, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
95 _ASSIGN(RGB332, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z3Y3X2)),
96 _ASSIGN(A8, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8)),
97 _ASSIGN(L8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8)),
98 _ASSIGN(I8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
99 _ASSIGN(CI8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
100 _ASSIGN(YCBCR, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE),
101 _ASSIGN(YCBCR_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE),
102 _ASSIGN(RGB_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1)),
103 _ASSIGN(RGBA_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1)),
104 _ASSIGN(RGBA_DXT3, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3)),
105 _ASSIGN(RGBA_DXT5, R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5)),
106 _ASSIGN(RGBA_FLOAT32, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R32G32B32A32)),
107 _ASSIGN(RGBA_FLOAT16, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R16G16B16A16)),
108 _ASSIGN(RGB_FLOAT32, 0xffffffff),
109 _ASSIGN(RGB_FLOAT16, 0xffffffff),
110 _ASSIGN(ALPHA_FLOAT32, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I32)),
111 _ASSIGN(ALPHA_FLOAT16, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I16)),
112 _ASSIGN(LUMINANCE_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I32)),
113 _ASSIGN(LUMINANCE_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I16)),
114 _ASSIGN(LUMINANCE_ALPHA_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I32A32)),
115 _ASSIGN(LUMINANCE_ALPHA_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16)),
116 _ASSIGN(INTENSITY_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, X, FL_I32)),
117 _ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)),
118 _ASSIGN(Z16, R300_EASY_TX_FORMAT(X, X, X, X, X16)),
119 _ASSIGN(Z24_S8, R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8)),
120 _ASSIGN(Z32, R300_EASY_TX_FORMAT(X, X, X, X, X32)),
121 /* *INDENT-ON* */
122 };
123
124 #undef _ASSIGN
125
126 void r300SetDepthTexMode(struct gl_texture_object *tObj)
127 {
128 static const GLuint formats[3][3] = {
129 {
130 R300_EASY_TX_FORMAT(X, X, X, X, X16),
131 R300_EASY_TX_FORMAT(X, X, X, ONE, X16),
132 R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X16),
133 },
134 {
135 R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8),
136 R300_EASY_TX_FORMAT(X, X, X, ONE, X24_Y8),
137 R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X24_Y8),
138 },
139 {
140 R300_EASY_TX_FORMAT(X, X, X, X, X32),
141 R300_EASY_TX_FORMAT(X, X, X, ONE, X32),
142 R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X32),
143 },
144 };
145 const GLuint *format;
146 r300TexObjPtr t;
147
148 if (!tObj)
149 return;
150
151 t = (r300TexObjPtr) tObj->DriverData;
152
153
154 switch (tObj->Image[0][tObj->BaseLevel]->TexFormat->MesaFormat) {
155 case MESA_FORMAT_Z16:
156 format = formats[0];
157 break;
158 case MESA_FORMAT_Z24_S8:
159 format = formats[1];
160 break;
161 case MESA_FORMAT_Z32:
162 format = formats[2];
163 break;
164 default:
165 /* Error...which should have already been caught by higher
166 * levels of Mesa.
167 */
168 ASSERT(0);
169 return;
170 }
171
172 switch (tObj->DepthMode) {
173 case GL_LUMINANCE:
174 t->format = format[0];
175 break;
176 case GL_INTENSITY:
177 t->format = format[1];
178 break;
179 case GL_ALPHA:
180 t->format = format[2];
181 break;
182 default:
183 /* Error...which should have already been caught by higher
184 * levels of Mesa.
185 */
186 ASSERT(0);
187 return;
188 }
189 }
190
191
192 /**
193 * This function computes the number of bytes of storage needed for
194 * the given texture object (all mipmap levels, all cube faces).
195 * The \c image[face][level].x/y/width/height parameters for upload/blitting
196 * are computed here. \c filter, \c format, etc. will be set here
197 * too.
198 *
199 * \param rmesa Context pointer
200 * \param tObj GL texture object whose images are to be posted to
201 * hardware state.
202 */
203 static void r300SetTexImages(r300ContextPtr rmesa,
204 struct gl_texture_object *tObj)
205 {
206 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
207 const struct gl_texture_image *baseImage =
208 tObj->Image[0][tObj->BaseLevel];
209 GLint curOffset, blitWidth;
210 GLint i, texelBytes;
211 GLint numLevels;
212 GLint log2Width, log2Height, log2Depth;
213
214 /* Set the hardware texture format
215 */
216 if (!t->image_override
217 && VALID_FORMAT(baseImage->TexFormat->MesaFormat)) {
218 if (baseImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) {
219 r300SetDepthTexMode(tObj);
220 } else {
221 t->format = tx_table[baseImage->TexFormat->MesaFormat].format;
222 }
223
224 t->filter |= tx_table[baseImage->TexFormat->MesaFormat].filter;
225 } else if (!t->image_override) {
226 _mesa_problem(NULL, "unexpected texture format in %s",
227 __FUNCTION__);
228 return;
229 }
230
231 texelBytes = baseImage->TexFormat->TexelBytes;
232
233 /* Compute which mipmap levels we really want to send to the hardware.
234 */
235 driCalculateTextureFirstLastLevel((driTextureObject *) t);
236 log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
237 log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
238 log2Depth = tObj->Image[0][t->base.firstLevel]->DepthLog2;
239
240 numLevels = t->base.lastLevel - t->base.firstLevel + 1;
241
242 assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS);
243
244 /* Calculate mipmap offsets and dimensions for blitting (uploading)
245 * The idea is that we lay out the mipmap levels within a block of
246 * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
247 */
248 curOffset = 0;
249 blitWidth = R300_BLIT_WIDTH_BYTES;
250 t->tile_bits = 0;
251
252 /* figure out if this texture is suitable for tiling. */
253 #if 0 /* Disabled for now */
254 if (texelBytes) {
255 if ((tObj->Target != GL_TEXTURE_RECTANGLE_NV) &&
256 /* texrect might be able to use micro tiling too in theory? */
257 (baseImage->Height > 1)) {
258
259 /* allow 32 (bytes) x 1 mip (which will use two times the space
260 the non-tiled version would use) max if base texture is large enough */
261 if ((numLevels == 1) ||
262 (((baseImage->Width * texelBytes /
263 baseImage->Height) <= 32)
264 && (baseImage->Width * texelBytes > 64))
265 ||
266 ((baseImage->Width * texelBytes /
267 baseImage->Height) <= 16)) {
268 t->tile_bits |= R300_TXO_MICRO_TILE;
269 }
270 }
271
272 if (tObj->Target != GL_TEXTURE_RECTANGLE_NV) {
273 /* we can set macro tiling even for small textures, they will be untiled anyway */
274 t->tile_bits |= R300_TXO_MACRO_TILE;
275 }
276 }
277 #endif
278
279 for (i = 0; i < numLevels; i++) {
280 const struct gl_texture_image *texImage;
281 GLuint size;
282
283 texImage = tObj->Image[0][i + t->base.firstLevel];
284 if (!texImage)
285 break;
286
287 /* find image size in bytes */
288 if (texImage->IsCompressed) {
289 if ((t->format & R300_TX_FORMAT_DXT1) ==
290 R300_TX_FORMAT_DXT1) {
291 // fprintf(stderr,"DXT 1 %d %08X\n", texImage->Width, t->format);
292 if ((texImage->Width + 3) < 8) /* width one block */
293 size = texImage->CompressedSize * 4;
294 else if ((texImage->Width + 3) < 16)
295 size = texImage->CompressedSize * 2;
296 else
297 size = texImage->CompressedSize;
298 } else {
299 /* DXT3/5, 16 bytes per block */
300 WARN_ONCE
301 ("DXT 3/5 suffers from multitexturing problems!\n");
302 // fprintf(stderr,"DXT 3/5 %d\n", texImage->Width);
303 if ((texImage->Width + 3) < 8)
304 size = texImage->CompressedSize * 2;
305 else
306 size = texImage->CompressedSize;
307 }
308 } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
309 size =
310 ((texImage->Width * texelBytes +
311 63) & ~63) * texImage->Height;
312 blitWidth = 64 / texelBytes;
313 } else if (t->tile_bits & R300_TXO_MICRO_TILE) {
314 /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
315 though the actual offset may be different (if texture is less than
316 32 bytes width) to the untiled case */
317 int w = (texImage->Width * texelBytes * 2 + 31) & ~31;
318 size =
319 (w * ((texImage->Height + 1) / 2)) *
320 texImage->Depth;
321 blitWidth = MAX2(texImage->Width, 64 / texelBytes);
322 } else {
323 int w = (texImage->Width * texelBytes + 31) & ~31;
324 size = w * texImage->Height * texImage->Depth;
325 blitWidth = MAX2(texImage->Width, 64 / texelBytes);
326 }
327 assert(size > 0);
328
329 if (RADEON_DEBUG & DEBUG_TEXTURE)
330 fprintf(stderr, "w=%d h=%d d=%d tb=%d intFormat=%d\n",
331 texImage->Width, texImage->Height,
332 texImage->Depth,
333 texImage->TexFormat->TexelBytes,
334 texImage->InternalFormat);
335
336 /* Align to 32-byte offset. It is faster to do this unconditionally
337 * (no branch penalty).
338 */
339
340 curOffset = (curOffset + 0x1f) & ~0x1f;
341
342 if (texelBytes) {
343 /* fix x and y coords up later together with offset */
344 t->image[0][i].x = curOffset;
345 t->image[0][i].y = 0;
346 t->image[0][i].width =
347 MIN2(size / texelBytes, blitWidth);
348 t->image[0][i].height =
349 (size / texelBytes) / t->image[0][i].width;
350 } else {
351 t->image[0][i].x = curOffset % R300_BLIT_WIDTH_BYTES;
352 t->image[0][i].y = curOffset / R300_BLIT_WIDTH_BYTES;
353 t->image[0][i].width =
354 MIN2(size, R300_BLIT_WIDTH_BYTES);
355 t->image[0][i].height = size / t->image[0][i].width;
356 }
357
358 if (RADEON_DEBUG & DEBUG_TEXTURE)
359 fprintf(stderr,
360 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
361 i, texImage->Width, texImage->Height,
362 t->image[0][i].x, t->image[0][i].y,
363 t->image[0][i].width, t->image[0][i].height,
364 size, curOffset);
365
366 curOffset += size;
367 }
368
369 /* Align the total size of texture memory block.
370 */
371 t->base.totalSize =
372 (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
373
374 /* Setup remaining cube face blits, if needed */
375 if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
376 GLuint face;
377 for (face = 1; face < 6; face++) {
378 for (i = 0; i < numLevels; i++) {
379 t->image[face][i].x = t->image[0][i].x;
380 t->image[face][i].y = t->image[0][i].y;
381 t->image[face][i].width = t->image[0][i].width;
382 t->image[face][i].height =
383 t->image[0][i].height;
384 }
385 }
386 t->base.totalSize *= 6; /* total texmem needed */
387 }
388
389 if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
390 ASSERT(log2Width == log2Height);
391 t->format |= R300_TX_FORMAT_CUBIC_MAP;
392 }
393
394 t->size =
395 (((tObj->Image[0][t->base.firstLevel]->Width -
396 1) << R300_TX_WIDTHMASK_SHIFT)
397 | ((tObj->Image[0][t->base.firstLevel]->Height - 1) <<
398 R300_TX_HEIGHTMASK_SHIFT))
399 | ((numLevels - 1) << R300_TX_MAX_MIP_LEVEL_SHIFT);
400
401 /* Only need to round to nearest 32 for textures, but the blitter
402 * requires 64-byte aligned pitches, and we may/may not need the
403 * blitter. NPOT only!
404 */
405 if (baseImage->IsCompressed) {
406 t->pitch =
407 (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63);
408 } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
409 unsigned int align = blitWidth - 1;
410 t->pitch = ((tObj->Image[0][t->base.firstLevel]->Width *
411 texelBytes) + 63) & ~(63);
412 t->size |= R300_TX_SIZE_TXPITCH_EN;
413 if (!t->image_override)
414 t->pitch_reg =
415 (((tObj->Image[0][t->base.firstLevel]->Width) +
416 align) & ~align) - 1;
417 } else {
418 t->pitch =
419 ((tObj->Image[0][t->base.firstLevel]->Width *
420 texelBytes) + 63) & ~(63);
421 }
422
423 t->dirty_state = TEX_ALL;
424
425 /* FYI: r300UploadTexImages( rmesa, t ) used to be called here */
426 }
427
428 /* ================================================================
429 * Texture unit state management
430 */
431
432 static GLboolean r300EnableTexture2D(GLcontext * ctx, int unit)
433 {
434 r300ContextPtr rmesa = R300_CONTEXT(ctx);
435 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
436 struct gl_texture_object *tObj = texUnit->_Current;
437 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
438
439 ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D);
440
441 if (t->base.dirty_images[0]) {
442 R300_FIREVERTICES(rmesa);
443
444 r300SetTexImages(rmesa, tObj);
445 r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
446 if (!t->base.memBlock && !t->image_override)
447 return GL_FALSE;
448 }
449
450 return GL_TRUE;
451 }
452
453 static GLboolean r300EnableTexture3D(GLcontext * ctx, int unit)
454 {
455 r300ContextPtr rmesa = R300_CONTEXT(ctx);
456 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
457 struct gl_texture_object *tObj = texUnit->_Current;
458 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
459
460 ASSERT(tObj->Target == GL_TEXTURE_3D);
461
462 /* r300 does not support mipmaps for 3D textures. */
463 if ((tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) {
464 return GL_FALSE;
465 }
466
467 if (t->base.dirty_images[0]) {
468 R300_FIREVERTICES(rmesa);
469 r300SetTexImages(rmesa, tObj);
470 r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
471 if (!t->base.memBlock)
472 return GL_FALSE;
473 }
474
475 return GL_TRUE;
476 }
477
478 static GLboolean r300EnableTextureCube(GLcontext * ctx, int unit)
479 {
480 r300ContextPtr rmesa = R300_CONTEXT(ctx);
481 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
482 struct gl_texture_object *tObj = texUnit->_Current;
483 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
484 GLuint face;
485
486 ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP);
487
488 if (t->base.dirty_images[0] || t->base.dirty_images[1] ||
489 t->base.dirty_images[2] || t->base.dirty_images[3] ||
490 t->base.dirty_images[4] || t->base.dirty_images[5]) {
491 /* flush */
492 R300_FIREVERTICES(rmesa);
493 /* layout memory space, once for all faces */
494 r300SetTexImages(rmesa, tObj);
495 }
496
497 /* upload (per face) */
498 for (face = 0; face < 6; face++) {
499 if (t->base.dirty_images[face]) {
500 r300UploadTexImages(rmesa,
501 (r300TexObjPtr) tObj->DriverData,
502 face);
503 }
504 }
505
506 if (!t->base.memBlock) {
507 /* texmem alloc failed, use s/w fallback */
508 return GL_FALSE;
509 }
510
511 return GL_TRUE;
512 }
513
514 static GLboolean r300EnableTextureRect(GLcontext * ctx, int unit)
515 {
516 r300ContextPtr rmesa = R300_CONTEXT(ctx);
517 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
518 struct gl_texture_object *tObj = texUnit->_Current;
519 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
520
521 ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);
522
523 if (t->base.dirty_images[0]) {
524 R300_FIREVERTICES(rmesa);
525
526 r300SetTexImages(rmesa, tObj);
527 r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
528 if (!t->base.memBlock && !t->image_override &&
529 !rmesa->prefer_gart_client_texturing)
530 return GL_FALSE;
531 }
532
533 return GL_TRUE;
534 }
535
536 static GLboolean r300UpdateTexture(GLcontext * ctx, int unit)
537 {
538 r300ContextPtr rmesa = R300_CONTEXT(ctx);
539 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
540 struct gl_texture_object *tObj = texUnit->_Current;
541 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
542
543 /* Fallback if there's a texture border */
544 if (tObj->Image[0][tObj->BaseLevel]->Border > 0)
545 return GL_FALSE;
546
547 /* Update state if this is a different texture object to last
548 * time.
549 */
550 if (rmesa->state.texture.unit[unit].texobj != t) {
551 if (rmesa->state.texture.unit[unit].texobj != NULL) {
552 /* The old texture is no longer bound to this texture unit.
553 * Mark it as such.
554 */
555
556 rmesa->state.texture.unit[unit].texobj->base.bound &=
557 ~(1 << unit);
558 }
559
560 rmesa->state.texture.unit[unit].texobj = t;
561 t->base.bound |= (1 << unit);
562 t->dirty_state |= 1 << unit;
563 driUpdateTextureLRU((driTextureObject *) t); /* XXX: should be locked! */
564 }
565
566 return !t->border_fallback;
567 }
568
569 void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
570 unsigned long long offset, GLint depth, GLuint pitch)
571 {
572 r300ContextPtr rmesa = pDRICtx->driverPrivate;
573 struct gl_texture_object *tObj =
574 _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
575 r300TexObjPtr t;
576
577 if (!tObj)
578 return;
579
580 t = (r300TexObjPtr) tObj->DriverData;
581
582 t->image_override = GL_TRUE;
583
584 if (!offset)
585 return;
586
587 t->offset = offset;
588 t->pitch_reg = pitch;
589
590 switch (depth) {
591 case 32:
592 t->format = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
593 t->filter |= tx_table[2].filter;
594 t->pitch_reg /= 4;
595 break;
596 case 24:
597 default:
598 t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
599 t->filter |= tx_table[4].filter;
600 t->pitch_reg /= 4;
601 break;
602 case 16:
603 t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
604 t->filter |= tx_table[5].filter;
605 t->pitch_reg /= 2;
606 break;
607 }
608
609 t->pitch_reg--;
610 }
611
612 static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit)
613 {
614 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
615
616 if (texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT)) {
617 return (r300EnableTextureRect(ctx, unit) &&
618 r300UpdateTexture(ctx, unit));
619 } else if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) {
620 return (r300EnableTexture2D(ctx, unit) &&
621 r300UpdateTexture(ctx, unit));
622 } else if (texUnit->_ReallyEnabled & (TEXTURE_3D_BIT)) {
623 return (r300EnableTexture3D(ctx, unit) &&
624 r300UpdateTexture(ctx, unit));
625 } else if (texUnit->_ReallyEnabled & (TEXTURE_CUBE_BIT)) {
626 return (r300EnableTextureCube(ctx, unit) &&
627 r300UpdateTexture(ctx, unit));
628 } else if (texUnit->_ReallyEnabled) {
629 return GL_FALSE;
630 } else {
631 return GL_TRUE;
632 }
633 }
634
635 void r300UpdateTextureState(GLcontext * ctx)
636 {
637 int i;
638
639 for (i = 0; i < 8; i++) {
640 if (!r300UpdateTextureUnit(ctx, i)) {
641 _mesa_warning(ctx,
642 "failed to update texture state for unit %d.\n",
643 i);
644 }
645 }
646 }