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
;
175 /* Set the hardware texture format
177 if (VALID_FORMAT(baseImage
->TexFormat
->MesaFormat
)) {
178 if (_mesa_little_endian()) {
180 tx_table_le
[baseImage
->TexFormat
->MesaFormat
].format
;
182 tx_table_le
[baseImage
->TexFormat
->MesaFormat
].filter
;
185 tx_table_be
[baseImage
->TexFormat
->MesaFormat
].format
;
187 tx_table_be
[baseImage
->TexFormat
->MesaFormat
].filter
;
190 _mesa_problem(NULL
, "unexpected texture format in %s",
195 texelBytes
= baseImage
->TexFormat
->TexelBytes
;
197 /* Compute which mipmap levels we really want to send to the hardware.
199 driCalculateTextureFirstLastLevel((driTextureObject
*) t
);
200 log2Width
= tObj
->Image
[0][t
->base
.firstLevel
]->WidthLog2
;
201 log2Height
= tObj
->Image
[0][t
->base
.firstLevel
]->HeightLog2
;
202 log2Depth
= tObj
->Image
[0][t
->base
.firstLevel
]->DepthLog2
;
204 numLevels
= t
->base
.lastLevel
- t
->base
.firstLevel
+ 1;
206 assert(numLevels
<= RADEON_MAX_TEXTURE_LEVELS
);
208 /* Calculate mipmap offsets and dimensions for blitting (uploading)
209 * The idea is that we lay out the mipmap levels within a block of
210 * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
213 blitWidth
= R300_BLIT_WIDTH_BYTES
;
216 /* figure out if this texture is suitable for tiling. */
217 #if 0 /* Disabled for now */
219 if (rmesa
->texmicrotile
&& (tObj
->Target
!= GL_TEXTURE_RECTANGLE_NV
) &&
220 /* texrect might be able to use micro tiling too in theory? */
221 (baseImage
->Height
> 1)) {
223 /* allow 32 (bytes) x 1 mip (which will use two times the space
224 the non-tiled version would use) max if base texture is large enough */
225 if ((numLevels
== 1) ||
226 (((baseImage
->Width
* texelBytes
/ baseImage
->Height
) <= 32) &&
227 (baseImage
->Width
* texelBytes
> 64)) ||
228 ((baseImage
->Width
* texelBytes
/ baseImage
->Height
) <= 16)) {
229 t
->tile_bits
|= R300_TXO_MICRO_TILE
;
233 if (tObj
->Target
!= GL_TEXTURE_RECTANGLE_NV
) {
234 /* we can set macro tiling even for small textures, they will be untiled anyway */
235 t
->tile_bits
|= R300_TXO_MACRO_TILE
;
240 for (i
= 0; i
< numLevels
; i
++) {
241 const struct gl_texture_image
*texImage
;
244 texImage
= tObj
->Image
[0][i
+ t
->base
.firstLevel
];
248 /* find image size in bytes */
249 if (texImage
->IsCompressed
) {
250 if ((t
->format
& R300_TX_FORMAT_DXT1
) == R300_TX_FORMAT_DXT1
) {
251 // fprintf(stderr,"DXT 1 %d %08X\n", texImage->Width, t->format);
252 if ((texImage
->Width
+ 3) < 8) /* width one block */
253 size
= texImage
->CompressedSize
* 4;
254 else if ((texImage
->Width
+ 3) < 16)
255 size
= texImage
->CompressedSize
* 2;
256 else size
= texImage
->CompressedSize
;
258 else /* DXT3/5, 16 bytes per block */
260 WARN_ONCE("DXT 3/5 suffers from multitexturing problems!\n");
261 // fprintf(stderr,"DXT 3/5 %d\n", texImage->Width);
262 if ((texImage
->Width
+ 3) < 8)
263 size
= texImage
->CompressedSize
* 2;
264 else size
= texImage
->CompressedSize
;
267 } else if (tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
) {
268 size
= ((texImage
->Width
* texelBytes
+ 63) & ~63) * texImage
->Height
;
269 blitWidth
= 64 / texelBytes
;
270 } else if (t
->tile_bits
& R300_TXO_MICRO_TILE
) {
271 /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
272 though the actual offset may be different (if texture is less than
273 32 bytes width) to the untiled case */
274 int w
= (texImage
->Width
* texelBytes
* 2 + 31) & ~31;
275 size
= (w
* ((texImage
->Height
+ 1) / 2)) * texImage
->Depth
;
276 blitWidth
= MAX2(texImage
->Width
, 64 / texelBytes
);
278 int w
= (texImage
->Width
* texelBytes
+ 31) & ~31;
279 size
= w
* texImage
->Height
* texImage
->Depth
;
280 blitWidth
= MAX2(texImage
->Width
, 64 / texelBytes
);
285 fprintf(stderr
, "w=%d h=%d d=%d tb=%d intFormat=%d\n", texImage
->Width
, texImage
->Height
,
286 texImage
->Depth
, texImage
->TexFormat
->TexelBytes
,
287 texImage
->InternalFormat
);
289 /* Align to 32-byte offset. It is faster to do this unconditionally
290 * (no branch penalty).
293 curOffset
= (curOffset
+ 0x1f) & ~0x1f;
296 t
->image
[0][i
].x
= curOffset
; /* fix x and y coords up later together with offset */
297 t
->image
[0][i
].y
= 0;
298 t
->image
[0][i
].width
= MIN2(size
/ texelBytes
, blitWidth
);
299 t
->image
[0][i
].height
= (size
/ texelBytes
) / t
->image
[0][i
].width
;
301 t
->image
[0][i
].x
= curOffset
% R300_BLIT_WIDTH_BYTES
;
302 t
->image
[0][i
].y
= curOffset
/ R300_BLIT_WIDTH_BYTES
;
303 t
->image
[0][i
].width
= MIN2(size
, R300_BLIT_WIDTH_BYTES
);
304 t
->image
[0][i
].height
= size
/ t
->image
[0][i
].width
;
307 /* for debugging only and only applicable to non-rectangle targets */
308 assert(size
% t
->image
[0][i
].width
== 0);
309 assert(t
->image
[0][i
].x
== 0
310 || (size
< R300_BLIT_WIDTH_BYTES
311 && t
->image
[0][i
].height
== 1));
316 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
317 i
, texImage
->Width
, texImage
->Height
,
318 t
->image
[0][i
].x
, t
->image
[0][i
].y
,
319 t
->image
[0][i
].width
, t
->image
[0][i
].height
,
326 /* Align the total size of texture memory block.
329 (curOffset
+ RADEON_OFFSET_MASK
) & ~RADEON_OFFSET_MASK
;
331 /* Setup remaining cube face blits, if needed */
332 if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
334 for (face
= 1; face
< 6; face
++) {
335 for (i
= 0; i
< numLevels
; i
++) {
336 t
->image
[face
][i
].x
= t
->image
[0][i
].x
;
337 t
->image
[face
][i
].y
= t
->image
[0][i
].y
;
338 t
->image
[face
][i
].width
= t
->image
[0][i
].width
;
339 t
->image
[face
][i
].height
=
340 t
->image
[0][i
].height
;
343 t
->base
.totalSize
*= 6; /* total texmem needed */
349 t
->format
&= ~(R200_TXFORMAT_WIDTH_MASK
|
350 R200_TXFORMAT_HEIGHT_MASK
|
351 R200_TXFORMAT_CUBIC_MAP_ENABLE
|
352 R200_TXFORMAT_F5_WIDTH_MASK
|
353 R200_TXFORMAT_F5_HEIGHT_MASK
);
354 t
->format
|= ((log2Width
<< R200_TXFORMAT_WIDTH_SHIFT
) |
355 (log2Height
<< R200_TXFORMAT_HEIGHT_SHIFT
));
358 t
->format_x
&= ~(R200_DEPTH_LOG2_MASK
| R200_TEXCOORD_MASK
);
359 if (tObj
->Target
== GL_TEXTURE_3D
) {
360 t
->format_x
|= (log2Depth
<< R200_DEPTH_LOG2_SHIFT
);
361 t
->format_x
|= R200_TEXCOORD_VOLUME
;
362 } else if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
363 ASSERT(log2Width
== log2Height
);
364 t
->format
|= R300_TX_FORMAT_CUBIC_MAP
;
366 t
->format_x
|= R200_TEXCOORD_CUBIC_ENV
;
367 t
->pp_cubic_faces
= ((log2Width
<< R200_FACE_WIDTH_1_SHIFT
) |
368 (log2Height
<< R200_FACE_HEIGHT_1_SHIFT
) |
369 (log2Width
<< R200_FACE_WIDTH_2_SHIFT
) |
370 (log2Height
<< R200_FACE_HEIGHT_2_SHIFT
) |
371 (log2Width
<< R200_FACE_WIDTH_3_SHIFT
) |
372 (log2Height
<< R200_FACE_HEIGHT_3_SHIFT
) |
373 (log2Width
<< R200_FACE_WIDTH_4_SHIFT
) |
374 (log2Height
<< R200_FACE_HEIGHT_4_SHIFT
));
377 if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
378 ASSERT(log2Width
== log2Height
);
379 t
->format
|= R300_TX_FORMAT_CUBIC_MAP
;
382 t
->size
= (((tObj
->Image
[0][t
->base
.firstLevel
]->Width
- 1) << R300_TX_WIDTHMASK_SHIFT
)
383 |((tObj
->Image
[0][t
->base
.firstLevel
]->Height
- 1) << R300_TX_HEIGHTMASK_SHIFT
))
384 |((numLevels
- 1) << R300_TX_MAX_MIP_LEVEL_SHIFT
);
386 /* Only need to round to nearest 32 for textures, but the blitter
387 * requires 64-byte aligned pitches, and we may/may not need the
388 * blitter. NPOT only!
390 if (baseImage
->IsCompressed
) {
392 (tObj
->Image
[0][t
->base
.firstLevel
]->Width
+ 63) & ~(63);
394 else if (tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
) {
395 unsigned int align
= blitWidth
- 1;
396 t
->pitch
= ((tObj
->Image
[0][t
->base
.firstLevel
]->Width
*
397 texelBytes
) + 63) & ~(63);
398 t
->size
|= R300_TX_SIZE_TXPITCH_EN
;
399 t
->pitch_reg
= (((tObj
->Image
[0][t
->base
.firstLevel
]->Width
) + align
) & ~align
) - 1;
403 ((tObj
->Image
[0][t
->base
.firstLevel
]->Width
*
404 texelBytes
) + 63) & ~(63);
407 t
->dirty_state
= TEX_ALL
;
409 /* FYI: r300UploadTexImages( rmesa, t ) used to be called here */
413 /* ================================================================
414 * Texture unit state management
417 static GLboolean
enable_tex_2d(GLcontext
* ctx
, int unit
)
419 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
420 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
421 struct gl_texture_object
*tObj
= texUnit
->_Current
;
422 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
424 ASSERT(tObj
->Target
== GL_TEXTURE_2D
|| tObj
->Target
== GL_TEXTURE_1D
);
426 if (t
->base
.dirty_images
[0]) {
427 R300_FIREVERTICES(rmesa
);
428 r300SetTexImages(rmesa
, tObj
);
429 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
430 if (!t
->base
.memBlock
)
437 #if ENABLE_HW_3D_TEXTURE
438 static GLboolean
enable_tex_3d(GLcontext
* ctx
, int unit
)
440 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
441 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
442 struct gl_texture_object
*tObj
= texUnit
->_Current
;
443 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
445 /* Need to load the 3d images associated with this unit.
448 if (t
->format
& R200_TXFORMAT_NON_POWER2
) {
449 t
->format
&= ~R200_TXFORMAT_NON_POWER2
;
450 t
->base
.dirty_images
[0] = ~0;
453 ASSERT(tObj
->Target
== GL_TEXTURE_3D
);
455 /* R100 & R200 do not support mipmaps for 3D textures.
457 if ((tObj
->MinFilter
!= GL_NEAREST
) && (tObj
->MinFilter
!= GL_LINEAR
)) {
461 if (t
->base
.dirty_images
[0]) {
462 R300_FIREVERTICES(rmesa
);
463 r300SetTexImages(rmesa
, tObj
);
464 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
465 if (!t
->base
.memBlock
)
473 static GLboolean
enable_tex_cube(GLcontext
* ctx
, int unit
)
475 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
476 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
477 struct gl_texture_object
*tObj
= texUnit
->_Current
;
478 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
481 /* Need to load the 2d images associated with this unit.
484 if (t
->format
& R200_TXFORMAT_NON_POWER2
) {
485 t
->format
&= ~R200_TXFORMAT_NON_POWER2
;
486 for (face
= 0; face
< 6; face
++)
487 t
->base
.dirty_images
[face
] = ~0;
490 ASSERT(tObj
->Target
== GL_TEXTURE_CUBE_MAP
);
492 if (t
->base
.dirty_images
[0] || t
->base
.dirty_images
[1] ||
493 t
->base
.dirty_images
[2] || t
->base
.dirty_images
[3] ||
494 t
->base
.dirty_images
[4] || t
->base
.dirty_images
[5]) {
496 R300_FIREVERTICES(rmesa
);
497 /* layout memory space, once for all faces */
498 r300SetTexImages(rmesa
, tObj
);
501 /* upload (per face) */
502 for (face
= 0; face
< 6; face
++) {
503 if (t
->base
.dirty_images
[face
]) {
504 r300UploadTexImages(rmesa
,
505 (r300TexObjPtr
) tObj
->DriverData
,
510 if (!t
->base
.memBlock
) {
511 /* texmem alloc failed, use s/w fallback */
518 static GLboolean
enable_tex_rect(GLcontext
* ctx
, int unit
)
520 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
521 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
522 struct gl_texture_object
*tObj
= texUnit
->_Current
;
523 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
525 ASSERT(tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
);
527 if (t
->base
.dirty_images
[0]) {
528 R300_FIREVERTICES(rmesa
);
529 r300SetTexImages(rmesa
, tObj
);
530 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
531 if (!t
->base
.memBlock
&& !rmesa
->prefer_gart_client_texturing
)
538 static GLboolean
update_tex_common(GLcontext
* ctx
, int unit
)
540 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
541 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
542 struct gl_texture_object
*tObj
= texUnit
->_Current
;
543 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
545 /* Fallback if there's a texture border */
546 if (tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0)
549 /* Update state if this is a different texture object to last
552 if (rmesa
->state
.texture
.unit
[unit
].texobj
!= t
) {
553 if (rmesa
->state
.texture
.unit
[unit
].texobj
!= NULL
) {
554 /* The old texture is no longer bound to this texture unit.
558 rmesa
->state
.texture
.unit
[unit
].texobj
->base
.bound
&=
562 rmesa
->state
.texture
.unit
[unit
].texobj
= t
;
563 t
->base
.bound
|= (1UL << unit
);
564 t
->dirty_state
|= 1 << unit
;
565 driUpdateTextureLRU((driTextureObject
*) t
); /* XXX: should be locked! */
568 return !t
->border_fallback
;
571 static GLboolean
r300UpdateTextureUnit(GLcontext
* ctx
, int unit
)
573 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
575 if (texUnit
->_ReallyEnabled
& (TEXTURE_RECT_BIT
)) {
576 return (enable_tex_rect(ctx
, unit
) &&
577 update_tex_common(ctx
, unit
));
578 } else if (texUnit
->_ReallyEnabled
& (TEXTURE_1D_BIT
| TEXTURE_2D_BIT
)) {
579 return (enable_tex_2d(ctx
, unit
) &&
580 update_tex_common(ctx
, unit
));
582 #if ENABLE_HW_3D_TEXTURE
583 else if (texUnit
->_ReallyEnabled
& (TEXTURE_3D_BIT
)) {
584 return (enable_tex_3d(ctx
, unit
) &&
585 update_tex_common(ctx
, unit
));
588 else if (texUnit
->_ReallyEnabled
& (TEXTURE_CUBE_BIT
)) {
589 return (enable_tex_cube(ctx
, unit
) &&
590 update_tex_common(ctx
, unit
));
591 } else if (texUnit
->_ReallyEnabled
) {
598 void r300UpdateTextureState(GLcontext
* ctx
)
602 ok
= (r300UpdateTextureUnit(ctx
, 0) &&
603 r300UpdateTextureUnit(ctx
, 1) &&
604 r300UpdateTextureUnit(ctx
, 2) &&
605 r300UpdateTextureUnit(ctx
, 3) &&
606 r300UpdateTextureUnit(ctx
, 4) &&
607 r300UpdateTextureUnit(ctx
, 5) &&
608 r300UpdateTextureUnit(ctx
, 6) &&
609 r300UpdateTextureUnit(ctx
, 7)