Doesnt apply anymore
[mesa.git] / src / mesa / drivers / dri / r300 / r300_texstate.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r300/r300_texstate.c,v 1.3 2003/02/15 22:18:47 dawes Exp $ */
2 /*
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4
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.
8
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:
16
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.
20
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.
28
29 **************************************************************************/
30
31 /*
32 * Authors:
33 * Keith Whitwell <keith@tungstengraphics.com>
34 */
35
36 #include "glheader.h"
37 #include "imports.h"
38 #include "context.h"
39 #include "macros.h"
40 #include "texformat.h"
41 #include "enums.h"
42
43 #include "r300_context.h"
44 #include "r300_state.h"
45 #include "r300_ioctl.h"
46 #include "radeon_ioctl.h"
47 //#include "r300_swtcl.h"
48 #include "r300_tex.h"
49 //#include "r300_tcl.h"
50 #include "r300_reg.h"
51
52 #define R200_TXFORMAT_A8 R200_TXFORMAT_I8
53 #define R200_TXFORMAT_L8 R200_TXFORMAT_I8
54 #define R200_TXFORMAT_AL88 R200_TXFORMAT_AI88
55 #define R200_TXFORMAT_YCBCR R200_TXFORMAT_YVYU422
56 #define R200_TXFORMAT_YCBCR_REV R200_TXFORMAT_VYUY422
57 #define R200_TXFORMAT_RGB_DXT1 R200_TXFORMAT_DXT1
58 #define R200_TXFORMAT_RGBA_DXT1 R200_TXFORMAT_DXT1
59 #define R200_TXFORMAT_RGBA_DXT3 R200_TXFORMAT_DXT23
60 #define R200_TXFORMAT_RGBA_DXT5 R200_TXFORMAT_DXT45
61
62 #define _COLOR(f) \
63 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, 0 }
64 #define _COLOR_REV(f) \
65 [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f, 0 }
66 #define _ALPHA(f) \
67 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
68 #define _ALPHA_REV(f) \
69 [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
70 #define _YUV(f) \
71 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, R200_YUV_TO_RGB }
72 #define _INVALID(f) \
73 [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
74 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \
75 && tx_table[f].flag )
76
77 #define _ASSIGN(entry, format) \
78 [ MESA_FORMAT_ ## entry ] = { format, 0, 1}
79
80 static const struct {
81 GLuint format, filter;
82 } tx_table0[] = {
83 _ALPHA(RGBA8888),
84 _ALPHA_REV(RGBA8888),
85 _ALPHA(ARGB8888),
86 _ALPHA_REV(ARGB8888),
87 _INVALID(RGB888),
88 _COLOR(RGB565),
89 _COLOR_REV(RGB565),
90 _ALPHA(ARGB4444),
91 _ALPHA_REV(ARGB4444),
92 _ALPHA(ARGB1555),
93 _ALPHA_REV(ARGB1555),
94 _ALPHA(AL88),
95 _ALPHA_REV(AL88),
96 _ALPHA(A8),
97 _COLOR(L8),
98 _ALPHA(I8),
99 _INVALID(CI8),
100 _YUV(YCBCR),
101 _YUV(YCBCR_REV),
102 _INVALID(RGB_FXT1),
103 _INVALID(RGBA_FXT1),
104 _COLOR(RGB_DXT1),
105 _ALPHA(RGBA_DXT1),
106 _ALPHA(RGBA_DXT3),
107 _ALPHA(RGBA_DXT5),
108 };
109
110 static const struct {
111 GLuint format, filter, flag;
112 } tx_table[] = {
113 /*
114 * Note that the _REV formats are the same as the non-REV formats.
115 * This is because the REV and non-REV formats are identical as a
116 * byte string, but differ when accessed as 16-bit or 32-bit words
117 * depending on the endianness of the host. Since the textures are
118 * transferred to the R300 as a byte string (i.e. without any
119 * byte-swapping), the R300 sees the REV and non-REV formats
120 * identically. -- paulus
121 */
122 _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
123 _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
124 _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
125 _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
126 _ASSIGN(RGB888, 0xffffffff),
127 _ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
128 _ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
129 _ASSIGN(ARGB4444, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
130 _ASSIGN(ARGB4444_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
131 _ASSIGN(ARGB1555, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
132 _ASSIGN(ARGB1555_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
133 _ASSIGN(AL88, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
134 _ASSIGN(AL88_REV, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
135 _ASSIGN(RGB332, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z3Y3X2)),
136 _ASSIGN(A8, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8)),
137 _ASSIGN(L8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8)),
138 _ASSIGN(I8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
139 _ASSIGN(CI8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
140 _ASSIGN(YCBCR, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8)|R300_TX_FORMAT_YUV_MODE ),
141 _ASSIGN(YCBCR_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8)|R300_TX_FORMAT_YUV_MODE),
142 _ASSIGN(RGB_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1)),
143 _ASSIGN(RGBA_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1)),
144 _ASSIGN(RGBA_DXT3, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3)),
145 _ASSIGN(RGBA_DXT5, R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5)),
146 };
147
148 #undef _COLOR
149 #undef _ALPHA
150 #undef _INVALID
151 #undef _ASSIGN
152
153
154 /**
155 * This function computes the number of bytes of storage needed for
156 * the given texture object (all mipmap levels, all cube faces).
157 * The \c image[face][level].x/y/width/height parameters for upload/blitting
158 * are computed here. \c filter, \c format, etc. will be set here
159 * too.
160 *
161 * \param rmesa Context pointer
162 * \param tObj GL texture object whose images are to be posted to
163 * hardware state.
164 */
165 static void r300SetTexImages(r300ContextPtr rmesa,
166 struct gl_texture_object *tObj)
167 {
168 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
169 const struct gl_texture_image *baseImage =
170 tObj->Image[0][tObj->BaseLevel];
171 GLint curOffset, blitWidth;
172 GLint i, texelBytes;
173 GLint numLevels;
174 GLint log2Width, log2Height, log2Depth;
175
176 /* Set the hardware texture format
177 */
178
179 t->format &= ~(R200_TXFORMAT_FORMAT_MASK |
180 R200_TXFORMAT_ALPHA_IN_MAP);
181 #if 0
182 t->filter &= ~R200_YUV_TO_RGB;
183 #endif
184 if (VALID_FORMAT(baseImage->TexFormat->MesaFormat)) {
185 t->format =
186 tx_table[baseImage->TexFormat->MesaFormat].format;
187 #if 1
188 t->filter |=
189 tx_table[baseImage->TexFormat->MesaFormat].filter;
190 #endif
191 } else {
192 _mesa_problem(NULL, "unexpected texture format in %s",
193 __FUNCTION__);
194 return;
195 }
196
197 texelBytes = baseImage->TexFormat->TexelBytes;
198
199 /* Compute which mipmap levels we really want to send to the hardware.
200 */
201
202 driCalculateTextureFirstLastLevel((driTextureObject *) t);
203 log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
204 log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
205 log2Depth = tObj->Image[0][t->base.firstLevel]->DepthLog2;
206
207 numLevels = t->base.lastLevel - t->base.firstLevel + 1;
208
209 assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS);
210
211 /* Calculate mipmap offsets and dimensions for blitting (uploading)
212 * The idea is that we lay out the mipmap levels within a block of
213 * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
214 */
215 curOffset = 0;
216 blitWidth = BLIT_WIDTH_BYTES;
217
218 for (i = 0; i < numLevels; i++) {
219 const struct gl_texture_image *texImage;
220 GLuint size;
221
222 texImage = tObj->Image[0][i + t->base.firstLevel];
223 if (!texImage)
224 break;
225
226 /* find image size in bytes */
227 if (texImage->IsCompressed) {
228 if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1) {
229 // fprintf(stderr,"DXT 1 %d %08X\n", texImage->Width, t->format);
230 if ((texImage->Width + 3) < 8) /* width one block */
231 size = texImage->CompressedSize * 4;
232 else if ((texImage->Width + 3) < 16)
233 size = texImage->CompressedSize * 2;
234 else size = texImage->CompressedSize;
235 }
236 else /* DXT3/5, 16 bytes per block */
237 {
238 // fprintf(stderr,"DXT 3/5 %d\n", texImage->Width);
239 if ((texImage->Width + 3) < 8)
240 size = texImage->CompressedSize * 2;
241 else size = texImage->CompressedSize;
242 }
243
244 } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
245 size = ((texImage->Width * texelBytes + 63) & ~63) * texImage->Height;
246 blitWidth = 64 / texelBytes;
247 } else {
248 int w = (texImage->Width * texelBytes + 31) & ~31;
249 size = w * texImage->Height * texImage->Depth;
250 blitWidth = MAX2(texImage->Width, 64 / texelBytes);
251 }
252 assert(size > 0);
253
254 if(0)
255 fprintf(stderr, "w=%d h=%d d=%d tb=%d intFormat=%d\n", texImage->Width, texImage->Height,
256 texImage->Depth, texImage->TexFormat->TexelBytes,
257 texImage->InternalFormat);
258
259 /* Align to 32-byte offset. It is faster to do this unconditionally
260 * (no branch penalty).
261 */
262
263 curOffset = (curOffset + 0x1f) & ~0x1f;
264
265 if (texelBytes) {
266 t->image[0][i].x = curOffset; /* fix x and y coords up later together with offset */
267 t->image[0][i].y = 0;
268 t->image[0][i].width = MIN2(size / texelBytes, blitWidth);
269 t->image[0][i].height = (size / texelBytes) / t->image[0][i].width;
270 } else {
271 t->image[0][i].x = curOffset % BLIT_WIDTH_BYTES;
272 t->image[0][i].y = curOffset / BLIT_WIDTH_BYTES;
273 t->image[0][i].width = MIN2(size, BLIT_WIDTH_BYTES);
274 t->image[0][i].height = size / t->image[0][i].width;
275 }
276 #if 0
277 /* for debugging only and only applicable to non-rectangle targets */
278 assert(size % t->image[0][i].width == 0);
279 assert(t->image[0][i].x == 0
280 || (size < BLIT_WIDTH_BYTES
281 && t->image[0][i].height == 1));
282 #endif
283
284 if (0)
285 fprintf(stderr,
286 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
287 i, texImage->Width, texImage->Height,
288 t->image[0][i].x, t->image[0][i].y,
289 t->image[0][i].width, t->image[0][i].height,
290 size, curOffset);
291
292 curOffset += size;
293
294 }
295
296 /* Align the total size of texture memory block.
297 */
298 t->base.totalSize =
299 (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
300
301 /* Setup remaining cube face blits, if needed */
302 if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
303 GLuint face;
304 for (face = 1; face < 6; face++) {
305 for (i = 0; i < numLevels; i++) {
306 t->image[face][i].x = t->image[0][i].x;
307 t->image[face][i].y = t->image[0][i].y;
308 t->image[face][i].width = t->image[0][i].width;
309 t->image[face][i].height =
310 t->image[0][i].height;
311 }
312 }
313 t->base.totalSize *= 6; /* total texmem needed */
314 }
315
316 /* Hardware state:
317 */
318 #if 0
319 t->filter &= ~R200_MAX_MIP_LEVEL_MASK;
320 t->filter |= (numLevels - 1) << R200_MAX_MIP_LEVEL_SHIFT;
321 #endif
322 #if 0
323 t->format &= ~(R200_TXFORMAT_WIDTH_MASK |
324 R200_TXFORMAT_HEIGHT_MASK |
325 R200_TXFORMAT_CUBIC_MAP_ENABLE |
326 R200_TXFORMAT_F5_WIDTH_MASK |
327 R200_TXFORMAT_F5_HEIGHT_MASK);
328 t->format |= ((log2Width << R200_TXFORMAT_WIDTH_SHIFT) |
329 (log2Height << R200_TXFORMAT_HEIGHT_SHIFT));
330 #endif
331
332 t->format_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK);
333 if (tObj->Target == GL_TEXTURE_3D) {
334 t->format_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT);
335 t->format_x |= R200_TEXCOORD_VOLUME;
336 } else if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
337 ASSERT(log2Width == log2Height);
338 t->format |= R300_TX_FORMAT_CUBIC_MAP;
339
340 t->format_x |= R200_TEXCOORD_CUBIC_ENV;
341 t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) |
342 (log2Height << R200_FACE_HEIGHT_1_SHIFT) |
343 (log2Width << R200_FACE_WIDTH_2_SHIFT) |
344 (log2Height << R200_FACE_HEIGHT_2_SHIFT) |
345 (log2Width << R200_FACE_WIDTH_3_SHIFT) |
346 (log2Height << R200_FACE_HEIGHT_3_SHIFT) |
347 (log2Width << R200_FACE_WIDTH_4_SHIFT) |
348 (log2Height << R200_FACE_HEIGHT_4_SHIFT));
349 }
350
351 t->size = (((tObj->Image[0][t->base.firstLevel]->Width - 1) << R300_TX_WIDTHMASK_SHIFT)
352 |((tObj->Image[0][t->base.firstLevel]->Height - 1) << R300_TX_HEIGHTMASK_SHIFT));
353
354 /* Only need to round to nearest 32 for textures, but the blitter
355 * requires 64-byte aligned pitches, and we may/may not need the
356 * blitter. NPOT only!
357 */
358 if (baseImage->IsCompressed) {
359 t->pitch =
360 (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63);
361 t->size |= ((log2Width>log2Height)?log2Width:log2Height)<<R300_TX_SIZE_SHIFT;
362 }
363 else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
364 unsigned int align = blitWidth - 1;
365 t->pitch = ((tObj->Image[0][t->base.firstLevel]->Width *
366 texelBytes) + 63) & ~(63);
367 t->size |= R300_TX_SIZE_TXPITCH_EN;
368 t->pitch_reg = (((tObj->Image[0][t->base.firstLevel]->Width) + align) & ~align) - 1;
369 }
370 else {
371 t->size |= ((log2Width>log2Height)?log2Width:log2Height)<<R300_TX_SIZE_SHIFT;
372 t->pitch =
373 ((tObj->Image[0][t->base.firstLevel]->Width *
374 texelBytes) + 63) & ~(63);
375 }
376
377 t->dirty_state = TEX_ALL;
378
379 /* FYI: r300UploadTexImages( rmesa, t ) used to be called here */
380 }
381
382 /* ================================================================
383 * Texture combine functions
384 */
385
386 /* GL_ARB_texture_env_combine support
387 */
388
389 /* The color tables have combine functions for GL_SRC_COLOR,
390 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
391 */
392 static GLuint r300_register_color[][R200_MAX_TEXTURE_UNITS] = {
393 {
394 R200_TXC_ARG_A_R0_COLOR,
395 R200_TXC_ARG_A_R1_COLOR,
396 R200_TXC_ARG_A_R2_COLOR,
397 R200_TXC_ARG_A_R3_COLOR,
398 R200_TXC_ARG_A_R4_COLOR,
399 R200_TXC_ARG_A_R5_COLOR},
400 {
401 R200_TXC_ARG_A_R0_COLOR | R200_TXC_COMP_ARG_A,
402 R200_TXC_ARG_A_R1_COLOR | R200_TXC_COMP_ARG_A,
403 R200_TXC_ARG_A_R2_COLOR | R200_TXC_COMP_ARG_A,
404 R200_TXC_ARG_A_R3_COLOR | R200_TXC_COMP_ARG_A,
405 R200_TXC_ARG_A_R4_COLOR | R200_TXC_COMP_ARG_A,
406 R200_TXC_ARG_A_R5_COLOR | R200_TXC_COMP_ARG_A},
407 {
408 R200_TXC_ARG_A_R0_ALPHA,
409 R200_TXC_ARG_A_R1_ALPHA,
410 R200_TXC_ARG_A_R2_ALPHA,
411 R200_TXC_ARG_A_R3_ALPHA,
412 R200_TXC_ARG_A_R4_ALPHA,
413 R200_TXC_ARG_A_R5_ALPHA},
414 {
415 R200_TXC_ARG_A_R0_ALPHA | R200_TXC_COMP_ARG_A,
416 R200_TXC_ARG_A_R1_ALPHA | R200_TXC_COMP_ARG_A,
417 R200_TXC_ARG_A_R2_ALPHA | R200_TXC_COMP_ARG_A,
418 R200_TXC_ARG_A_R3_ALPHA | R200_TXC_COMP_ARG_A,
419 R200_TXC_ARG_A_R4_ALPHA | R200_TXC_COMP_ARG_A,
420 R200_TXC_ARG_A_R5_ALPHA | R200_TXC_COMP_ARG_A},
421 };
422
423 static GLuint r300_tfactor_color[] = {
424 R200_TXC_ARG_A_TFACTOR_COLOR,
425 R200_TXC_ARG_A_TFACTOR_COLOR | R200_TXC_COMP_ARG_A,
426 R200_TXC_ARG_A_TFACTOR_ALPHA,
427 R200_TXC_ARG_A_TFACTOR_ALPHA | R200_TXC_COMP_ARG_A
428 };
429
430 static GLuint r300_primary_color[] = {
431 R200_TXC_ARG_A_DIFFUSE_COLOR,
432 R200_TXC_ARG_A_DIFFUSE_COLOR | R200_TXC_COMP_ARG_A,
433 R200_TXC_ARG_A_DIFFUSE_ALPHA,
434 R200_TXC_ARG_A_DIFFUSE_ALPHA | R200_TXC_COMP_ARG_A
435 };
436
437 /* GL_ZERO table - indices 0-3
438 * GL_ONE table - indices 1-4
439 */
440 static GLuint r300_zero_color[] = {
441 R200_TXC_ARG_A_ZERO,
442 R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A,
443 R200_TXC_ARG_A_ZERO,
444 R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A,
445 R200_TXC_ARG_A_ZERO
446 };
447
448 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
449 */
450 static GLuint r300_register_alpha[][R200_MAX_TEXTURE_UNITS] = {
451 {
452 R200_TXA_ARG_A_R0_ALPHA,
453 R200_TXA_ARG_A_R1_ALPHA,
454 R200_TXA_ARG_A_R2_ALPHA,
455 R200_TXA_ARG_A_R3_ALPHA,
456 R200_TXA_ARG_A_R4_ALPHA,
457 R200_TXA_ARG_A_R5_ALPHA},
458 {
459 R200_TXA_ARG_A_R0_ALPHA | R200_TXA_COMP_ARG_A,
460 R200_TXA_ARG_A_R1_ALPHA | R200_TXA_COMP_ARG_A,
461 R200_TXA_ARG_A_R2_ALPHA | R200_TXA_COMP_ARG_A,
462 R200_TXA_ARG_A_R3_ALPHA | R200_TXA_COMP_ARG_A,
463 R200_TXA_ARG_A_R4_ALPHA | R200_TXA_COMP_ARG_A,
464 R200_TXA_ARG_A_R5_ALPHA | R200_TXA_COMP_ARG_A},
465 };
466
467 static GLuint r300_tfactor_alpha[] = {
468 R200_TXA_ARG_A_TFACTOR_ALPHA,
469 R200_TXA_ARG_A_TFACTOR_ALPHA | R200_TXA_COMP_ARG_A
470 };
471
472 static GLuint r300_primary_alpha[] = {
473 R200_TXA_ARG_A_DIFFUSE_ALPHA,
474 R200_TXA_ARG_A_DIFFUSE_ALPHA | R200_TXA_COMP_ARG_A
475 };
476
477 /* GL_ZERO table - indices 0-1
478 * GL_ONE table - indices 1-2
479 */
480 static GLuint r300_zero_alpha[] = {
481 R200_TXA_ARG_A_ZERO,
482 R200_TXA_ARG_A_ZERO | R200_TXA_COMP_ARG_A,
483 R200_TXA_ARG_A_ZERO,
484 };
485
486 /* Extract the arg from slot A, shift it into the correct argument slot
487 * and set the corresponding complement bit.
488 */
489 #define R200_COLOR_ARG( n, arg ) \
490 do { \
491 color_combine |= \
492 ((color_arg[n] & R200_TXC_ARG_A_MASK) \
493 << R200_TXC_ARG_##arg##_SHIFT); \
494 color_combine |= \
495 ((color_arg[n] >> R200_TXC_COMP_ARG_A_SHIFT) \
496 << R200_TXC_COMP_ARG_##arg##_SHIFT); \
497 } while (0)
498
499 #define R200_ALPHA_ARG( n, arg ) \
500 do { \
501 alpha_combine |= \
502 ((alpha_arg[n] & R200_TXA_ARG_A_MASK) \
503 << R200_TXA_ARG_##arg##_SHIFT); \
504 alpha_combine |= \
505 ((alpha_arg[n] >> R200_TXA_COMP_ARG_A_SHIFT) \
506 << R200_TXA_COMP_ARG_##arg##_SHIFT); \
507 } while (0)
508
509 /* ================================================================
510 * Texture unit state management
511 */
512
513 static GLboolean r300UpdateTextureEnv(GLcontext * ctx, int unit)
514 {
515 r300ContextPtr rmesa = R300_CONTEXT(ctx);
516 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
517 GLuint color_combine, alpha_combine;
518
519 #if 0 /* disable for now.. */
520 GLuint color_scale = rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2] &
521 ~(R200_TXC_SCALE_MASK);
522 GLuint alpha_scale = rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2] &
523 ~(R200_TXA_DOT_ALPHA | R200_TXA_SCALE_MASK);
524 #endif
525
526 GLuint color_scale=0, alpha_scale=0;
527
528 /* texUnit->_Current can be NULL if and only if the texture unit is
529 * not actually enabled.
530 */
531 assert((texUnit->_ReallyEnabled == 0)
532 || (texUnit->_Current != NULL));
533
534 if (RADEON_DEBUG & DEBUG_TEXTURE) {
535 fprintf(stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx,
536 unit);
537 }
538
539 /* Set the texture environment state. Isn't this nice and clean?
540 * The chip will automagically set the texture alpha to 0xff when
541 * the texture format does not include an alpha component. This
542 * reduces the amount of special-casing we have to do, alpha-only
543 * textures being a notable exception.
544 */
545 /* Don't cache these results.
546 */
547 #if 0
548 rmesa->state.texture.unit[unit].format = 0;
549 #endif
550 rmesa->state.texture.unit[unit].envMode = 0;
551
552
553 if (!texUnit->_ReallyEnabled) {
554 if (unit == 0) {
555 color_combine =
556 R200_TXC_ARG_A_ZERO | R200_TXC_ARG_B_ZERO |
557 R200_TXC_ARG_C_DIFFUSE_COLOR | R200_TXC_OP_MADD;
558 alpha_combine =
559 R200_TXA_ARG_A_ZERO | R200_TXA_ARG_B_ZERO |
560 R200_TXA_ARG_C_DIFFUSE_ALPHA | R200_TXA_OP_MADD;
561 } else {
562 color_combine =
563 R200_TXC_ARG_A_ZERO | R200_TXC_ARG_B_ZERO |
564 R200_TXC_ARG_C_R0_COLOR | R200_TXC_OP_MADD;
565 alpha_combine =
566 R200_TXA_ARG_A_ZERO | R200_TXA_ARG_B_ZERO |
567 R200_TXA_ARG_C_R0_ALPHA | R200_TXA_OP_MADD;
568 }
569 } else {
570 GLuint color_arg[3], alpha_arg[3];
571 GLuint i;
572 const GLuint numColorArgs =
573 texUnit->_CurrentCombine->_NumArgsRGB;
574 const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
575 GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB;
576 GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA;
577
578 /* Step 1:
579 * Extract the color and alpha combine function arguments.
580 */
581 for (i = 0; i < numColorArgs; i++) {
582 const GLint op =
583 texUnit->_CurrentCombine->OperandRGB[i] -
584 GL_SRC_COLOR;
585 assert(op >= 0);
586 assert(op <= 3);
587 switch (texUnit->_CurrentCombine->SourceRGB[i]) {
588 case GL_TEXTURE:
589 color_arg[i] = r300_register_color[op][unit];
590 break;
591 case GL_CONSTANT:
592 color_arg[i] = r300_tfactor_color[op];
593 break;
594 case GL_PRIMARY_COLOR:
595 color_arg[i] = r300_primary_color[op];
596 break;
597 case GL_PREVIOUS:
598 if (unit == 0)
599 color_arg[i] = r300_primary_color[op];
600 else
601 color_arg[i] =
602 r300_register_color[op][0];
603 break;
604 case GL_ZERO:
605 color_arg[i] = r300_zero_color[op];
606 break;
607 case GL_ONE:
608 color_arg[i] = r300_zero_color[op + 1];
609 break;
610 default:
611 return GL_FALSE;
612 }
613 }
614
615 for (i = 0; i < numAlphaArgs; i++) {
616 const GLint op =
617 texUnit->_CurrentCombine->OperandA[i] -
618 GL_SRC_ALPHA;
619 assert(op >= 0);
620 assert(op <= 1);
621 switch (texUnit->_CurrentCombine->SourceA[i]) {
622 case GL_TEXTURE:
623 alpha_arg[i] = r300_register_alpha[op][unit];
624 break;
625 case GL_CONSTANT:
626 alpha_arg[i] = r300_tfactor_alpha[op];
627 break;
628 case GL_PRIMARY_COLOR:
629 alpha_arg[i] = r300_primary_alpha[op];
630 break;
631 case GL_PREVIOUS:
632 if (unit == 0)
633 alpha_arg[i] = r300_primary_alpha[op];
634 else
635 alpha_arg[i] =
636 r300_register_alpha[op][0];
637 break;
638 case GL_ZERO:
639 alpha_arg[i] = r300_zero_alpha[op];
640 break;
641 case GL_ONE:
642 alpha_arg[i] = r300_zero_alpha[op + 1];
643 break;
644 default:
645 return GL_FALSE;
646 }
647 }
648
649 /* Step 2:
650 * Build up the color and alpha combine functions.
651 */
652 switch (texUnit->_CurrentCombine->ModeRGB) {
653 case GL_REPLACE:
654 color_combine = (R200_TXC_ARG_A_ZERO |
655 R200_TXC_ARG_B_ZERO |
656 R200_TXC_OP_MADD);
657 R200_COLOR_ARG(0, C);
658 break;
659 case GL_MODULATE:
660 color_combine = (R200_TXC_ARG_C_ZERO |
661 R200_TXC_OP_MADD);
662 R200_COLOR_ARG(0, A);
663 R200_COLOR_ARG(1, B);
664 break;
665 case GL_ADD:
666 color_combine = (R200_TXC_ARG_B_ZERO |
667 R200_TXC_COMP_ARG_B |
668 R200_TXC_OP_MADD);
669 R200_COLOR_ARG(0, A);
670 R200_COLOR_ARG(1, C);
671 break;
672 case GL_ADD_SIGNED:
673 color_combine = (R200_TXC_ARG_B_ZERO | R200_TXC_COMP_ARG_B | R200_TXC_BIAS_ARG_C | /* new */
674 R200_TXC_OP_MADD); /* was ADDSIGNED */
675 R200_COLOR_ARG(0, A);
676 R200_COLOR_ARG(1, C);
677 break;
678 case GL_SUBTRACT:
679 color_combine = (R200_TXC_ARG_B_ZERO |
680 R200_TXC_COMP_ARG_B |
681 R200_TXC_NEG_ARG_C | R200_TXC_OP_MADD);
682 R200_COLOR_ARG(0, A);
683 R200_COLOR_ARG(1, C);
684 break;
685 case GL_INTERPOLATE:
686 color_combine = (R200_TXC_OP_LERP);
687 R200_COLOR_ARG(0, B);
688 R200_COLOR_ARG(1, A);
689 R200_COLOR_ARG(2, C);
690 break;
691
692 case GL_DOT3_RGB_EXT:
693 case GL_DOT3_RGBA_EXT:
694 /* The EXT version of the DOT3 extension does not support the
695 * scale factor, but the ARB version (and the version in OpenGL
696 * 1.3) does.
697 */
698 RGBshift = 0;
699 /* FALLTHROUGH */
700
701 case GL_DOT3_RGB:
702 case GL_DOT3_RGBA:
703 /* DOT3 works differently on R200 than on R100. On R100, just
704 * setting the DOT3 mode did everything for you. On R200, the
705 * driver has to enable the biasing and scale in the inputs to
706 * put them in the proper [-1,1] range. This is what the 4x and
707 * the -0.5 in the DOT3 spec do. The post-scale is then set
708 * normally.
709 */
710
711 color_combine = (R200_TXC_ARG_C_ZERO |
712 R200_TXC_OP_DOT3 |
713 R200_TXC_BIAS_ARG_A |
714 R200_TXC_BIAS_ARG_B |
715 R200_TXC_SCALE_ARG_A |
716 R200_TXC_SCALE_ARG_B);
717 R200_COLOR_ARG(0, A);
718 R200_COLOR_ARG(1, B);
719 break;
720
721 case GL_MODULATE_ADD_ATI:
722 color_combine = (R200_TXC_OP_MADD);
723 R200_COLOR_ARG(0, A);
724 R200_COLOR_ARG(1, C);
725 R200_COLOR_ARG(2, B);
726 break;
727 case GL_MODULATE_SIGNED_ADD_ATI:
728 color_combine = (R200_TXC_BIAS_ARG_C | /* new */
729 R200_TXC_OP_MADD); /* was ADDSIGNED */
730 R200_COLOR_ARG(0, A);
731 R200_COLOR_ARG(1, C);
732 R200_COLOR_ARG(2, B);
733 break;
734 case GL_MODULATE_SUBTRACT_ATI:
735 color_combine = (R200_TXC_NEG_ARG_C | R200_TXC_OP_MADD);
736 R200_COLOR_ARG(0, A);
737 R200_COLOR_ARG(1, C);
738 R200_COLOR_ARG(2, B);
739 break;
740 default:
741 return GL_FALSE;
742 }
743
744 switch (texUnit->_CurrentCombine->ModeA) {
745 case GL_REPLACE:
746 alpha_combine = (R200_TXA_ARG_A_ZERO |
747 R200_TXA_ARG_B_ZERO |
748 R200_TXA_OP_MADD);
749 R200_ALPHA_ARG(0, C);
750 break;
751 case GL_MODULATE:
752 alpha_combine = (R200_TXA_ARG_C_ZERO |
753 R200_TXA_OP_MADD);
754 R200_ALPHA_ARG(0, A);
755 R200_ALPHA_ARG(1, B);
756 break;
757 case GL_ADD:
758 alpha_combine = (R200_TXA_ARG_B_ZERO |
759 R200_TXA_COMP_ARG_B |
760 R200_TXA_OP_MADD);
761 R200_ALPHA_ARG(0, A);
762 R200_ALPHA_ARG(1, C);
763 break;
764 case GL_ADD_SIGNED:
765 alpha_combine = (R200_TXA_ARG_B_ZERO | R200_TXA_COMP_ARG_B | R200_TXA_BIAS_ARG_C | /* new */
766 R200_TXA_OP_MADD); /* was ADDSIGNED */
767 R200_ALPHA_ARG(0, A);
768 R200_ALPHA_ARG(1, C);
769 break;
770 case GL_SUBTRACT:
771 alpha_combine = (R200_TXA_ARG_B_ZERO |
772 R200_TXA_COMP_ARG_B |
773 R200_TXA_NEG_ARG_C | R200_TXA_OP_MADD);
774 R200_ALPHA_ARG(0, A);
775 R200_ALPHA_ARG(1, C);
776 break;
777 case GL_INTERPOLATE:
778 alpha_combine = (R200_TXA_OP_LERP);
779 R200_ALPHA_ARG(0, B);
780 R200_ALPHA_ARG(1, A);
781 R200_ALPHA_ARG(2, C);
782 break;
783
784 case GL_MODULATE_ADD_ATI:
785 alpha_combine = (R200_TXA_OP_MADD);
786 R200_ALPHA_ARG(0, A);
787 R200_ALPHA_ARG(1, C);
788 R200_ALPHA_ARG(2, B);
789 break;
790 case GL_MODULATE_SIGNED_ADD_ATI:
791 alpha_combine = (R200_TXA_BIAS_ARG_C | /* new */
792 R200_TXA_OP_MADD); /* was ADDSIGNED */
793 R200_ALPHA_ARG(0, A);
794 R200_ALPHA_ARG(1, C);
795 R200_ALPHA_ARG(2, B);
796 break;
797 case GL_MODULATE_SUBTRACT_ATI:
798 alpha_combine = (R200_TXA_NEG_ARG_C | R200_TXA_OP_MADD);
799 R200_ALPHA_ARG(0, A);
800 R200_ALPHA_ARG(1, C);
801 R200_ALPHA_ARG(2, B);
802 break;
803 default:
804 return GL_FALSE;
805 }
806
807 if ((texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT)
808 || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA)) {
809 alpha_scale |= R200_TXA_DOT_ALPHA;
810 Ashift = RGBshift;
811 }
812
813 /* Step 3:
814 * Apply the scale factor.
815 */
816 color_scale |= (RGBshift << R200_TXC_SCALE_SHIFT);
817 alpha_scale |= (Ashift << R200_TXA_SCALE_SHIFT);
818
819 /* All done!
820 */
821 }
822
823 #if 0
824 fprintf(stderr, "color_combine=%08x alpha_combine=%08x color_scale=%08x alpha_scale=%08x\n",
825 color_combine, alpha_combine, color_scale, alpha_scale);
826 #endif
827
828 #if 0
829 if (rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND] != color_combine ||
830 rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND] != alpha_combine ||
831 rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2] != color_scale ||
832 rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2] != alpha_scale) {
833 R300_STATECHANGE(rmesa, pix[unit]);
834 rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND] = color_combine;
835 rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND] = alpha_combine;
836 rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2] = color_scale;
837 rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2] = alpha_scale;
838 }
839
840 #endif
841
842 return GL_TRUE;
843 }
844
845 #define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK | \
846 R200_MIN_FILTER_MASK | \
847 R200_MAG_FILTER_MASK | \
848 R200_MAX_ANISO_MASK | \
849 R200_YUV_TO_RGB | \
850 R200_YUV_TEMPERATURE_MASK | \
851 R200_CLAMP_S_MASK | \
852 R200_CLAMP_T_MASK | \
853 R200_BORDER_MODE_D3D )
854
855 #define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK | \
856 R200_TXFORMAT_HEIGHT_MASK | \
857 R200_TXFORMAT_FORMAT_MASK | \
858 R200_TXFORMAT_F5_WIDTH_MASK | \
859 R200_TXFORMAT_F5_HEIGHT_MASK | \
860 R200_TXFORMAT_ALPHA_IN_MAP | \
861 R200_TXFORMAT_CUBIC_MAP_ENABLE | \
862 R200_TXFORMAT_NON_POWER2)
863
864 #define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK | \
865 R200_TEXCOORD_MASK | \
866 R200_CLAMP_Q_MASK | \
867 R200_VOLUME_FILTER_MASK)
868
869 static void disable_tex(GLcontext * ctx, int unit)
870 {
871 #if 0 /* This needs to be redone.. or done elsewhere */
872 r300ContextPtr rmesa = R300_CONTEXT(ctx);
873
874 if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE << unit)) {
875 /* Texture unit disabled */
876 if (rmesa->state.texture.unit[unit].texobj != NULL) {
877 /* The old texture is no longer bound to this texture unit.
878 * Mark it as such.
879 */
880
881 rmesa->state.texture.unit[unit].texobj->base.bound &=
882 ~(1UL << unit);
883 rmesa->state.texture.unit[unit].texobj = NULL;
884 }
885
886 R300_STATECHANGE(rmesa, ctx);
887 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~((R200_TEX_0_ENABLE |
888 R200_TEX_BLEND_0_ENABLE) <<
889 unit);
890 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_BLEND_0_ENABLE;
891
892 R300_STATECHANGE(rmesa, tcl);
893 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &=
894 ~(7 << (unit * 3));
895
896 if (rmesa->radeon.TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0 << unit)) {
897 TCL_FALLBACK(ctx, (RADEON_TCL_FALLBACK_TEXGEN_0 << unit),
898 GL_FALSE);
899 }
900
901 /* Actually want to keep all units less than max active texture
902 * enabled, right? Fix this for >2 texunits.
903 */
904 /* FIXME: What should happen here if r300UpdateTextureEnv fails? */
905 if (unit == 0)
906 r300UpdateTextureEnv(ctx, unit);
907
908 {
909 GLuint inputshift =
910 R200_TEXGEN_0_INPUT_SHIFT + unit * 4;
911 GLuint tmp = rmesa->TexGenEnabled;
912
913 rmesa->TexGenEnabled &=
914 ~(R200_TEXGEN_TEXMAT_0_ENABLE << unit);
915 rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE << unit);
916 rmesa->TexGenEnabled &=
917 ~(R200_TEXGEN_INPUT_MASK << inputshift);
918 rmesa->TexGenNeedNormals[unit] = 0;
919 rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
920 rmesa->TexGenInputs &=
921 ~(R200_TEXGEN_INPUT_MASK << inputshift);
922
923 if (tmp != rmesa->TexGenEnabled) {
924 rmesa->recheck_texgen[unit] = GL_TRUE;
925 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
926 }
927 }
928 }
929 #endif
930 }
931
932 static GLboolean enable_tex_2d(GLcontext * ctx, int unit)
933 {
934 r300ContextPtr rmesa = R300_CONTEXT(ctx);
935 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
936 struct gl_texture_object *tObj = texUnit->_Current;
937 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
938
939 /* Need to load the 2d images associated with this unit.
940 */
941 #if 0
942 if (t->format & R200_TXFORMAT_NON_POWER2) {
943 t->format &= ~R200_TXFORMAT_NON_POWER2;
944 t->base.dirty_images[0] = ~0;
945 }
946 #endif
947
948 ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D);
949
950 if (t->base.dirty_images[0]) {
951 R300_FIREVERTICES(rmesa);
952 r300SetTexImages(rmesa, tObj);
953 r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
954 if (!t->base.memBlock)
955 return GL_FALSE;
956 }
957
958 return GL_TRUE;
959 }
960
961 #if ENABLE_HW_3D_TEXTURE
962 static GLboolean enable_tex_3d(GLcontext * ctx, int unit)
963 {
964 r300ContextPtr rmesa = R300_CONTEXT(ctx);
965 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
966 struct gl_texture_object *tObj = texUnit->_Current;
967 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
968
969 /* Need to load the 3d images associated with this unit.
970 */
971 if (t->format & R200_TXFORMAT_NON_POWER2) {
972 t->format &= ~R200_TXFORMAT_NON_POWER2;
973 t->base.dirty_images[0] = ~0;
974 }
975
976 ASSERT(tObj->Target == GL_TEXTURE_3D);
977
978 /* R100 & R200 do not support mipmaps for 3D textures.
979 */
980 if ((tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) {
981 return GL_FALSE;
982 }
983
984 if (t->base.dirty_images[0]) {
985 R300_FIREVERTICES(rmesa);
986 r300SetTexImages(rmesa, tObj);
987 r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
988 if (!t->base.memBlock)
989 return GL_FALSE;
990 }
991
992 return GL_TRUE;
993 }
994 #endif
995
996 static GLboolean enable_tex_cube(GLcontext * ctx, int unit)
997 {
998 r300ContextPtr rmesa = R300_CONTEXT(ctx);
999 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1000 struct gl_texture_object *tObj = texUnit->_Current;
1001 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
1002 GLuint face;
1003
1004 /* Need to load the 2d images associated with this unit.
1005 */
1006 if (t->format & R200_TXFORMAT_NON_POWER2) {
1007 t->format &= ~R200_TXFORMAT_NON_POWER2;
1008 for (face = 0; face < 6; face++)
1009 t->base.dirty_images[face] = ~0;
1010 }
1011
1012 ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP);
1013
1014 if (t->base.dirty_images[0] || t->base.dirty_images[1] ||
1015 t->base.dirty_images[2] || t->base.dirty_images[3] ||
1016 t->base.dirty_images[4] || t->base.dirty_images[5]) {
1017 /* flush */
1018 R300_FIREVERTICES(rmesa);
1019 /* layout memory space, once for all faces */
1020 r300SetTexImages(rmesa, tObj);
1021 }
1022
1023 /* upload (per face) */
1024 for (face = 0; face < 6; face++) {
1025 if (t->base.dirty_images[face]) {
1026 r300UploadTexImages(rmesa,
1027 (r300TexObjPtr) tObj->DriverData,
1028 face);
1029 }
1030 }
1031
1032 if (!t->base.memBlock) {
1033 /* texmem alloc failed, use s/w fallback */
1034 return GL_FALSE;
1035 }
1036
1037 return GL_TRUE;
1038 }
1039
1040 static GLboolean enable_tex_rect(GLcontext * ctx, int unit)
1041 {
1042 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1043 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1044 struct gl_texture_object *tObj = texUnit->_Current;
1045 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
1046
1047 #if 0
1048 if (!(t->format & R200_TXFORMAT_NON_POWER2)) {
1049 t->format |= R200_TXFORMAT_NON_POWER2;
1050 t->base.dirty_images[0] = ~0;
1051 }
1052 #endif
1053
1054 ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);
1055
1056 if (t->base.dirty_images[0]) {
1057 R300_FIREVERTICES(rmesa);
1058 r300SetTexImages(rmesa, tObj);
1059 r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
1060 if (!t->base.memBlock && !rmesa->prefer_gart_client_texturing)
1061 return GL_FALSE;
1062 }
1063
1064 return GL_TRUE;
1065 }
1066
1067 static GLboolean update_tex_common(GLcontext * ctx, int unit)
1068 {
1069 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1070 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1071 struct gl_texture_object *tObj = texUnit->_Current;
1072 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
1073 GLenum format;
1074
1075 /* Fallback if there's a texture border */
1076 if (tObj->Image[0][tObj->BaseLevel]->Border > 0)
1077 return GL_FALSE;
1078
1079 /* Update state if this is a different texture object to last
1080 * time.
1081 */
1082 if (rmesa->state.texture.unit[unit].texobj != t) {
1083 if (rmesa->state.texture.unit[unit].texobj != NULL) {
1084 /* The old texture is no longer bound to this texture unit.
1085 * Mark it as such.
1086 */
1087
1088 rmesa->state.texture.unit[unit].texobj->base.bound &=
1089 ~(1UL << unit);
1090 }
1091
1092 rmesa->state.texture.unit[unit].texobj = t;
1093 t->base.bound |= (1UL << unit);
1094 t->dirty_state |= 1 << unit;
1095 driUpdateTextureLRU((driTextureObject *) t); /* XXX: should be locked! */
1096 }
1097
1098 #if 0 /* do elsewhere ? */
1099 /* Newly enabled?
1100 */
1101 if (1
1102 || !(rmesa->hw.ctx.
1103 cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE << unit))) {
1104 R300_STATECHANGE(rmesa, ctx);
1105 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_0_ENABLE |
1106 R200_TEX_BLEND_0_ENABLE) <<
1107 unit;
1108
1109 R300_STATECHANGE(rmesa, vtx);
1110 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3);
1111
1112 rmesa->recheck_texgen[unit] = GL_TRUE;
1113 }
1114
1115 if (t->dirty_state & (1 << unit)) {
1116 import_tex_obj_state(rmesa, unit, t);
1117 }
1118
1119 if (rmesa->recheck_texgen[unit]) {
1120 GLboolean fallback = !r300_validate_texgen(ctx, unit);
1121 TCL_FALLBACK(ctx, (RADEON_TCL_FALLBACK_TEXGEN_0 << unit),
1122 fallback);
1123 rmesa->recheck_texgen[unit] = 0;
1124 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
1125 }
1126 #endif
1127
1128 format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
1129 if (rmesa->state.texture.unit[unit].format != format ||
1130 rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode) {
1131 //rmesa->state.texture.unit[unit].format = format;
1132 rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode;
1133 if (!r300UpdateTextureEnv(ctx, unit)) {
1134 return GL_FALSE;
1135 }
1136 }
1137
1138 #if R200_MERGED
1139 FALLBACK(&rmesa->radeon, RADEON_FALLBACK_BORDER_MODE, t->border_fallback);
1140 #endif
1141
1142 return !t->border_fallback;
1143 }
1144
1145 static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit)
1146 {
1147 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1148
1149 if (texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT)) {
1150 return (enable_tex_rect(ctx, unit) &&
1151 update_tex_common(ctx, unit));
1152 } else if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) {
1153 return (enable_tex_2d(ctx, unit) &&
1154 update_tex_common(ctx, unit));
1155 }
1156 #if ENABLE_HW_3D_TEXTURE
1157 else if (texUnit->_ReallyEnabled & (TEXTURE_3D_BIT)) {
1158 return (enable_tex_3d(ctx, unit) &&
1159 update_tex_common(ctx, unit));
1160 }
1161 #endif
1162 else if (texUnit->_ReallyEnabled & (TEXTURE_CUBE_BIT)) {
1163 return (enable_tex_cube(ctx, unit) &&
1164 update_tex_common(ctx, unit));
1165 } else if (texUnit->_ReallyEnabled) {
1166 return GL_FALSE;
1167 } else {
1168 disable_tex(ctx, unit);
1169 return GL_TRUE;
1170 }
1171 }
1172
1173 void r300UpdateTextureState(GLcontext * ctx)
1174 {
1175 #if 0
1176 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1177 GLuint dbg;
1178 int i;
1179 #endif
1180 GLboolean ok;
1181
1182 ok = (r300UpdateTextureUnit(ctx, 0) &&
1183 r300UpdateTextureUnit(ctx, 1) &&
1184 r300UpdateTextureUnit(ctx, 2) &&
1185 r300UpdateTextureUnit(ctx, 3) &&
1186 r300UpdateTextureUnit(ctx, 4) &&
1187 r300UpdateTextureUnit(ctx, 5) &&
1188 r300UpdateTextureUnit(ctx, 6) &&
1189 r300UpdateTextureUnit(ctx, 7)
1190 );
1191
1192 #if R200_MERGED
1193 FALLBACK(&rmesa->radeon, RADEON_FALLBACK_TEXTURE, !ok);
1194 #endif
1195
1196 /* This needs correction, or just be done elsewhere
1197 if (rmesa->radeon.TclFallback)
1198 r300ChooseVertexState(ctx);
1199 */
1200
1201 #if 0 /* Workaround - disable.. */
1202 if (GET_CHIP(rmesa->radeon.radeonScreen) == RADEON_CHIP_REAL_R200) {
1203 /*
1204 * T0 hang workaround -------------
1205 * not needed for r200 derivatives?
1206 */
1207 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_ENABLE_MASK) ==
1208 R200_TEX_0_ENABLE
1209 && (rmesa->hw.tex[0].
1210 cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) >
1211 R200_MIN_FILTER_LINEAR) {
1212
1213 R300_STATECHANGE(rmesa, ctx);
1214 R300_STATECHANGE(rmesa, tex[1]);
1215 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_1_ENABLE;
1216 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &=
1217 ~TEXOBJ_TXFORMAT_MASK;
1218 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] |= 0x08000000;
1219 } else {
1220 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE)
1221 && (rmesa->hw.tex[1].
1222 cmd[TEX_PP_TXFORMAT] & 0x08000000)) {
1223 R300_STATECHANGE(rmesa, tex[1]);
1224 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &=
1225 ~0x08000000;
1226 }
1227 }
1228
1229 /* maybe needs to be done pairwise due to 2 parallel (physical) tex units ?
1230 looks like that's not the case, if 8500/9100 owners don't complain remove this...
1231 for ( i = 0; i < ctx->Const.MaxTextureUnits; i += 2) {
1232 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & ((R200_TEX_0_ENABLE |
1233 R200_TEX_1_ENABLE ) << i)) == (R200_TEX_0_ENABLE << i)) &&
1234 ((rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) >
1235 R200_MIN_FILTER_LINEAR)) {
1236 R300_STATECHANGE(rmesa, ctx);
1237 R300_STATECHANGE(rmesa, tex[i+1]);
1238 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_1_ENABLE << i);
1239 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1240 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] |= 0x08000000;
1241 }
1242 else {
1243 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE << i)) &&
1244 (rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) {
1245 R300_STATECHANGE(rmesa, tex[i+1]);
1246 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000;
1247 }
1248 }
1249 } */
1250
1251 /*
1252 * Texture cache LRU hang workaround -------------
1253 * not needed for r200 derivatives?
1254 */
1255 dbg = 0x0;
1256
1257 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE)) &&
1258 ((((rmesa->hw.tex[0].
1259 cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04)
1260 == 0))
1261 || ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_2_ENABLE)
1262 &&
1263 ((((rmesa->hw.tex[2].
1264 cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1265 0x04) == 0))
1266 || ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_4_ENABLE)
1267 &&
1268 ((((rmesa->hw.tex[4].
1269 cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1270 0x04) == 0))) {
1271 dbg |= 0x02;
1272 }
1273
1274 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE)) &&
1275 ((((rmesa->hw.tex[1].
1276 cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04)
1277 == 0))
1278 || ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_3_ENABLE)
1279 &&
1280 ((((rmesa->hw.tex[3].
1281 cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1282 0x04) == 0))
1283 || ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_5_ENABLE)
1284 &&
1285 ((((rmesa->hw.tex[5].
1286 cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1287 0x04) == 0))) {
1288 dbg |= 0x04;
1289 }
1290
1291 if (dbg != rmesa->hw.tam.cmd[TAM_DEBUG3]) {
1292 R300_STATECHANGE(rmesa, tam);
1293 rmesa->hw.tam.cmd[TAM_DEBUG3] = dbg;
1294 if (0)
1295 printf("TEXCACHE LRU HANG WORKAROUND %x\n",
1296 dbg);
1297 }
1298 }
1299 #endif
1300 }