1 /* $XFree86: xc/lib/GL/mesa/src/drv/r300/r300_texstate.c,v 1.3 2003/02/15 22:18:47 dawes Exp $ */
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
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.
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:
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.
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.
29 **************************************************************************/
33 * Keith Whitwell <keith@tungstengraphics.com>
40 #include "texformat.h"
43 #include "r300_context.h"
44 #include "r300_state.h"
45 #include "r300_ioctl.h"
46 #include "radeon_ioctl.h"
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 )
56 #define _ASSIGN(entry, format) \
57 [ MESA_FORMAT_ ## entry ] = { format, 0, 1}
60 GLuint format
, filter
, flag
;
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
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
)),
109 static const struct {
110 GLuint format
, filter
, flag
;
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
)),
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
160 * \param rmesa Context pointer
161 * \param tObj GL texture object whose images are to be posted to
164 static void r300SetTexImages(r300ContextPtr rmesa
,
165 struct gl_texture_object
*tObj
)
167 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
168 const struct gl_texture_image
*baseImage
=
169 tObj
->Image
[0][tObj
->BaseLevel
];
170 GLint curOffset
, blitWidth
;
173 GLint log2Width
, log2Height
, log2Depth
;
176 /* Set the hardware texture format
178 if (VALID_FORMAT(baseImage
->TexFormat
->MesaFormat
)) {
179 if (_mesa_little_endian()) {
181 tx_table_le
[baseImage
->TexFormat
->MesaFormat
].format
;
183 tx_table_le
[baseImage
->TexFormat
->MesaFormat
].filter
;
186 tx_table_be
[baseImage
->TexFormat
->MesaFormat
].format
;
188 tx_table_be
[baseImage
->TexFormat
->MesaFormat
].filter
;
191 _mesa_problem(NULL
, "unexpected texture format in %s",
196 texelBytes
= baseImage
->TexFormat
->TexelBytes
;
198 /* Compute which mipmap levels we really want to send to the hardware.
200 driCalculateTextureFirstLastLevel((driTextureObject
*) t
);
201 log2Width
= tObj
->Image
[0][t
->base
.firstLevel
]->WidthLog2
;
202 log2Height
= tObj
->Image
[0][t
->base
.firstLevel
]->HeightLog2
;
203 log2Depth
= tObj
->Image
[0][t
->base
.firstLevel
]->DepthLog2
;
205 numLevels
= t
->base
.lastLevel
- t
->base
.firstLevel
+ 1;
207 assert(numLevels
<= RADEON_MAX_TEXTURE_LEVELS
);
209 /* Calculate mipmap offsets and dimensions for blitting (uploading)
210 * The idea is that we lay out the mipmap levels within a block of
211 * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
214 blitWidth
= R300_BLIT_WIDTH_BYTES
;
217 /* figure out if this texture is suitable for tiling. */
218 #if 0 /* Disabled for now */
220 if (rmesa
->texmicrotile
&& (tObj
->Target
!= GL_TEXTURE_RECTANGLE_NV
) &&
221 /* texrect might be able to use micro tiling too in theory? */
222 (baseImage
->Height
> 1)) {
224 /* allow 32 (bytes) x 1 mip (which will use two times the space
225 the non-tiled version would use) max if base texture is large enough */
226 if ((numLevels
== 1) ||
227 (((baseImage
->Width
* texelBytes
/ baseImage
->Height
) <= 32) &&
228 (baseImage
->Width
* texelBytes
> 64)) ||
229 ((baseImage
->Width
* texelBytes
/ baseImage
->Height
) <= 16)) {
230 t
->tile_bits
|= R300_TXO_MICRO_TILE
;
234 if (tObj
->Target
!= GL_TEXTURE_RECTANGLE_NV
) {
235 /* we can set macro tiling even for small textures, they will be untiled anyway */
236 t
->tile_bits
|= R300_TXO_MACRO_TILE
;
241 for (i
= 0; i
< numLevels
; i
++) {
242 const struct gl_texture_image
*texImage
;
245 texImage
= tObj
->Image
[0][i
+ t
->base
.firstLevel
];
249 /* find image size in bytes */
250 if (texImage
->IsCompressed
) {
251 if ((t
->format
& R300_TX_FORMAT_DXT1
) == R300_TX_FORMAT_DXT1
) {
252 // fprintf(stderr,"DXT 1 %d %08X\n", texImage->Width, t->format);
253 if ((texImage
->Width
+ 3) < 8) /* width one block */
254 size
= texImage
->CompressedSize
* 4;
255 else if ((texImage
->Width
+ 3) < 16)
256 size
= texImage
->CompressedSize
* 2;
257 else size
= texImage
->CompressedSize
;
259 else /* DXT3/5, 16 bytes per block */
261 WARN_ONCE("DXT 3/5 suffers from multitexturing problems!\n");
262 // fprintf(stderr,"DXT 3/5 %d\n", texImage->Width);
263 if ((texImage
->Width
+ 3) < 8)
264 size
= texImage
->CompressedSize
* 2;
265 else size
= texImage
->CompressedSize
;
268 } else if (tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
) {
269 size
= ((texImage
->Width
* texelBytes
+ 63) & ~63) * texImage
->Height
;
270 blitWidth
= 64 / texelBytes
;
271 } else if (t
->tile_bits
& R300_TXO_MICRO_TILE
) {
272 /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
273 though the actual offset may be different (if texture is less than
274 32 bytes width) to the untiled case */
275 int w
= (texImage
->Width
* texelBytes
* 2 + 31) & ~31;
276 size
= (w
* ((texImage
->Height
+ 1) / 2)) * texImage
->Depth
;
277 blitWidth
= MAX2(texImage
->Width
, 64 / texelBytes
);
279 int w
= (texImage
->Width
* texelBytes
+ 31) & ~31;
280 size
= w
* texImage
->Height
* texImage
->Depth
;
281 blitWidth
= MAX2(texImage
->Width
, 64 / texelBytes
);
286 fprintf(stderr
, "w=%d h=%d d=%d tb=%d intFormat=%d\n", texImage
->Width
, texImage
->Height
,
287 texImage
->Depth
, texImage
->TexFormat
->TexelBytes
,
288 texImage
->InternalFormat
);
290 /* Align to 32-byte offset. It is faster to do this unconditionally
291 * (no branch penalty).
294 curOffset
= (curOffset
+ 0x1f) & ~0x1f;
297 t
->image
[0][i
].x
= curOffset
; /* fix x and y coords up later together with offset */
298 t
->image
[0][i
].y
= 0;
299 t
->image
[0][i
].width
= MIN2(size
/ texelBytes
, blitWidth
);
300 t
->image
[0][i
].height
= (size
/ texelBytes
) / t
->image
[0][i
].width
;
302 t
->image
[0][i
].x
= curOffset
% R300_BLIT_WIDTH_BYTES
;
303 t
->image
[0][i
].y
= curOffset
/ R300_BLIT_WIDTH_BYTES
;
304 t
->image
[0][i
].width
= MIN2(size
, R300_BLIT_WIDTH_BYTES
);
305 t
->image
[0][i
].height
= size
/ t
->image
[0][i
].width
;
308 /* for debugging only and only applicable to non-rectangle targets */
309 assert(size
% t
->image
[0][i
].width
== 0);
310 assert(t
->image
[0][i
].x
== 0
311 || (size
< R300_BLIT_WIDTH_BYTES
312 && t
->image
[0][i
].height
== 1));
317 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
318 i
, texImage
->Width
, texImage
->Height
,
319 t
->image
[0][i
].x
, t
->image
[0][i
].y
,
320 t
->image
[0][i
].width
, t
->image
[0][i
].height
,
327 /* Align the total size of texture memory block.
330 (curOffset
+ RADEON_OFFSET_MASK
) & ~RADEON_OFFSET_MASK
;
332 /* Setup remaining cube face blits, if needed */
333 if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
335 for (face
= 1; face
< 6; face
++) {
336 for (i
= 0; i
< numLevels
; i
++) {
337 t
->image
[face
][i
].x
= t
->image
[0][i
].x
;
338 t
->image
[face
][i
].y
= t
->image
[0][i
].y
;
339 t
->image
[face
][i
].width
= t
->image
[0][i
].width
;
340 t
->image
[face
][i
].height
=
341 t
->image
[0][i
].height
;
344 t
->base
.totalSize
*= 6; /* total texmem needed */
350 t
->format
&= ~(R200_TXFORMAT_WIDTH_MASK
|
351 R200_TXFORMAT_HEIGHT_MASK
|
352 R200_TXFORMAT_CUBIC_MAP_ENABLE
|
353 R200_TXFORMAT_F5_WIDTH_MASK
|
354 R200_TXFORMAT_F5_HEIGHT_MASK
);
355 t
->format
|= ((log2Width
<< R200_TXFORMAT_WIDTH_SHIFT
) |
356 (log2Height
<< R200_TXFORMAT_HEIGHT_SHIFT
));
359 t
->format_x
&= ~(R200_DEPTH_LOG2_MASK
| R200_TEXCOORD_MASK
);
360 if (tObj
->Target
== GL_TEXTURE_3D
) {
361 t
->format_x
|= (log2Depth
<< R200_DEPTH_LOG2_SHIFT
);
362 t
->format_x
|= R200_TEXCOORD_VOLUME
;
363 } else if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
364 ASSERT(log2Width
== log2Height
);
365 t
->format
|= R300_TX_FORMAT_CUBIC_MAP
;
367 t
->format_x
|= R200_TEXCOORD_CUBIC_ENV
;
368 t
->pp_cubic_faces
= ((log2Width
<< R200_FACE_WIDTH_1_SHIFT
) |
369 (log2Height
<< R200_FACE_HEIGHT_1_SHIFT
) |
370 (log2Width
<< R200_FACE_WIDTH_2_SHIFT
) |
371 (log2Height
<< R200_FACE_HEIGHT_2_SHIFT
) |
372 (log2Width
<< R200_FACE_WIDTH_3_SHIFT
) |
373 (log2Height
<< R200_FACE_HEIGHT_3_SHIFT
) |
374 (log2Width
<< R200_FACE_WIDTH_4_SHIFT
) |
375 (log2Height
<< R200_FACE_HEIGHT_4_SHIFT
));
378 if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
379 ASSERT(log2Width
== log2Height
);
380 t
->format
|= R300_TX_FORMAT_CUBIC_MAP
;
383 t
->size
= (((tObj
->Image
[0][t
->base
.firstLevel
]->Width
- 1) << R300_TX_WIDTHMASK_SHIFT
)
384 |((tObj
->Image
[0][t
->base
.firstLevel
]->Height
- 1) << R300_TX_HEIGHTMASK_SHIFT
))
385 |((numLevels
- 1) << R300_TX_MAX_MIP_LEVEL_SHIFT
);
387 /* Only need to round to nearest 32 for textures, but the blitter
388 * requires 64-byte aligned pitches, and we may/may not need the
389 * blitter. NPOT only!
391 if (baseImage
->IsCompressed
) {
393 (tObj
->Image
[0][t
->base
.firstLevel
]->Width
+ 63) & ~(63);
395 else if (tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
) {
396 unsigned int align
= blitWidth
- 1;
397 t
->pitch
= ((tObj
->Image
[0][t
->base
.firstLevel
]->Width
*
398 texelBytes
) + 63) & ~(63);
399 t
->size
|= R300_TX_SIZE_TXPITCH_EN
;
400 t
->pitch_reg
= (((tObj
->Image
[0][t
->base
.firstLevel
]->Width
) + align
) & ~align
) - 1;
404 ((tObj
->Image
[0][t
->base
.firstLevel
]->Width
*
405 texelBytes
) + 63) & ~(63);
408 t
->dirty_state
= TEX_ALL
;
410 /* FYI: r300UploadTexImages( rmesa, t ) used to be called here */
414 /* ================================================================
415 * Texture unit state management
418 static GLboolean
enable_tex_2d(GLcontext
* ctx
, int unit
)
420 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
421 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
422 struct gl_texture_object
*tObj
= texUnit
->_Current
;
423 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
425 ASSERT(tObj
->Target
== GL_TEXTURE_2D
|| tObj
->Target
== GL_TEXTURE_1D
);
427 if (t
->base
.dirty_images
[0]) {
428 R300_FIREVERTICES(rmesa
);
429 r300SetTexImages(rmesa
, tObj
);
430 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
431 if (!t
->base
.memBlock
)
438 #if ENABLE_HW_3D_TEXTURE
439 static GLboolean
enable_tex_3d(GLcontext
* ctx
, int unit
)
441 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
442 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
443 struct gl_texture_object
*tObj
= texUnit
->_Current
;
444 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
446 /* Need to load the 3d images associated with this unit.
449 if (t
->format
& R200_TXFORMAT_NON_POWER2
) {
450 t
->format
&= ~R200_TXFORMAT_NON_POWER2
;
451 t
->base
.dirty_images
[0] = ~0;
454 ASSERT(tObj
->Target
== GL_TEXTURE_3D
);
456 /* R100 & R200 do not support mipmaps for 3D textures.
458 if ((tObj
->MinFilter
!= GL_NEAREST
) && (tObj
->MinFilter
!= GL_LINEAR
)) {
462 if (t
->base
.dirty_images
[0]) {
463 R300_FIREVERTICES(rmesa
);
464 r300SetTexImages(rmesa
, tObj
);
465 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
466 if (!t
->base
.memBlock
)
474 static GLboolean
enable_tex_cube(GLcontext
* ctx
, int unit
)
476 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
477 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
478 struct gl_texture_object
*tObj
= texUnit
->_Current
;
479 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
482 /* Need to load the 2d images associated with this unit.
485 if (t
->format
& R200_TXFORMAT_NON_POWER2
) {
486 t
->format
&= ~R200_TXFORMAT_NON_POWER2
;
487 for (face
= 0; face
< 6; face
++)
488 t
->base
.dirty_images
[face
] = ~0;
491 ASSERT(tObj
->Target
== GL_TEXTURE_CUBE_MAP
);
493 if (t
->base
.dirty_images
[0] || t
->base
.dirty_images
[1] ||
494 t
->base
.dirty_images
[2] || t
->base
.dirty_images
[3] ||
495 t
->base
.dirty_images
[4] || t
->base
.dirty_images
[5]) {
497 R300_FIREVERTICES(rmesa
);
498 /* layout memory space, once for all faces */
499 r300SetTexImages(rmesa
, tObj
);
502 /* upload (per face) */
503 for (face
= 0; face
< 6; face
++) {
504 if (t
->base
.dirty_images
[face
]) {
505 r300UploadTexImages(rmesa
,
506 (r300TexObjPtr
) tObj
->DriverData
,
511 if (!t
->base
.memBlock
) {
512 /* texmem alloc failed, use s/w fallback */
519 static GLboolean
enable_tex_rect(GLcontext
* ctx
, int unit
)
521 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
522 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
523 struct gl_texture_object
*tObj
= texUnit
->_Current
;
524 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
526 ASSERT(tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
);
528 if (t
->base
.dirty_images
[0]) {
529 R300_FIREVERTICES(rmesa
);
530 r300SetTexImages(rmesa
, tObj
);
531 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
532 if (!t
->base
.memBlock
&& !rmesa
->prefer_gart_client_texturing
)
539 static GLboolean
update_tex_common(GLcontext
* ctx
, int unit
)
541 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
542 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
543 struct gl_texture_object
*tObj
= texUnit
->_Current
;
544 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
546 /* Fallback if there's a texture border */
547 if (tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0)
550 /* Update state if this is a different texture object to last
553 if (rmesa
->state
.texture
.unit
[unit
].texobj
!= t
) {
554 if (rmesa
->state
.texture
.unit
[unit
].texobj
!= NULL
) {
555 /* The old texture is no longer bound to this texture unit.
559 rmesa
->state
.texture
.unit
[unit
].texobj
->base
.bound
&=
563 rmesa
->state
.texture
.unit
[unit
].texobj
= t
;
564 t
->base
.bound
|= (1UL << unit
);
565 t
->dirty_state
|= 1 << unit
;
566 driUpdateTextureLRU((driTextureObject
*) t
); /* XXX: should be locked! */
569 return !t
->border_fallback
;
572 static GLboolean
r300UpdateTextureUnit(GLcontext
* ctx
, int unit
)
574 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
576 if (texUnit
->_ReallyEnabled
& (TEXTURE_RECT_BIT
)) {
577 return (enable_tex_rect(ctx
, unit
) &&
578 update_tex_common(ctx
, unit
));
579 } else if (texUnit
->_ReallyEnabled
& (TEXTURE_1D_BIT
| TEXTURE_2D_BIT
)) {
580 return (enable_tex_2d(ctx
, unit
) &&
581 update_tex_common(ctx
, unit
));
583 #if ENABLE_HW_3D_TEXTURE
584 else if (texUnit
->_ReallyEnabled
& (TEXTURE_3D_BIT
)) {
585 return (enable_tex_3d(ctx
, unit
) &&
586 update_tex_common(ctx
, unit
));
589 else if (texUnit
->_ReallyEnabled
& (TEXTURE_CUBE_BIT
)) {
590 return (enable_tex_cube(ctx
, unit
) &&
591 update_tex_common(ctx
, unit
));
592 } else if (texUnit
->_ReallyEnabled
) {
599 void r300UpdateTextureState(GLcontext
* ctx
)
603 ok
= (r300UpdateTextureUnit(ctx
, 0) &&
604 r300UpdateTextureUnit(ctx
, 1) &&
605 r300UpdateTextureUnit(ctx
, 2) &&
606 r300UpdateTextureUnit(ctx
, 3) &&
607 r300UpdateTextureUnit(ctx
, 4) &&
608 r300UpdateTextureUnit(ctx
, 5) &&
609 r300UpdateTextureUnit(ctx
, 6) &&
610 r300UpdateTextureUnit(ctx
, 7)