merge of glsl-compiler-1 branch
[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 * Authors:
32 * Keith Whitwell <keith@tungstengraphics.com>
33 */
34
35 #include "glheader.h"
36 #include "imports.h"
37 #include "context.h"
38 #include "macros.h"
39 #include "texformat.h"
40 #include "enums.h"
41
42 #include "r300_context.h"
43 #include "r300_state.h"
44 #include "r300_ioctl.h"
45 #include "radeon_ioctl.h"
46 #include "r300_tex.h"
47 #include "r300_reg.h"
48
49
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 )
54
55 #define _ASSIGN(entry, format) \
56 [ MESA_FORMAT_ ## entry ] = { format, 0, 1}
57
58 static const struct {
59 GLuint format, filter, flag;
60 } tx_table_be[] = {
61 /*
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
69 */
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)),
106 };
107
108 static const struct {
109 GLuint format, filter, flag;
110 } tx_table_le[] = {
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)),
147 };
148
149 #undef _ASSIGN
150
151
152 /**
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
157 * too.
158 *
159 * \param rmesa Context pointer
160 * \param tObj GL texture object whose images are to be posted to
161 * hardware state.
162 */
163 static void r300SetTexImages(r300ContextPtr rmesa,
164 struct gl_texture_object *tObj)
165 {
166 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
167 const struct gl_texture_image *baseImage =
168 tObj->Image[0][tObj->BaseLevel];
169 GLint curOffset, blitWidth;
170 GLint i, texelBytes;
171 GLint numLevels;
172 GLint log2Width, log2Height, log2Depth;
173
174 /* Set the hardware texture format
175 */
176 if (VALID_FORMAT(baseImage->TexFormat->MesaFormat)) {
177 if (_mesa_little_endian()) {
178 t->format =
179 tx_table_le[baseImage->TexFormat->MesaFormat].format;
180 t->filter |=
181 tx_table_le[baseImage->TexFormat->MesaFormat].filter;
182 } else {
183 t->format =
184 tx_table_be[baseImage->TexFormat->MesaFormat].format;
185 t->filter |=
186 tx_table_be[baseImage->TexFormat->MesaFormat].filter;
187 }
188 } else {
189 _mesa_problem(NULL, "unexpected texture format in %s",
190 __FUNCTION__);
191 return;
192 }
193
194 texelBytes = baseImage->TexFormat->TexelBytes;
195
196 /* Compute which mipmap levels we really want to send to the hardware.
197 */
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;
202
203 numLevels = t->base.lastLevel - t->base.firstLevel + 1;
204
205 assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS);
206
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.
210 */
211 curOffset = 0;
212 blitWidth = R300_BLIT_WIDTH_BYTES;
213 t->tile_bits = 0;
214
215 /* figure out if this texture is suitable for tiling. */
216 #if 0 /* Disabled for now */
217 if (texelBytes) {
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)) {
221
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;
229 }
230 }
231
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;
235 }
236 }
237 #endif
238
239 for (i = 0; i < numLevels; i++) {
240 const struct gl_texture_image *texImage;
241 GLuint size;
242
243 texImage = tObj->Image[0][i + t->base.firstLevel];
244 if (!texImage)
245 break;
246
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;
255 else
256 size = texImage->CompressedSize;
257 } else {
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;
263 else
264 size = texImage->CompressedSize;
265 }
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);
276 } else {
277 int w = (texImage->Width * texelBytes + 31) & ~31;
278 size = w * texImage->Height * texImage->Depth;
279 blitWidth = MAX2(texImage->Width, 64 / texelBytes);
280 }
281 assert(size > 0);
282
283 if(0)
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);
288
289 /* Align to 32-byte offset. It is faster to do this unconditionally
290 * (no branch penalty).
291 */
292
293 curOffset = (curOffset + 0x1f) & ~0x1f;
294
295 if (texelBytes) {
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;
301 } else {
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;
306 }
307
308 if (0)
309 fprintf(stderr,
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,
314 size, curOffset);
315
316 curOffset += size;
317 }
318
319 /* Align the total size of texture memory block.
320 */
321 t->base.totalSize =
322 (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
323
324 /* Setup remaining cube face blits, if needed */
325 if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
326 GLuint face;
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;
334 }
335 }
336 t->base.totalSize *= 6; /* total texmem needed */
337 }
338
339 /* Hardware state:
340 */
341 #if 0
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));
349 #endif
350 #if 0
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;
358
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));
368 }
369 #endif
370 if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
371 ASSERT(log2Width == log2Height);
372 t->format |= R300_TX_FORMAT_CUBIC_MAP;
373 }
374
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);
378
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!
382 */
383 if (baseImage->IsCompressed) {
384 t->pitch =
385 (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63);
386 }
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;
393 }
394 else {
395 t->pitch =
396 ((tObj->Image[0][t->base.firstLevel]->Width *
397 texelBytes) + 63) & ~(63);
398 }
399
400 t->dirty_state = TEX_ALL;
401
402 /* FYI: r300UploadTexImages( rmesa, t ) used to be called here */
403 }
404
405
406 /* ================================================================
407 * Texture unit state management
408 */
409
410 static GLboolean enable_tex_2d(GLcontext * ctx, int unit)
411 {
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;
416
417 ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D);
418
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)
424 return GL_FALSE;
425 }
426
427 return GL_TRUE;
428 }
429
430 #if ENABLE_HW_3D_TEXTURE
431 static GLboolean enable_tex_3d(GLcontext * ctx, int unit)
432 {
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;
437
438 /* Need to load the 3d images associated with this unit.
439 */
440 #if 0
441 if (t->format & R200_TXFORMAT_NON_POWER2) {
442 t->format &= ~R200_TXFORMAT_NON_POWER2;
443 t->base.dirty_images[0] = ~0;
444 }
445 #endif
446 ASSERT(tObj->Target == GL_TEXTURE_3D);
447
448 /* R100 & R200 do not support mipmaps for 3D textures.
449 */
450 if ((tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) {
451 return GL_FALSE;
452 }
453
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)
459 return GL_FALSE;
460 }
461
462 return GL_TRUE;
463 }
464 #endif
465
466 static GLboolean enable_tex_cube(GLcontext * ctx, int unit)
467 {
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;
472 GLuint face;
473
474 /* Need to load the 2d images associated with this unit.
475 */
476 #if 0
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;
481 }
482 #endif
483 ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP);
484
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]) {
488 /* flush */
489 R300_FIREVERTICES(rmesa);
490 /* layout memory space, once for all faces */
491 r300SetTexImages(rmesa, tObj);
492 }
493
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,
499 face);
500 }
501 }
502
503 if (!t->base.memBlock) {
504 /* texmem alloc failed, use s/w fallback */
505 return GL_FALSE;
506 }
507
508 return GL_TRUE;
509 }
510
511 static GLboolean enable_tex_rect(GLcontext * ctx, int unit)
512 {
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;
517
518 ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);
519
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)
525 return GL_FALSE;
526 }
527
528 return GL_TRUE;
529 }
530
531 static GLboolean update_tex_common(GLcontext * ctx, int unit)
532 {
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;
537
538 /* Fallback if there's a texture border */
539 if (tObj->Image[0][tObj->BaseLevel]->Border > 0)
540 return GL_FALSE;
541
542 /* Update state if this is a different texture object to last
543 * time.
544 */
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.
548 * Mark it as such.
549 */
550
551 rmesa->state.texture.unit[unit].texobj->base.bound &=
552 ~(1UL << unit);
553 }
554
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! */
559 }
560
561 return !t->border_fallback;
562 }
563
564 static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit)
565 {
566 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
567
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));
574 }
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));
579 }
580 #endif
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) {
585 return GL_FALSE;
586 } else {
587 return GL_TRUE;
588 }
589 }
590
591 void r300UpdateTextureState(GLcontext * ctx)
592 {
593 GLboolean ok;
594
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)
603 );
604 }