2 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
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.
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:
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.
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.
28 **************************************************************************/
33 * \author Keith Whitwell <keith@tungstengraphics.com>
35 * \todo Enable R300 texture tiling code?
42 #include "texformat.h"
47 #include "r300_context.h"
48 #include "r300_state.h"
49 #include "r300_ioctl.h"
50 #include "radeon_ioctl.h"
54 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5 \
55 || ((f) >= MESA_FORMAT_RGBA_FLOAT32 && \
56 (f) <= MESA_FORMAT_INTENSITY_FLOAT16)) \
59 #define _ASSIGN(entry, format) \
60 [ MESA_FORMAT_ ## entry ] = { format, 0, 1}
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
71 static const struct tx_table
{
72 GLuint format
, filter
, flag
;
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
)),
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
)),
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
)),
126 void r300SetDepthTexMode(struct gl_texture_object
*tObj
)
128 static const GLuint formats
[3][3] = {
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
),
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
),
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
),
145 const GLuint
*format
;
151 t
= (r300TexObjPtr
) tObj
->DriverData
;
154 switch (tObj
->Image
[0][tObj
->BaseLevel
]->TexFormat
->MesaFormat
) {
155 case MESA_FORMAT_Z16
:
158 case MESA_FORMAT_Z24_S8
:
161 case MESA_FORMAT_Z32
:
165 /* Error...which should have already been caught by higher
172 switch (tObj
->DepthMode
) {
174 t
->format
= format
[0];
177 t
->format
= format
[1];
180 t
->format
= format
[2];
183 /* Error...which should have already been caught by higher
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
199 * \param rmesa Context pointer
200 * \param tObj GL texture object whose images are to be posted to
203 static void r300SetTexImages(r300ContextPtr rmesa
,
204 struct gl_texture_object
*tObj
)
206 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
207 const struct gl_texture_image
*baseImage
=
208 tObj
->Image
[0][tObj
->BaseLevel
];
209 GLint curOffset
, blitWidth
;
212 GLint log2Width
, log2Height
, log2Depth
;
214 /* Set the hardware texture format
216 if (!t
->image_override
217 && VALID_FORMAT(baseImage
->TexFormat
->MesaFormat
)) {
218 if (baseImage
->TexFormat
->BaseFormat
== GL_DEPTH_COMPONENT
) {
219 r300SetDepthTexMode(tObj
);
221 t
->format
= tx_table
[baseImage
->TexFormat
->MesaFormat
].format
;
224 t
->filter
|= tx_table
[baseImage
->TexFormat
->MesaFormat
].filter
;
225 } else if (!t
->image_override
) {
226 _mesa_problem(NULL
, "unexpected texture format in %s",
231 texelBytes
= baseImage
->TexFormat
->TexelBytes
;
233 /* Compute which mipmap levels we really want to send to the hardware.
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
;
240 numLevels
= t
->base
.lastLevel
- t
->base
.firstLevel
+ 1;
242 assert(numLevels
<= RADEON_MAX_TEXTURE_LEVELS
);
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.
249 blitWidth
= R300_BLIT_WIDTH_BYTES
;
252 /* figure out if this texture is suitable for tiling. */
253 #if 0 /* Disabled for now */
255 if ((tObj
->Target
!= GL_TEXTURE_RECTANGLE_NV
) &&
256 /* texrect might be able to use micro tiling too in theory? */
257 (baseImage
->Height
> 1)) {
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))
266 ((baseImage
->Width
* texelBytes
/
267 baseImage
->Height
) <= 16)) {
268 t
->tile_bits
|= R300_TXO_MICRO_TILE
;
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
;
279 for (i
= 0; i
< numLevels
; i
++) {
280 const struct gl_texture_image
*texImage
;
283 texImage
= tObj
->Image
[0][i
+ t
->base
.firstLevel
];
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;
297 size
= texImage
->CompressedSize
;
299 /* DXT3/5, 16 bytes per block */
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;
306 size
= texImage
->CompressedSize
;
308 } else if (tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
) {
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;
319 (w
* ((texImage
->Height
+ 1) / 2)) *
321 blitWidth
= MAX2(texImage
->Width
, 64 / texelBytes
);
323 int w
= (texImage
->Width
* texelBytes
+ 31) & ~31;
324 size
= w
* texImage
->Height
* texImage
->Depth
;
325 blitWidth
= MAX2(texImage
->Width
, 64 / texelBytes
);
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
,
333 texImage
->TexFormat
->TexelBytes
,
334 texImage
->InternalFormat
);
336 /* Align to 32-byte offset. It is faster to do this unconditionally
337 * (no branch penalty).
340 curOffset
= (curOffset
+ 0x1f) & ~0x1f;
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
;
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
;
358 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
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
,
369 /* Align the total size of texture memory block.
372 (curOffset
+ RADEON_OFFSET_MASK
) & ~RADEON_OFFSET_MASK
;
374 /* Setup remaining cube face blits, if needed */
375 if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
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
;
386 t
->base
.totalSize
*= 6; /* total texmem needed */
389 if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
390 ASSERT(log2Width
== log2Height
);
391 t
->format
|= R300_TX_FORMAT_CUBIC_MAP
;
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
);
402 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
) {
403 if (tObj
->Image
[0][t
->base
.firstLevel
]->Width
> 2048)
404 t
->pitch
|= R500_TXWIDTH_BIT11
;
405 if (tObj
->Image
[0][t
->base
.firstLevel
]->Height
> 2048)
406 t
->pitch
|= R500_TXHEIGHT_BIT11
;
409 /* Only need to round to nearest 32 for textures, but the blitter
410 * requires 64-byte aligned pitches, and we may/may not need the
411 * blitter. NPOT only!
413 if (baseImage
->IsCompressed
) {
415 (tObj
->Image
[0][t
->base
.firstLevel
]->Width
+ 63) & ~(63);
416 } else if (tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
) {
417 unsigned int align
= blitWidth
- 1;
418 t
->pitch
|= ((tObj
->Image
[0][t
->base
.firstLevel
]->Width
*
419 texelBytes
) + 63) & ~(63);
420 t
->size
|= R300_TX_SIZE_TXPITCH_EN
;
421 if (!t
->image_override
)
423 (((tObj
->Image
[0][t
->base
.firstLevel
]->Width
) +
424 align
) & ~align
) - 1;
427 ((tObj
->Image
[0][t
->base
.firstLevel
]->Width
*
428 texelBytes
) + 63) & ~(63);
431 t
->dirty_state
= TEX_ALL
;
433 /* FYI: r300UploadTexImages( rmesa, t ) used to be called here */
436 /* ================================================================
437 * Texture unit state management
440 static GLboolean
r300EnableTexture2D(GLcontext
* ctx
, int unit
)
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
;
447 ASSERT(tObj
->Target
== GL_TEXTURE_2D
|| tObj
->Target
== GL_TEXTURE_1D
);
449 if (t
->base
.dirty_images
[0]) {
450 R300_FIREVERTICES(rmesa
);
452 r300SetTexImages(rmesa
, tObj
);
453 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
454 if (!t
->base
.memBlock
&& !t
->image_override
)
461 static GLboolean
r300EnableTexture3D(GLcontext
* ctx
, int unit
)
463 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
464 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
465 struct gl_texture_object
*tObj
= texUnit
->_Current
;
466 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
468 ASSERT(tObj
->Target
== GL_TEXTURE_3D
);
470 /* r300 does not support mipmaps for 3D textures. */
471 if ((tObj
->MinFilter
!= GL_NEAREST
) && (tObj
->MinFilter
!= GL_LINEAR
)) {
475 if (t
->base
.dirty_images
[0]) {
476 R300_FIREVERTICES(rmesa
);
477 r300SetTexImages(rmesa
, tObj
);
478 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
479 if (!t
->base
.memBlock
)
486 static GLboolean
r300EnableTextureCube(GLcontext
* ctx
, int unit
)
488 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
489 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
490 struct gl_texture_object
*tObj
= texUnit
->_Current
;
491 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
494 ASSERT(tObj
->Target
== GL_TEXTURE_CUBE_MAP
);
496 if (t
->base
.dirty_images
[0] || t
->base
.dirty_images
[1] ||
497 t
->base
.dirty_images
[2] || t
->base
.dirty_images
[3] ||
498 t
->base
.dirty_images
[4] || t
->base
.dirty_images
[5]) {
500 R300_FIREVERTICES(rmesa
);
501 /* layout memory space, once for all faces */
502 r300SetTexImages(rmesa
, tObj
);
505 /* upload (per face) */
506 for (face
= 0; face
< 6; face
++) {
507 if (t
->base
.dirty_images
[face
]) {
508 r300UploadTexImages(rmesa
,
509 (r300TexObjPtr
) tObj
->DriverData
,
514 if (!t
->base
.memBlock
) {
515 /* texmem alloc failed, use s/w fallback */
522 static GLboolean
r300EnableTextureRect(GLcontext
* ctx
, int unit
)
524 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
525 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
526 struct gl_texture_object
*tObj
= texUnit
->_Current
;
527 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
529 ASSERT(tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
);
531 if (t
->base
.dirty_images
[0]) {
532 R300_FIREVERTICES(rmesa
);
534 r300SetTexImages(rmesa
, tObj
);
535 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
536 if (!t
->base
.memBlock
&& !t
->image_override
&&
537 !rmesa
->prefer_gart_client_texturing
)
544 static GLboolean
r300UpdateTexture(GLcontext
* ctx
, int unit
)
546 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
547 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
548 struct gl_texture_object
*tObj
= texUnit
->_Current
;
549 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
551 /* Fallback if there's a texture border */
552 if (tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0)
555 /* Update state if this is a different texture object to last
558 if (rmesa
->state
.texture
.unit
[unit
].texobj
!= t
) {
559 if (rmesa
->state
.texture
.unit
[unit
].texobj
!= NULL
) {
560 /* The old texture is no longer bound to this texture unit.
564 rmesa
->state
.texture
.unit
[unit
].texobj
->base
.bound
&=
568 rmesa
->state
.texture
.unit
[unit
].texobj
= t
;
569 t
->base
.bound
|= (1 << unit
);
570 t
->dirty_state
|= 1 << unit
;
571 driUpdateTextureLRU((driTextureObject
*) t
); /* XXX: should be locked! */
574 return !t
->border_fallback
;
577 void r300SetTexOffset(__DRIcontext
* pDRICtx
, GLint texname
,
578 unsigned long long offset
, GLint depth
, GLuint pitch
)
580 r300ContextPtr rmesa
= pDRICtx
->driverPrivate
;
581 struct gl_texture_object
*tObj
=
582 _mesa_lookup_texture(rmesa
->radeon
.glCtx
, texname
);
588 t
= (r300TexObjPtr
) tObj
->DriverData
;
590 t
->image_override
= GL_TRUE
;
596 t
->pitch_reg
= pitch
;
600 t
->format
= R300_EASY_TX_FORMAT(X
, Y
, Z
, W
, W8Z8Y8X8
);
601 t
->filter
|= tx_table
[2].filter
;
606 t
->format
= R300_EASY_TX_FORMAT(X
, Y
, Z
, ONE
, W8Z8Y8X8
);
607 t
->filter
|= tx_table
[4].filter
;
611 t
->format
= R300_EASY_TX_FORMAT(X
, Y
, Z
, ONE
, Z5Y6X5
);
612 t
->filter
|= tx_table
[5].filter
;
620 static GLboolean
r300UpdateTextureUnit(GLcontext
* ctx
, int unit
)
622 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
624 if (texUnit
->_ReallyEnabled
& (TEXTURE_RECT_BIT
)) {
625 return (r300EnableTextureRect(ctx
, unit
) &&
626 r300UpdateTexture(ctx
, unit
));
627 } else if (texUnit
->_ReallyEnabled
& (TEXTURE_1D_BIT
| TEXTURE_2D_BIT
)) {
628 return (r300EnableTexture2D(ctx
, unit
) &&
629 r300UpdateTexture(ctx
, unit
));
630 } else if (texUnit
->_ReallyEnabled
& (TEXTURE_3D_BIT
)) {
631 return (r300EnableTexture3D(ctx
, unit
) &&
632 r300UpdateTexture(ctx
, unit
));
633 } else if (texUnit
->_ReallyEnabled
& (TEXTURE_CUBE_BIT
)) {
634 return (r300EnableTextureCube(ctx
, unit
) &&
635 r300UpdateTexture(ctx
, unit
));
636 } else if (texUnit
->_ReallyEnabled
) {
643 void r300UpdateTextureState(GLcontext
* ctx
)
647 for (i
= 0; i
< 8; i
++) {
648 if (!r300UpdateTextureUnit(ctx
, i
)) {
650 "failed to update texture state for unit %d.\n",