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