Fix r300SetTexOffset for big endian platforms.
[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 /* *INDENT-ON* */
119 };
120
121 #undef _ASSIGN
122
123 /**
124 * This function computes the number of bytes of storage needed for
125 * the given texture object (all mipmap levels, all cube faces).
126 * The \c image[face][level].x/y/width/height parameters for upload/blitting
127 * are computed here. \c filter, \c format, etc. will be set here
128 * too.
129 *
130 * \param rmesa Context pointer
131 * \param tObj GL texture object whose images are to be posted to
132 * hardware state.
133 */
134 static void r300SetTexImages(r300ContextPtr rmesa,
135 struct gl_texture_object *tObj)
136 {
137 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
138 const struct gl_texture_image *baseImage =
139 tObj->Image[0][tObj->BaseLevel];
140 GLint curOffset, blitWidth;
141 GLint i, texelBytes;
142 GLint numLevels;
143 GLint log2Width, log2Height, log2Depth;
144
145 /* Set the hardware texture format
146 */
147 if (!t->image_override
148 && VALID_FORMAT(baseImage->TexFormat->MesaFormat)) {
149 t->format = tx_table[baseImage->TexFormat->MesaFormat].format;
150 t->filter |= tx_table[baseImage->TexFormat->MesaFormat].filter;
151 } else if (!t->image_override) {
152 _mesa_problem(NULL, "unexpected texture format in %s",
153 __FUNCTION__);
154 return;
155 }
156
157 texelBytes = baseImage->TexFormat->TexelBytes;
158
159 /* Compute which mipmap levels we really want to send to the hardware.
160 */
161 driCalculateTextureFirstLastLevel((driTextureObject *) t);
162 log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
163 log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
164 log2Depth = tObj->Image[0][t->base.firstLevel]->DepthLog2;
165
166 numLevels = t->base.lastLevel - t->base.firstLevel + 1;
167
168 assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS);
169
170 /* Calculate mipmap offsets and dimensions for blitting (uploading)
171 * The idea is that we lay out the mipmap levels within a block of
172 * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
173 */
174 curOffset = 0;
175 blitWidth = R300_BLIT_WIDTH_BYTES;
176 t->tile_bits = 0;
177
178 /* figure out if this texture is suitable for tiling. */
179 #if 0 /* Disabled for now */
180 if (texelBytes) {
181 if ((tObj->Target != GL_TEXTURE_RECTANGLE_NV) &&
182 /* texrect might be able to use micro tiling too in theory? */
183 (baseImage->Height > 1)) {
184
185 /* allow 32 (bytes) x 1 mip (which will use two times the space
186 the non-tiled version would use) max if base texture is large enough */
187 if ((numLevels == 1) ||
188 (((baseImage->Width * texelBytes /
189 baseImage->Height) <= 32)
190 && (baseImage->Width * texelBytes > 64))
191 ||
192 ((baseImage->Width * texelBytes /
193 baseImage->Height) <= 16)) {
194 t->tile_bits |= R300_TXO_MICRO_TILE;
195 }
196 }
197
198 if (tObj->Target != GL_TEXTURE_RECTANGLE_NV) {
199 /* we can set macro tiling even for small textures, they will be untiled anyway */
200 t->tile_bits |= R300_TXO_MACRO_TILE;
201 }
202 }
203 #endif
204
205 for (i = 0; i < numLevels; i++) {
206 const struct gl_texture_image *texImage;
207 GLuint size;
208
209 texImage = tObj->Image[0][i + t->base.firstLevel];
210 if (!texImage)
211 break;
212
213 /* find image size in bytes */
214 if (texImage->IsCompressed) {
215 if ((t->format & R300_TX_FORMAT_DXT1) ==
216 R300_TX_FORMAT_DXT1) {
217 // fprintf(stderr,"DXT 1 %d %08X\n", texImage->Width, t->format);
218 if ((texImage->Width + 3) < 8) /* width one block */
219 size = texImage->CompressedSize * 4;
220 else if ((texImage->Width + 3) < 16)
221 size = texImage->CompressedSize * 2;
222 else
223 size = texImage->CompressedSize;
224 } else {
225 /* DXT3/5, 16 bytes per block */
226 WARN_ONCE
227 ("DXT 3/5 suffers from multitexturing problems!\n");
228 // fprintf(stderr,"DXT 3/5 %d\n", texImage->Width);
229 if ((texImage->Width + 3) < 8)
230 size = texImage->CompressedSize * 2;
231 else
232 size = texImage->CompressedSize;
233 }
234 } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
235 size =
236 ((texImage->Width * texelBytes +
237 63) & ~63) * texImage->Height;
238 blitWidth = 64 / texelBytes;
239 } else if (t->tile_bits & R300_TXO_MICRO_TILE) {
240 /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
241 though the actual offset may be different (if texture is less than
242 32 bytes width) to the untiled case */
243 int w = (texImage->Width * texelBytes * 2 + 31) & ~31;
244 size =
245 (w * ((texImage->Height + 1) / 2)) *
246 texImage->Depth;
247 blitWidth = MAX2(texImage->Width, 64 / texelBytes);
248 } else {
249 int w = (texImage->Width * texelBytes + 31) & ~31;
250 size = w * texImage->Height * texImage->Depth;
251 blitWidth = MAX2(texImage->Width, 64 / texelBytes);
252 }
253 assert(size > 0);
254
255 if (RADEON_DEBUG & DEBUG_TEXTURE)
256 fprintf(stderr, "w=%d h=%d d=%d tb=%d intFormat=%d\n",
257 texImage->Width, texImage->Height,
258 texImage->Depth,
259 texImage->TexFormat->TexelBytes,
260 texImage->InternalFormat);
261
262 /* Align to 32-byte offset. It is faster to do this unconditionally
263 * (no branch penalty).
264 */
265
266 curOffset = (curOffset + 0x1f) & ~0x1f;
267
268 if (texelBytes) {
269 /* fix x and y coords up later together with offset */
270 t->image[0][i].x = curOffset;
271 t->image[0][i].y = 0;
272 t->image[0][i].width =
273 MIN2(size / texelBytes, blitWidth);
274 t->image[0][i].height =
275 (size / texelBytes) / t->image[0][i].width;
276 } else {
277 t->image[0][i].x = curOffset % R300_BLIT_WIDTH_BYTES;
278 t->image[0][i].y = curOffset / R300_BLIT_WIDTH_BYTES;
279 t->image[0][i].width =
280 MIN2(size, R300_BLIT_WIDTH_BYTES);
281 t->image[0][i].height = size / t->image[0][i].width;
282 }
283
284 if (RADEON_DEBUG & DEBUG_TEXTURE)
285 fprintf(stderr,
286 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
287 i, texImage->Width, texImage->Height,
288 t->image[0][i].x, t->image[0][i].y,
289 t->image[0][i].width, t->image[0][i].height,
290 size, curOffset);
291
292 curOffset += size;
293 }
294
295 /* Align the total size of texture memory block.
296 */
297 t->base.totalSize =
298 (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
299
300 /* Setup remaining cube face blits, if needed */
301 if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
302 GLuint face;
303 for (face = 1; face < 6; face++) {
304 for (i = 0; i < numLevels; i++) {
305 t->image[face][i].x = t->image[0][i].x;
306 t->image[face][i].y = t->image[0][i].y;
307 t->image[face][i].width = t->image[0][i].width;
308 t->image[face][i].height =
309 t->image[0][i].height;
310 }
311 }
312 t->base.totalSize *= 6; /* total texmem needed */
313 }
314
315 if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
316 ASSERT(log2Width == log2Height);
317 t->format |= R300_TX_FORMAT_CUBIC_MAP;
318 }
319
320 t->size =
321 (((tObj->Image[0][t->base.firstLevel]->Width -
322 1) << R300_TX_WIDTHMASK_SHIFT)
323 | ((tObj->Image[0][t->base.firstLevel]->Height - 1) <<
324 R300_TX_HEIGHTMASK_SHIFT))
325 | ((numLevels - 1) << R300_TX_MAX_MIP_LEVEL_SHIFT);
326
327 /* Only need to round to nearest 32 for textures, but the blitter
328 * requires 64-byte aligned pitches, and we may/may not need the
329 * blitter. NPOT only!
330 */
331 if (baseImage->IsCompressed) {
332 t->pitch =
333 (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63);
334 } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
335 unsigned int align = blitWidth - 1;
336 t->pitch = ((tObj->Image[0][t->base.firstLevel]->Width *
337 texelBytes) + 63) & ~(63);
338 t->size |= R300_TX_SIZE_TXPITCH_EN;
339 if (!t->image_override)
340 t->pitch_reg =
341 (((tObj->Image[0][t->base.firstLevel]->Width) +
342 align) & ~align) - 1;
343 } else {
344 t->pitch =
345 ((tObj->Image[0][t->base.firstLevel]->Width *
346 texelBytes) + 63) & ~(63);
347 }
348
349 t->dirty_state = TEX_ALL;
350
351 /* FYI: r300UploadTexImages( rmesa, t ) used to be called here */
352 }
353
354 /* ================================================================
355 * Texture unit state management
356 */
357
358 static GLboolean r300EnableTexture2D(GLcontext * ctx, int unit)
359 {
360 r300ContextPtr rmesa = R300_CONTEXT(ctx);
361 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
362 struct gl_texture_object *tObj = texUnit->_Current;
363 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
364
365 ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D);
366
367 if (t->base.dirty_images[0]) {
368 R300_FIREVERTICES(rmesa);
369
370 r300SetTexImages(rmesa, tObj);
371 r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
372 if (!t->base.memBlock && !t->image_override)
373 return GL_FALSE;
374 }
375
376 return GL_TRUE;
377 }
378
379 static GLboolean r300EnableTexture3D(GLcontext * ctx, int unit)
380 {
381 r300ContextPtr rmesa = R300_CONTEXT(ctx);
382 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
383 struct gl_texture_object *tObj = texUnit->_Current;
384 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
385
386 ASSERT(tObj->Target == GL_TEXTURE_3D);
387
388 /* r300 does not support mipmaps for 3D textures. */
389 if ((tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) {
390 return GL_FALSE;
391 }
392
393 if (t->base.dirty_images[0]) {
394 R300_FIREVERTICES(rmesa);
395 r300SetTexImages(rmesa, tObj);
396 r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
397 if (!t->base.memBlock)
398 return GL_FALSE;
399 }
400
401 return GL_TRUE;
402 }
403
404 static GLboolean r300EnableTextureCube(GLcontext * ctx, int unit)
405 {
406 r300ContextPtr rmesa = R300_CONTEXT(ctx);
407 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
408 struct gl_texture_object *tObj = texUnit->_Current;
409 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
410 GLuint face;
411
412 ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP);
413
414 if (t->base.dirty_images[0] || t->base.dirty_images[1] ||
415 t->base.dirty_images[2] || t->base.dirty_images[3] ||
416 t->base.dirty_images[4] || t->base.dirty_images[5]) {
417 /* flush */
418 R300_FIREVERTICES(rmesa);
419 /* layout memory space, once for all faces */
420 r300SetTexImages(rmesa, tObj);
421 }
422
423 /* upload (per face) */
424 for (face = 0; face < 6; face++) {
425 if (t->base.dirty_images[face]) {
426 r300UploadTexImages(rmesa,
427 (r300TexObjPtr) tObj->DriverData,
428 face);
429 }
430 }
431
432 if (!t->base.memBlock) {
433 /* texmem alloc failed, use s/w fallback */
434 return GL_FALSE;
435 }
436
437 return GL_TRUE;
438 }
439
440 static GLboolean r300EnableTextureRect(GLcontext * ctx, int unit)
441 {
442 r300ContextPtr rmesa = R300_CONTEXT(ctx);
443 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
444 struct gl_texture_object *tObj = texUnit->_Current;
445 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
446
447 ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);
448
449 if (t->base.dirty_images[0]) {
450 R300_FIREVERTICES(rmesa);
451
452 r300SetTexImages(rmesa, tObj);
453 r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
454 if (!t->base.memBlock && !t->image_override &&
455 !rmesa->prefer_gart_client_texturing)
456 return GL_FALSE;
457 }
458
459 return GL_TRUE;
460 }
461
462 static GLboolean r300UpdateTexture(GLcontext * ctx, int unit)
463 {
464 r300ContextPtr rmesa = R300_CONTEXT(ctx);
465 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
466 struct gl_texture_object *tObj = texUnit->_Current;
467 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
468
469 /* Fallback if there's a texture border */
470 if (tObj->Image[0][tObj->BaseLevel]->Border > 0)
471 return GL_FALSE;
472
473 /* Update state if this is a different texture object to last
474 * time.
475 */
476 if (rmesa->state.texture.unit[unit].texobj != t) {
477 if (rmesa->state.texture.unit[unit].texobj != NULL) {
478 /* The old texture is no longer bound to this texture unit.
479 * Mark it as such.
480 */
481
482 rmesa->state.texture.unit[unit].texobj->base.bound &=
483 ~(1UL << unit);
484 }
485
486 rmesa->state.texture.unit[unit].texobj = t;
487 t->base.bound |= (1UL << unit);
488 t->dirty_state |= 1 << unit;
489 driUpdateTextureLRU((driTextureObject *) t); /* XXX: should be locked! */
490 }
491
492 return !t->border_fallback;
493 }
494
495 void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
496 unsigned long long offset, GLint depth, GLuint pitch)
497 {
498 r300ContextPtr rmesa =
499 (r300ContextPtr) ((__DRIcontextPrivate *) pDRICtx->private)->
500 driverPrivate;
501 struct gl_texture_object *tObj =
502 _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
503 r300TexObjPtr t;
504
505 if (!tObj)
506 return;
507
508 t = (r300TexObjPtr) tObj->DriverData;
509
510 t->image_override = GL_TRUE;
511
512 if (!offset)
513 return;
514
515 t->offset = offset;
516 t->pitch_reg = pitch;
517
518 switch (depth) {
519 case 32:
520 t->format = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
521 t->filter |= tx_table[2].filter;
522 t->pitch_reg /= 4;
523 break;
524 case 24:
525 default:
526 t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
527 t->filter |= tx_table[4].filter;
528 t->pitch_reg /= 4;
529 break;
530 case 16:
531 t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
532 t->filter |= tx_table[5].filter;
533 t->pitch_reg /= 2;
534 break;
535 }
536
537 t->pitch_reg--;
538 }
539
540 static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit)
541 {
542 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
543
544 if (texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT)) {
545 return (r300EnableTextureRect(ctx, unit) &&
546 r300UpdateTexture(ctx, unit));
547 } else if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) {
548 return (r300EnableTexture2D(ctx, unit) &&
549 r300UpdateTexture(ctx, unit));
550 } else if (texUnit->_ReallyEnabled & (TEXTURE_3D_BIT)) {
551 return (r300EnableTexture3D(ctx, unit) &&
552 r300UpdateTexture(ctx, unit));
553 } else if (texUnit->_ReallyEnabled & (TEXTURE_CUBE_BIT)) {
554 return (r300EnableTextureCube(ctx, unit) &&
555 r300UpdateTexture(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 }