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 **************************************************************************/
32 * Keith Whitwell <keith@tungstengraphics.com>
39 #include "texformat.h"
42 #include "r300_context.h"
43 #include "r300_state.h"
44 #include "r300_ioctl.h"
45 #include "radeon_ioctl.h"
50 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5 \
51 || ((f) >= MESA_FORMAT_RGBA_FLOAT32 && \
52 (f) <= MESA_FORMAT_INTENSITY_FLOAT16)) \
53 && tx_table_le[f].flag )
55 #define _ASSIGN(entry, format) \
56 [ MESA_FORMAT_ ## entry ] = { format, 0, 1}
59 GLuint format
, filter
, flag
;
62 * Note that the _REV formats are the same as the non-REV formats.
63 * This is because the REV and non-REV formats are identical as a
64 * byte string, but differ when accessed as 16-bit or 32-bit words
65 * depending on the endianness of the host. Since the textures are
66 * transferred to the R300 as a byte string (i.e. without any
67 * byte-swapping), the R300 sees the REV and non-REV formats
68 * identically. -- paulus
70 _ASSIGN(RGBA8888
, R300_EASY_TX_FORMAT(Z
, Y
, X
, W
, W8Z8Y8X8
)),
71 _ASSIGN(RGBA8888_REV
, R300_EASY_TX_FORMAT(Y
, Z
, W
, X
, W8Z8Y8X8
)),
72 _ASSIGN(ARGB8888
, R300_EASY_TX_FORMAT(W
, Z
, Y
, X
, W8Z8Y8X8
)),
73 _ASSIGN(ARGB8888_REV
, R300_EASY_TX_FORMAT(X
, Y
, Z
, W
, W8Z8Y8X8
)),
74 _ASSIGN(RGB888
, 0xffffffff),
75 _ASSIGN(RGB565
, R300_EASY_TX_FORMAT(X
, Y
, Z
, ONE
, Z5Y6X5
)),
76 _ASSIGN(RGB565_REV
, R300_EASY_TX_FORMAT(X
, Y
, Z
, ONE
, Z5Y6X5
)),
77 _ASSIGN(ARGB4444
, R300_EASY_TX_FORMAT(X
, Y
, Z
, W
, W4Z4Y4X4
)),
78 _ASSIGN(ARGB4444_REV
, R300_EASY_TX_FORMAT(X
, Y
, Z
, W
, W4Z4Y4X4
)),
79 _ASSIGN(ARGB1555
, R300_EASY_TX_FORMAT(X
, Y
, Z
, W
, W1Z5Y5X5
)),
80 _ASSIGN(ARGB1555_REV
, R300_EASY_TX_FORMAT(X
, Y
, Z
, W
, W1Z5Y5X5
)),
81 _ASSIGN(AL88
, R300_EASY_TX_FORMAT(X
, X
, X
, Y
, Y8X8
)),
82 _ASSIGN(AL88_REV
, R300_EASY_TX_FORMAT(X
, X
, X
, Y
, Y8X8
)),
83 _ASSIGN(RGB332
, R300_EASY_TX_FORMAT(X
, Y
, Z
, ONE
, Z3Y3X2
)),
84 _ASSIGN(A8
, R300_EASY_TX_FORMAT(ZERO
, ZERO
, ZERO
, X
, X8
)),
85 _ASSIGN(L8
, R300_EASY_TX_FORMAT(X
, X
, X
, ONE
, X8
)),
86 _ASSIGN(I8
, R300_EASY_TX_FORMAT(X
, X
, X
, X
, X8
)),
87 _ASSIGN(CI8
, R300_EASY_TX_FORMAT(X
, X
, X
, X
, X8
)),
88 _ASSIGN(YCBCR
, R300_EASY_TX_FORMAT(X
, Y
, Z
, ONE
, G8R8_G8B8
)|R300_TX_FORMAT_YUV_MODE
),
89 _ASSIGN(YCBCR_REV
, R300_EASY_TX_FORMAT(X
, Y
, Z
, ONE
, G8R8_G8B8
)|R300_TX_FORMAT_YUV_MODE
),
90 _ASSIGN(RGB_DXT1
, R300_EASY_TX_FORMAT(X
, Y
, Z
, ONE
, DXT1
)),
91 _ASSIGN(RGBA_DXT1
, R300_EASY_TX_FORMAT(X
, Y
, Z
, W
, DXT1
)),
92 _ASSIGN(RGBA_DXT3
, R300_EASY_TX_FORMAT(X
, Y
, Z
, W
, DXT3
)),
93 _ASSIGN(RGBA_DXT5
, R300_EASY_TX_FORMAT(Y
, Z
, W
, X
, DXT5
)),
94 _ASSIGN(RGBA_FLOAT32
, R300_EASY_TX_FORMAT(Z
, Y
, X
, W
, FL_R32G32B32A32
)),
95 _ASSIGN(RGBA_FLOAT16
, R300_EASY_TX_FORMAT(Z
, Y
, X
, W
, FL_R16G16B16A16
)),
96 _ASSIGN(RGB_FLOAT32
, 0xffffffff),
97 _ASSIGN(RGB_FLOAT16
, 0xffffffff),
98 _ASSIGN(ALPHA_FLOAT32
, R300_EASY_TX_FORMAT(ZERO
, ZERO
, ZERO
, X
, FL_I32
)),
99 _ASSIGN(ALPHA_FLOAT16
, R300_EASY_TX_FORMAT(ZERO
, ZERO
, ZERO
, X
, FL_I16
)),
100 _ASSIGN(LUMINANCE_FLOAT32
, R300_EASY_TX_FORMAT(X
, X
, X
, ONE
, FL_I32
)),
101 _ASSIGN(LUMINANCE_FLOAT16
, R300_EASY_TX_FORMAT(X
, X
, X
, ONE
, FL_I16
)),
102 _ASSIGN(LUMINANCE_ALPHA_FLOAT32
, R300_EASY_TX_FORMAT(X
, X
, X
, Y
, FL_I32A32
)),
103 _ASSIGN(LUMINANCE_ALPHA_FLOAT16
, R300_EASY_TX_FORMAT(X
, X
, X
, Y
, FL_I16A16
)),
104 _ASSIGN(INTENSITY_FLOAT32
, R300_EASY_TX_FORMAT(X
, X
, X
, X
, FL_I32
)),
105 _ASSIGN(INTENSITY_FLOAT16
, R300_EASY_TX_FORMAT(X
, X
, X
, X
, FL_I16
)),
108 static const struct {
109 GLuint format
, filter
, flag
;
111 _ASSIGN(RGBA8888
, R300_EASY_TX_FORMAT(Y
, Z
, W
, X
, W8Z8Y8X8
)),
112 _ASSIGN(RGBA8888_REV
, R300_EASY_TX_FORMAT(Z
, Y
, X
, W
, W8Z8Y8X8
)),
113 _ASSIGN(ARGB8888
, R300_EASY_TX_FORMAT(X
, Y
, Z
, W
, W8Z8Y8X8
)),
114 _ASSIGN(ARGB8888_REV
, R300_EASY_TX_FORMAT(W
, Z
, Y
, X
, W8Z8Y8X8
)),
115 _ASSIGN(RGB888
, 0xffffffff),
116 _ASSIGN(RGB565
, R300_EASY_TX_FORMAT(X
, Y
, Z
, ONE
, Z5Y6X5
)),
117 _ASSIGN(RGB565_REV
, R300_EASY_TX_FORMAT(X
, Y
, Z
, ONE
, Z5Y6X5
)),
118 _ASSIGN(ARGB4444
, R300_EASY_TX_FORMAT(X
, Y
, Z
, W
, W4Z4Y4X4
)),
119 _ASSIGN(ARGB4444_REV
, R300_EASY_TX_FORMAT(X
, Y
, Z
, W
, W4Z4Y4X4
)),
120 _ASSIGN(ARGB1555
, R300_EASY_TX_FORMAT(X
, Y
, Z
, W
, W1Z5Y5X5
)),
121 _ASSIGN(ARGB1555_REV
, R300_EASY_TX_FORMAT(X
, Y
, Z
, W
, W1Z5Y5X5
)),
122 _ASSIGN(AL88
, R300_EASY_TX_FORMAT(X
, X
, X
, Y
, Y8X8
)),
123 _ASSIGN(AL88_REV
, R300_EASY_TX_FORMAT(X
, X
, X
, Y
, Y8X8
)),
124 _ASSIGN(RGB332
, R300_EASY_TX_FORMAT(X
, Y
, Z
, ONE
, Z3Y3X2
)),
125 _ASSIGN(A8
, R300_EASY_TX_FORMAT(ZERO
, ZERO
, ZERO
, X
, X8
)),
126 _ASSIGN(L8
, R300_EASY_TX_FORMAT(X
, X
, X
, ONE
, X8
)),
127 _ASSIGN(I8
, R300_EASY_TX_FORMAT(X
, X
, X
, X
, X8
)),
128 _ASSIGN(CI8
, R300_EASY_TX_FORMAT(X
, X
, X
, X
, X8
)),
129 _ASSIGN(YCBCR
, R300_EASY_TX_FORMAT(X
, Y
, Z
, ONE
, G8R8_G8B8
)|R300_TX_FORMAT_YUV_MODE
),
130 _ASSIGN(YCBCR_REV
, R300_EASY_TX_FORMAT(X
, Y
, Z
, ONE
, G8R8_G8B8
)|R300_TX_FORMAT_YUV_MODE
),
131 _ASSIGN(RGB_DXT1
, R300_EASY_TX_FORMAT(X
, Y
, Z
, ONE
, DXT1
)),
132 _ASSIGN(RGBA_DXT1
, R300_EASY_TX_FORMAT(X
, Y
, Z
, W
, DXT1
)),
133 _ASSIGN(RGBA_DXT3
, R300_EASY_TX_FORMAT(X
, Y
, Z
, W
, DXT3
)),
134 _ASSIGN(RGBA_DXT5
, R300_EASY_TX_FORMAT(Y
, Z
, W
, X
, DXT5
)),
135 _ASSIGN(RGBA_FLOAT32
, R300_EASY_TX_FORMAT(Z
, Y
, X
, W
, FL_R32G32B32A32
)),
136 _ASSIGN(RGBA_FLOAT16
, R300_EASY_TX_FORMAT(Z
, Y
, X
, W
, FL_R16G16B16A16
)),
137 _ASSIGN(RGB_FLOAT32
, 0xffffffff),
138 _ASSIGN(RGB_FLOAT16
, 0xffffffff),
139 _ASSIGN(ALPHA_FLOAT32
, R300_EASY_TX_FORMAT(ZERO
, ZERO
, ZERO
, X
, FL_I32
)),
140 _ASSIGN(ALPHA_FLOAT16
, R300_EASY_TX_FORMAT(ZERO
, ZERO
, ZERO
, X
, FL_I16
)),
141 _ASSIGN(LUMINANCE_FLOAT32
, R300_EASY_TX_FORMAT(X
, X
, X
, ONE
, FL_I32
)),
142 _ASSIGN(LUMINANCE_FLOAT16
, R300_EASY_TX_FORMAT(X
, X
, X
, ONE
, FL_I16
)),
143 _ASSIGN(LUMINANCE_ALPHA_FLOAT32
, R300_EASY_TX_FORMAT(X
, X
, X
, Y
, FL_I32A32
)),
144 _ASSIGN(LUMINANCE_ALPHA_FLOAT16
, R300_EASY_TX_FORMAT(X
, X
, X
, Y
, FL_I16A16
)),
145 _ASSIGN(INTENSITY_FLOAT32
, R300_EASY_TX_FORMAT(X
, X
, X
, X
, FL_I32
)),
146 _ASSIGN(INTENSITY_FLOAT16
, R300_EASY_TX_FORMAT(X
, X
, X
, X
, FL_I16
)),
153 * This function computes the number of bytes of storage needed for
154 * the given texture object (all mipmap levels, all cube faces).
155 * The \c image[face][level].x/y/width/height parameters for upload/blitting
156 * are computed here. \c filter, \c format, etc. will be set here
159 * \param rmesa Context pointer
160 * \param tObj GL texture object whose images are to be posted to
163 static void r300SetTexImages(r300ContextPtr rmesa
,
164 struct gl_texture_object
*tObj
)
166 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
167 const struct gl_texture_image
*baseImage
=
168 tObj
->Image
[0][tObj
->BaseLevel
];
169 GLint curOffset
, blitWidth
;
172 GLint log2Width
, log2Height
, log2Depth
;
174 /* Set the hardware texture format
176 if (VALID_FORMAT(baseImage
->TexFormat
->MesaFormat
)) {
177 if (_mesa_little_endian()) {
179 tx_table_le
[baseImage
->TexFormat
->MesaFormat
].format
;
181 tx_table_le
[baseImage
->TexFormat
->MesaFormat
].filter
;
184 tx_table_be
[baseImage
->TexFormat
->MesaFormat
].format
;
186 tx_table_be
[baseImage
->TexFormat
->MesaFormat
].filter
;
189 _mesa_problem(NULL
, "unexpected texture format in %s",
194 texelBytes
= baseImage
->TexFormat
->TexelBytes
;
196 /* Compute which mipmap levels we really want to send to the hardware.
198 driCalculateTextureFirstLastLevel((driTextureObject
*) t
);
199 log2Width
= tObj
->Image
[0][t
->base
.firstLevel
]->WidthLog2
;
200 log2Height
= tObj
->Image
[0][t
->base
.firstLevel
]->HeightLog2
;
201 log2Depth
= tObj
->Image
[0][t
->base
.firstLevel
]->DepthLog2
;
203 numLevels
= t
->base
.lastLevel
- t
->base
.firstLevel
+ 1;
205 assert(numLevels
<= RADEON_MAX_TEXTURE_LEVELS
);
207 /* Calculate mipmap offsets and dimensions for blitting (uploading)
208 * The idea is that we lay out the mipmap levels within a block of
209 * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
212 blitWidth
= R300_BLIT_WIDTH_BYTES
;
215 /* figure out if this texture is suitable for tiling. */
216 #if 0 /* Disabled for now */
218 if (rmesa
->texmicrotile
&& (tObj
->Target
!= GL_TEXTURE_RECTANGLE_NV
) &&
219 /* texrect might be able to use micro tiling too in theory? */
220 (baseImage
->Height
> 1)) {
222 /* allow 32 (bytes) x 1 mip (which will use two times the space
223 the non-tiled version would use) max if base texture is large enough */
224 if ((numLevels
== 1) ||
225 (((baseImage
->Width
* texelBytes
/ baseImage
->Height
) <= 32) &&
226 (baseImage
->Width
* texelBytes
> 64)) ||
227 ((baseImage
->Width
* texelBytes
/ baseImage
->Height
) <= 16)) {
228 t
->tile_bits
|= R300_TXO_MICRO_TILE
;
232 if (tObj
->Target
!= GL_TEXTURE_RECTANGLE_NV
) {
233 /* we can set macro tiling even for small textures, they will be untiled anyway */
234 t
->tile_bits
|= R300_TXO_MACRO_TILE
;
239 for (i
= 0; i
< numLevels
; i
++) {
240 const struct gl_texture_image
*texImage
;
243 texImage
= tObj
->Image
[0][i
+ t
->base
.firstLevel
];
247 /* find image size in bytes */
248 if (texImage
->IsCompressed
) {
249 if ((t
->format
& R300_TX_FORMAT_DXT1
) == R300_TX_FORMAT_DXT1
) {
250 // fprintf(stderr,"DXT 1 %d %08X\n", texImage->Width, t->format);
251 if ((texImage
->Width
+ 3) < 8) /* width one block */
252 size
= texImage
->CompressedSize
* 4;
253 else if ((texImage
->Width
+ 3) < 16)
254 size
= texImage
->CompressedSize
* 2;
256 size
= texImage
->CompressedSize
;
258 /* DXT3/5, 16 bytes per block */
259 WARN_ONCE("DXT 3/5 suffers from multitexturing problems!\n");
260 // fprintf(stderr,"DXT 3/5 %d\n", texImage->Width);
261 if ((texImage
->Width
+ 3) < 8)
262 size
= texImage
->CompressedSize
* 2;
264 size
= texImage
->CompressedSize
;
266 } else if (tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
) {
267 size
= ((texImage
->Width
* texelBytes
+ 63) & ~63) * texImage
->Height
;
268 blitWidth
= 64 / texelBytes
;
269 } else if (t
->tile_bits
& R300_TXO_MICRO_TILE
) {
270 /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
271 though the actual offset may be different (if texture is less than
272 32 bytes width) to the untiled case */
273 int w
= (texImage
->Width
* texelBytes
* 2 + 31) & ~31;
274 size
= (w
* ((texImage
->Height
+ 1) / 2)) * texImage
->Depth
;
275 blitWidth
= MAX2(texImage
->Width
, 64 / texelBytes
);
277 int w
= (texImage
->Width
* texelBytes
+ 31) & ~31;
278 size
= w
* texImage
->Height
* texImage
->Depth
;
279 blitWidth
= MAX2(texImage
->Width
, 64 / texelBytes
);
284 fprintf(stderr
, "w=%d h=%d d=%d tb=%d intFormat=%d\n",
285 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 /* fix x and y coords up later together with offset */
297 t
->image
[0][i
].x
= curOffset
;
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
;
310 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
311 i
, texImage
->Width
, texImage
->Height
,
312 t
->image
[0][i
].x
, t
->image
[0][i
].y
,
313 t
->image
[0][i
].width
, t
->image
[0][i
].height
,
319 /* Align the total size of texture memory block.
322 (curOffset
+ RADEON_OFFSET_MASK
) & ~RADEON_OFFSET_MASK
;
324 /* Setup remaining cube face blits, if needed */
325 if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
327 for (face
= 1; face
< 6; face
++) {
328 for (i
= 0; i
< numLevels
; i
++) {
329 t
->image
[face
][i
].x
= t
->image
[0][i
].x
;
330 t
->image
[face
][i
].y
= t
->image
[0][i
].y
;
331 t
->image
[face
][i
].width
= t
->image
[0][i
].width
;
332 t
->image
[face
][i
].height
=
333 t
->image
[0][i
].height
;
336 t
->base
.totalSize
*= 6; /* total texmem needed */
342 t
->format
&= ~(R200_TXFORMAT_WIDTH_MASK
|
343 R200_TXFORMAT_HEIGHT_MASK
|
344 R200_TXFORMAT_CUBIC_MAP_ENABLE
|
345 R200_TXFORMAT_F5_WIDTH_MASK
|
346 R200_TXFORMAT_F5_HEIGHT_MASK
);
347 t
->format
|= ((log2Width
<< R200_TXFORMAT_WIDTH_SHIFT
) |
348 (log2Height
<< R200_TXFORMAT_HEIGHT_SHIFT
));
351 t
->format_x
&= ~(R200_DEPTH_LOG2_MASK
| R200_TEXCOORD_MASK
);
352 if (tObj
->Target
== GL_TEXTURE_3D
) {
353 t
->format_x
|= (log2Depth
<< R200_DEPTH_LOG2_SHIFT
);
354 t
->format_x
|= R200_TEXCOORD_VOLUME
;
355 } else if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
356 ASSERT(log2Width
== log2Height
);
357 t
->format
|= R300_TX_FORMAT_CUBIC_MAP
;
359 t
->format_x
|= R200_TEXCOORD_CUBIC_ENV
;
360 t
->pp_cubic_faces
= ((log2Width
<< R200_FACE_WIDTH_1_SHIFT
) |
361 (log2Height
<< R200_FACE_HEIGHT_1_SHIFT
) |
362 (log2Width
<< R200_FACE_WIDTH_2_SHIFT
) |
363 (log2Height
<< R200_FACE_HEIGHT_2_SHIFT
) |
364 (log2Width
<< R200_FACE_WIDTH_3_SHIFT
) |
365 (log2Height
<< R200_FACE_HEIGHT_3_SHIFT
) |
366 (log2Width
<< R200_FACE_WIDTH_4_SHIFT
) |
367 (log2Height
<< R200_FACE_HEIGHT_4_SHIFT
));
370 if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
371 ASSERT(log2Width
== log2Height
);
372 t
->format
|= R300_TX_FORMAT_CUBIC_MAP
;
375 t
->size
= (((tObj
->Image
[0][t
->base
.firstLevel
]->Width
- 1) << R300_TX_WIDTHMASK_SHIFT
)
376 |((tObj
->Image
[0][t
->base
.firstLevel
]->Height
- 1) << R300_TX_HEIGHTMASK_SHIFT
))
377 |((numLevels
- 1) << R300_TX_MAX_MIP_LEVEL_SHIFT
);
379 /* Only need to round to nearest 32 for textures, but the blitter
380 * requires 64-byte aligned pitches, and we may/may not need the
381 * blitter. NPOT only!
383 if (baseImage
->IsCompressed
) {
385 (tObj
->Image
[0][t
->base
.firstLevel
]->Width
+ 63) & ~(63);
387 else if (tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
) {
388 unsigned int align
= blitWidth
- 1;
389 t
->pitch
= ((tObj
->Image
[0][t
->base
.firstLevel
]->Width
*
390 texelBytes
) + 63) & ~(63);
391 t
->size
|= R300_TX_SIZE_TXPITCH_EN
;
392 t
->pitch_reg
= (((tObj
->Image
[0][t
->base
.firstLevel
]->Width
) + align
) & ~align
) - 1;
396 ((tObj
->Image
[0][t
->base
.firstLevel
]->Width
*
397 texelBytes
) + 63) & ~(63);
400 t
->dirty_state
= TEX_ALL
;
402 /* FYI: r300UploadTexImages( rmesa, t ) used to be called here */
406 /* ================================================================
407 * Texture unit state management
410 static GLboolean
enable_tex_2d(GLcontext
* ctx
, int unit
)
412 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
413 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
414 struct gl_texture_object
*tObj
= texUnit
->_Current
;
415 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
417 ASSERT(tObj
->Target
== GL_TEXTURE_2D
|| tObj
->Target
== GL_TEXTURE_1D
);
419 if (t
->base
.dirty_images
[0]) {
420 R300_FIREVERTICES(rmesa
);
421 r300SetTexImages(rmesa
, tObj
);
422 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
423 if (!t
->base
.memBlock
)
430 #if ENABLE_HW_3D_TEXTURE
431 static GLboolean
enable_tex_3d(GLcontext
* ctx
, int unit
)
433 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
434 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
435 struct gl_texture_object
*tObj
= texUnit
->_Current
;
436 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
438 /* Need to load the 3d images associated with this unit.
441 if (t
->format
& R200_TXFORMAT_NON_POWER2
) {
442 t
->format
&= ~R200_TXFORMAT_NON_POWER2
;
443 t
->base
.dirty_images
[0] = ~0;
446 ASSERT(tObj
->Target
== GL_TEXTURE_3D
);
448 /* R100 & R200 do not support mipmaps for 3D textures.
450 if ((tObj
->MinFilter
!= GL_NEAREST
) && (tObj
->MinFilter
!= GL_LINEAR
)) {
454 if (t
->base
.dirty_images
[0]) {
455 R300_FIREVERTICES(rmesa
);
456 r300SetTexImages(rmesa
, tObj
);
457 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
458 if (!t
->base
.memBlock
)
466 static GLboolean
enable_tex_cube(GLcontext
* ctx
, int unit
)
468 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
469 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
470 struct gl_texture_object
*tObj
= texUnit
->_Current
;
471 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
474 /* Need to load the 2d images associated with this unit.
477 if (t
->format
& R200_TXFORMAT_NON_POWER2
) {
478 t
->format
&= ~R200_TXFORMAT_NON_POWER2
;
479 for (face
= 0; face
< 6; face
++)
480 t
->base
.dirty_images
[face
] = ~0;
483 ASSERT(tObj
->Target
== GL_TEXTURE_CUBE_MAP
);
485 if (t
->base
.dirty_images
[0] || t
->base
.dirty_images
[1] ||
486 t
->base
.dirty_images
[2] || t
->base
.dirty_images
[3] ||
487 t
->base
.dirty_images
[4] || t
->base
.dirty_images
[5]) {
489 R300_FIREVERTICES(rmesa
);
490 /* layout memory space, once for all faces */
491 r300SetTexImages(rmesa
, tObj
);
494 /* upload (per face) */
495 for (face
= 0; face
< 6; face
++) {
496 if (t
->base
.dirty_images
[face
]) {
497 r300UploadTexImages(rmesa
,
498 (r300TexObjPtr
) tObj
->DriverData
,
503 if (!t
->base
.memBlock
) {
504 /* texmem alloc failed, use s/w fallback */
511 static GLboolean
enable_tex_rect(GLcontext
* ctx
, int unit
)
513 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
514 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
515 struct gl_texture_object
*tObj
= texUnit
->_Current
;
516 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
518 ASSERT(tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
);
520 if (t
->base
.dirty_images
[0]) {
521 R300_FIREVERTICES(rmesa
);
522 r300SetTexImages(rmesa
, tObj
);
523 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
524 if (!t
->base
.memBlock
&& !rmesa
->prefer_gart_client_texturing
)
531 static GLboolean
update_tex_common(GLcontext
* ctx
, int unit
)
533 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
534 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
535 struct gl_texture_object
*tObj
= texUnit
->_Current
;
536 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
538 /* Fallback if there's a texture border */
539 if (tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0)
542 /* Update state if this is a different texture object to last
545 if (rmesa
->state
.texture
.unit
[unit
].texobj
!= t
) {
546 if (rmesa
->state
.texture
.unit
[unit
].texobj
!= NULL
) {
547 /* The old texture is no longer bound to this texture unit.
551 rmesa
->state
.texture
.unit
[unit
].texobj
->base
.bound
&=
555 rmesa
->state
.texture
.unit
[unit
].texobj
= t
;
556 t
->base
.bound
|= (1UL << unit
);
557 t
->dirty_state
|= 1 << unit
;
558 driUpdateTextureLRU((driTextureObject
*) t
); /* XXX: should be locked! */
561 return !t
->border_fallback
;
564 static GLboolean
r300UpdateTextureUnit(GLcontext
* ctx
, int unit
)
566 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
568 if (texUnit
->_ReallyEnabled
& (TEXTURE_RECT_BIT
)) {
569 return (enable_tex_rect(ctx
, unit
) &&
570 update_tex_common(ctx
, unit
));
571 } else if (texUnit
->_ReallyEnabled
& (TEXTURE_1D_BIT
| TEXTURE_2D_BIT
)) {
572 return (enable_tex_2d(ctx
, unit
) &&
573 update_tex_common(ctx
, unit
));
575 #if ENABLE_HW_3D_TEXTURE
576 else if (texUnit
->_ReallyEnabled
& (TEXTURE_3D_BIT
)) {
577 return (enable_tex_3d(ctx
, unit
) &&
578 update_tex_common(ctx
, unit
));
581 else if (texUnit
->_ReallyEnabled
& (TEXTURE_CUBE_BIT
)) {
582 return (enable_tex_cube(ctx
, unit
) &&
583 update_tex_common(ctx
, unit
));
584 } else if (texUnit
->_ReallyEnabled
) {
591 void r300UpdateTextureState(GLcontext
* ctx
)
595 ok
= (r300UpdateTextureUnit(ctx
, 0) &&
596 r300UpdateTextureUnit(ctx
, 1) &&
597 r300UpdateTextureUnit(ctx
, 2) &&
598 r300UpdateTextureUnit(ctx
, 3) &&
599 r300UpdateTextureUnit(ctx
, 4) &&
600 r300UpdateTextureUnit(ctx
, 5) &&
601 r300UpdateTextureUnit(ctx
, 6) &&
602 r300UpdateTextureUnit(ctx
, 7)