1 /* $XFree86: xc/lib/GL/mesa/src/drv/r300/r300_texstate.c,v 1.3 2003/02/15 22:18:47 dawes Exp $ */
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
5 The Weather Channel (TM) funded Tungsten Graphics to develop the
6 initial release of the Radeon 8500 driver under the XFree86 license.
7 This notice must be preserved.
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial
19 portions of the Software.
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
33 * Keith Whitwell <keith@tungstengraphics.com>
40 #include "texformat.h"
43 #include "r300_context.h"
44 #include "r300_state.h"
45 #include "radeon_ioctl.h"
46 //#include "r300_swtcl.h"
48 //#include "r300_tcl.h"
50 #define R200_TXFORMAT_A8 R200_TXFORMAT_I8
51 #define R200_TXFORMAT_L8 R200_TXFORMAT_I8
52 #define R200_TXFORMAT_AL88 R200_TXFORMAT_AI88
53 #define R200_TXFORMAT_YCBCR R200_TXFORMAT_YVYU422
54 #define R200_TXFORMAT_YCBCR_REV R200_TXFORMAT_VYUY422
57 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, 0 }
58 #define _COLOR_REV(f) \
59 [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f, 0 }
61 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
62 #define _ALPHA_REV(f) \
63 [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
65 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, R200_YUV_TO_RGB }
67 [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
68 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_YCBCR_REV) \
69 && (tx_table[f].format != 0xffffffff) )
72 GLuint format
, filter
;
89 _ALPHA(I8
), _INVALID(CI8
), _YUV(YCBCR
), _YUV(YCBCR_REV
),};
96 * This function computes the number of bytes of storage needed for
97 * the given texture object (all mipmap levels, all cube faces).
98 * The \c image[face][level].x/y/width/height parameters for upload/blitting
99 * are computed here. \c filter, \c format, etc. will be set here
102 * \param rmesa Context pointer
103 * \param tObj GL texture object whose images are to be posted to
106 static void r300SetTexImages(r300ContextPtr rmesa
,
107 struct gl_texture_object
*tObj
)
109 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
110 const struct gl_texture_image
*baseImage
=
111 tObj
->Image
[0][tObj
->BaseLevel
];
115 GLint log2Width
, log2Height
, log2Depth
;
117 /* Set the hardware texture format
120 t
->format
&= ~(R200_TXFORMAT_FORMAT_MASK
|
121 R200_TXFORMAT_ALPHA_IN_MAP
);
122 t
->filter
&= ~R200_YUV_TO_RGB
;
124 if (VALID_FORMAT(baseImage
->TexFormat
->MesaFormat
)) {
126 tx_table
[baseImage
->TexFormat
->MesaFormat
].format
;
128 tx_table
[baseImage
->TexFormat
->MesaFormat
].filter
;
130 _mesa_problem(NULL
, "unexpected texture format in %s",
135 /* Compute which mipmap levels we really want to send to the hardware.
138 driCalculateTextureFirstLastLevel((driTextureObject
*) t
);
139 log2Width
= tObj
->Image
[0][t
->base
.firstLevel
]->WidthLog2
;
140 log2Height
= tObj
->Image
[0][t
->base
.firstLevel
]->HeightLog2
;
141 log2Depth
= tObj
->Image
[0][t
->base
.firstLevel
]->DepthLog2
;
143 numLevels
= t
->base
.lastLevel
- t
->base
.firstLevel
+ 1;
145 assert(numLevels
<= RADEON_MAX_TEXTURE_LEVELS
);
147 /* Calculate mipmap offsets and dimensions for blitting (uploading)
148 * The idea is that we lay out the mipmap levels within a block of
149 * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
153 for (i
= 0; i
< numLevels
; i
++) {
154 const struct gl_texture_image
*texImage
;
157 texImage
= tObj
->Image
[0][i
+ t
->base
.firstLevel
];
161 /* find image size in bytes */
162 if (texImage
->IsCompressed
) {
163 size
= texImage
->CompressedSize
;
164 } else if (tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
) {
167 texImage
->TexFormat
->TexelBytes
+ 63)
168 & ~63) * texImage
->Height
;
171 texImage
->Width
* texImage
->TexFormat
->TexelBytes
;
174 size
= w
* texImage
->Height
* texImage
->Depth
;
178 /* Align to 32-byte offset. It is faster to do this unconditionally
179 * (no branch penalty).
182 curOffset
= (curOffset
+ 0x1f) & ~0x1f;
184 t
->image
[0][i
].x
= curOffset
% BLIT_WIDTH_BYTES
;
185 t
->image
[0][i
].y
= curOffset
/ BLIT_WIDTH_BYTES
;
186 t
->image
[0][i
].width
= MIN2(size
, BLIT_WIDTH_BYTES
);
187 t
->image
[0][i
].height
= size
/ t
->image
[0][i
].width
;
190 /* for debugging only and only applicable to non-rectangle targets */
191 assert(size
% t
->image
[0][i
].width
== 0);
192 assert(t
->image
[0][i
].x
== 0
193 || (size
< BLIT_WIDTH_BYTES
194 && t
->image
[0][i
].height
== 1));
199 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
200 i
, texImage
->Width
, texImage
->Height
,
201 t
->image
[0][i
].x
, t
->image
[0][i
].y
,
202 t
->image
[0][i
].width
, t
->image
[0][i
].height
,
209 /* Align the total size of texture memory block.
212 (curOffset
+ RADEON_OFFSET_MASK
) & ~RADEON_OFFSET_MASK
;
214 /* Setup remaining cube face blits, if needed */
215 if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
216 /* Round totalSize up to multiple of BLIT_WIDTH_BYTES */
217 const GLuint faceSize
=
218 (t
->base
.totalSize
+ BLIT_WIDTH_BYTES
- 1)
219 & ~(BLIT_WIDTH_BYTES
- 1);
220 const GLuint lines
= faceSize
/ BLIT_WIDTH_BYTES
;
222 /* reuse face 0 x/y/width/height - just adjust y */
223 for (face
= 1; face
< 6; face
++) {
224 for (i
= 0; i
< numLevels
; i
++) {
225 t
->image
[face
][i
].x
= t
->image
[0][i
].x
;
226 t
->image
[face
][i
].y
=
227 t
->image
[0][i
].y
+ face
* lines
;
228 t
->image
[face
][i
].width
= t
->image
[0][i
].width
;
229 t
->image
[face
][i
].height
=
230 t
->image
[0][i
].height
;
233 t
->base
.totalSize
= 6 * faceSize
; /* total texmem needed */
238 t
->filter
&= ~R200_MAX_MIP_LEVEL_MASK
;
239 t
->filter
|= (numLevels
- 1) << R200_MAX_MIP_LEVEL_SHIFT
;
241 t
->format
&= ~(R200_TXFORMAT_WIDTH_MASK
|
242 R200_TXFORMAT_HEIGHT_MASK
|
243 R200_TXFORMAT_CUBIC_MAP_ENABLE
|
244 R200_TXFORMAT_F5_WIDTH_MASK
|
245 R200_TXFORMAT_F5_HEIGHT_MASK
);
246 t
->format
|= ((log2Width
<< R200_TXFORMAT_WIDTH_SHIFT
) |
247 (log2Height
<< R200_TXFORMAT_HEIGHT_SHIFT
));
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
));
271 t
->size
= (((tObj
->Image
[0][t
->base
.firstLevel
]->Width
- 1) << 0) |
272 ((tObj
->Image
[0][t
->base
.firstLevel
]->Height
-
275 /* Only need to round to nearest 32 for textures, but the blitter
276 * requires 64-byte aligned pitches, and we may/may not need the
277 * blitter. NPOT only!
279 if (baseImage
->IsCompressed
)
281 (tObj
->Image
[0][t
->base
.firstLevel
]->Width
+ 63) & ~(63);
284 ((tObj
->Image
[0][t
->base
.firstLevel
]->Width
*
285 baseImage
->TexFormat
->TexelBytes
) + 63) & ~(63);
288 t
->dirty_state
= TEX_ALL
;
290 /* FYI: r300UploadTexImages( rmesa, t ) used to be called here */
293 /* ================================================================
294 * Texture combine functions
297 /* GL_ARB_texture_env_combine support
300 /* The color tables have combine functions for GL_SRC_COLOR,
301 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
303 static GLuint r300_register_color
[][R200_MAX_TEXTURE_UNITS
] = {
305 R200_TXC_ARG_A_R0_COLOR
,
306 R200_TXC_ARG_A_R1_COLOR
,
307 R200_TXC_ARG_A_R2_COLOR
,
308 R200_TXC_ARG_A_R3_COLOR
,
309 R200_TXC_ARG_A_R4_COLOR
,
310 R200_TXC_ARG_A_R5_COLOR
},
312 R200_TXC_ARG_A_R0_COLOR
| R200_TXC_COMP_ARG_A
,
313 R200_TXC_ARG_A_R1_COLOR
| R200_TXC_COMP_ARG_A
,
314 R200_TXC_ARG_A_R2_COLOR
| R200_TXC_COMP_ARG_A
,
315 R200_TXC_ARG_A_R3_COLOR
| R200_TXC_COMP_ARG_A
,
316 R200_TXC_ARG_A_R4_COLOR
| R200_TXC_COMP_ARG_A
,
317 R200_TXC_ARG_A_R5_COLOR
| R200_TXC_COMP_ARG_A
},
319 R200_TXC_ARG_A_R0_ALPHA
,
320 R200_TXC_ARG_A_R1_ALPHA
,
321 R200_TXC_ARG_A_R2_ALPHA
,
322 R200_TXC_ARG_A_R3_ALPHA
,
323 R200_TXC_ARG_A_R4_ALPHA
,
324 R200_TXC_ARG_A_R5_ALPHA
},
326 R200_TXC_ARG_A_R0_ALPHA
| R200_TXC_COMP_ARG_A
,
327 R200_TXC_ARG_A_R1_ALPHA
| R200_TXC_COMP_ARG_A
,
328 R200_TXC_ARG_A_R2_ALPHA
| R200_TXC_COMP_ARG_A
,
329 R200_TXC_ARG_A_R3_ALPHA
| R200_TXC_COMP_ARG_A
,
330 R200_TXC_ARG_A_R4_ALPHA
| R200_TXC_COMP_ARG_A
,
331 R200_TXC_ARG_A_R5_ALPHA
| R200_TXC_COMP_ARG_A
},
334 static GLuint r300_tfactor_color
[] = {
335 R200_TXC_ARG_A_TFACTOR_COLOR
,
336 R200_TXC_ARG_A_TFACTOR_COLOR
| R200_TXC_COMP_ARG_A
,
337 R200_TXC_ARG_A_TFACTOR_ALPHA
,
338 R200_TXC_ARG_A_TFACTOR_ALPHA
| R200_TXC_COMP_ARG_A
341 static GLuint r300_primary_color
[] = {
342 R200_TXC_ARG_A_DIFFUSE_COLOR
,
343 R200_TXC_ARG_A_DIFFUSE_COLOR
| R200_TXC_COMP_ARG_A
,
344 R200_TXC_ARG_A_DIFFUSE_ALPHA
,
345 R200_TXC_ARG_A_DIFFUSE_ALPHA
| R200_TXC_COMP_ARG_A
348 /* GL_ZERO table - indices 0-3
349 * GL_ONE table - indices 1-4
351 static GLuint r300_zero_color
[] = {
353 R200_TXC_ARG_A_ZERO
| R200_TXC_COMP_ARG_A
,
355 R200_TXC_ARG_A_ZERO
| R200_TXC_COMP_ARG_A
,
359 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
361 static GLuint r300_register_alpha
[][R200_MAX_TEXTURE_UNITS
] = {
363 R200_TXA_ARG_A_R0_ALPHA
,
364 R200_TXA_ARG_A_R1_ALPHA
,
365 R200_TXA_ARG_A_R2_ALPHA
,
366 R200_TXA_ARG_A_R3_ALPHA
,
367 R200_TXA_ARG_A_R4_ALPHA
,
368 R200_TXA_ARG_A_R5_ALPHA
},
370 R200_TXA_ARG_A_R0_ALPHA
| R200_TXA_COMP_ARG_A
,
371 R200_TXA_ARG_A_R1_ALPHA
| R200_TXA_COMP_ARG_A
,
372 R200_TXA_ARG_A_R2_ALPHA
| R200_TXA_COMP_ARG_A
,
373 R200_TXA_ARG_A_R3_ALPHA
| R200_TXA_COMP_ARG_A
,
374 R200_TXA_ARG_A_R4_ALPHA
| R200_TXA_COMP_ARG_A
,
375 R200_TXA_ARG_A_R5_ALPHA
| R200_TXA_COMP_ARG_A
},
378 static GLuint r300_tfactor_alpha
[] = {
379 R200_TXA_ARG_A_TFACTOR_ALPHA
,
380 R200_TXA_ARG_A_TFACTOR_ALPHA
| R200_TXA_COMP_ARG_A
383 static GLuint r300_primary_alpha
[] = {
384 R200_TXA_ARG_A_DIFFUSE_ALPHA
,
385 R200_TXA_ARG_A_DIFFUSE_ALPHA
| R200_TXA_COMP_ARG_A
388 /* GL_ZERO table - indices 0-1
389 * GL_ONE table - indices 1-2
391 static GLuint r300_zero_alpha
[] = {
393 R200_TXA_ARG_A_ZERO
| R200_TXA_COMP_ARG_A
,
397 /* Extract the arg from slot A, shift it into the correct argument slot
398 * and set the corresponding complement bit.
400 #define R200_COLOR_ARG( n, arg ) \
403 ((color_arg[n] & R200_TXC_ARG_A_MASK) \
404 << R200_TXC_ARG_##arg##_SHIFT); \
406 ((color_arg[n] >> R200_TXC_COMP_ARG_A_SHIFT) \
407 << R200_TXC_COMP_ARG_##arg##_SHIFT); \
410 #define R200_ALPHA_ARG( n, arg ) \
413 ((alpha_arg[n] & R200_TXA_ARG_A_MASK) \
414 << R200_TXA_ARG_##arg##_SHIFT); \
416 ((alpha_arg[n] >> R200_TXA_COMP_ARG_A_SHIFT) \
417 << R200_TXA_COMP_ARG_##arg##_SHIFT); \
420 /* ================================================================
421 * Texture unit state management
424 static GLboolean
r300UpdateTextureEnv(GLcontext
* ctx
, int unit
)
426 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
427 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
428 GLuint color_combine
, alpha_combine
;
430 #if 0 /* disable for now.. */
431 GLuint color_scale
= rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXCBLEND2
] &
432 ~(R200_TXC_SCALE_MASK
);
433 GLuint alpha_scale
= rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXABLEND2
] &
434 ~(R200_TXA_DOT_ALPHA
| R200_TXA_SCALE_MASK
);
436 /* texUnit->_Current can be NULL if and only if the texture unit is
437 * not actually enabled.
439 assert((texUnit
->_ReallyEnabled
== 0)
440 || (texUnit
->_Current
!= NULL
));
442 if (RADEON_DEBUG
& DEBUG_TEXTURE
) {
443 fprintf(stderr
, "%s( %p, %d )\n", __FUNCTION__
, (void *)ctx
,
447 /* Set the texture environment state. Isn't this nice and clean?
448 * The chip will automagically set the texture alpha to 0xff when
449 * the texture format does not include an alpha component. This
450 * reduces the amount of special-casing we have to do, alpha-only
451 * textures being a notable exception.
453 /* Don't cache these results.
455 rmesa
->state
.texture
.unit
[unit
].format
= 0;
456 rmesa
->state
.texture
.unit
[unit
].envMode
= 0;
458 if (!texUnit
->_ReallyEnabled
) {
461 R200_TXC_ARG_A_ZERO
| R200_TXC_ARG_B_ZERO
|
462 R200_TXC_ARG_C_DIFFUSE_COLOR
| R200_TXC_OP_MADD
;
464 R200_TXA_ARG_A_ZERO
| R200_TXA_ARG_B_ZERO
|
465 R200_TXA_ARG_C_DIFFUSE_ALPHA
| R200_TXA_OP_MADD
;
468 R200_TXC_ARG_A_ZERO
| R200_TXC_ARG_B_ZERO
|
469 R200_TXC_ARG_C_R0_COLOR
| R200_TXC_OP_MADD
;
471 R200_TXA_ARG_A_ZERO
| R200_TXA_ARG_B_ZERO
|
472 R200_TXA_ARG_C_R0_ALPHA
| R200_TXA_OP_MADD
;
475 GLuint color_arg
[3], alpha_arg
[3];
477 const GLuint numColorArgs
=
478 texUnit
->_CurrentCombine
->_NumArgsRGB
;
479 const GLuint numAlphaArgs
= texUnit
->_CurrentCombine
->_NumArgsA
;
480 GLuint RGBshift
= texUnit
->_CurrentCombine
->ScaleShiftRGB
;
481 GLuint Ashift
= texUnit
->_CurrentCombine
->ScaleShiftA
;
484 * Extract the color and alpha combine function arguments.
486 for (i
= 0; i
< numColorArgs
; i
++) {
488 texUnit
->_CurrentCombine
->OperandRGB
[i
] -
492 switch (texUnit
->_CurrentCombine
->SourceRGB
[i
]) {
494 color_arg
[i
] = r300_register_color
[op
][unit
];
497 color_arg
[i
] = r300_tfactor_color
[op
];
499 case GL_PRIMARY_COLOR
:
500 color_arg
[i
] = r300_primary_color
[op
];
504 color_arg
[i
] = r300_primary_color
[op
];
507 r300_register_color
[op
][0];
510 color_arg
[i
] = r300_zero_color
[op
];
513 color_arg
[i
] = r300_zero_color
[op
+ 1];
520 for (i
= 0; i
< numAlphaArgs
; i
++) {
522 texUnit
->_CurrentCombine
->OperandA
[i
] -
526 switch (texUnit
->_CurrentCombine
->SourceA
[i
]) {
528 alpha_arg
[i
] = r300_register_alpha
[op
][unit
];
531 alpha_arg
[i
] = r300_tfactor_alpha
[op
];
533 case GL_PRIMARY_COLOR
:
534 alpha_arg
[i
] = r300_primary_alpha
[op
];
538 alpha_arg
[i
] = r300_primary_alpha
[op
];
541 r300_register_alpha
[op
][0];
544 alpha_arg
[i
] = r300_zero_alpha
[op
];
547 alpha_arg
[i
] = r300_zero_alpha
[op
+ 1];
555 * Build up the color and alpha combine functions.
557 switch (texUnit
->_CurrentCombine
->ModeRGB
) {
559 color_combine
= (R200_TXC_ARG_A_ZERO
|
560 R200_TXC_ARG_B_ZERO
|
562 R200_COLOR_ARG(0, C
);
565 color_combine
= (R200_TXC_ARG_C_ZERO
|
567 R200_COLOR_ARG(0, A
);
568 R200_COLOR_ARG(1, B
);
571 color_combine
= (R200_TXC_ARG_B_ZERO
|
572 R200_TXC_COMP_ARG_B
|
574 R200_COLOR_ARG(0, A
);
575 R200_COLOR_ARG(1, C
);
578 color_combine
= (R200_TXC_ARG_B_ZERO
| R200_TXC_COMP_ARG_B
| R200_TXC_BIAS_ARG_C
| /* new */
579 R200_TXC_OP_MADD
); /* was ADDSIGNED */
580 R200_COLOR_ARG(0, A
);
581 R200_COLOR_ARG(1, C
);
584 color_combine
= (R200_TXC_ARG_B_ZERO
|
585 R200_TXC_COMP_ARG_B
|
586 R200_TXC_NEG_ARG_C
| R200_TXC_OP_MADD
);
587 R200_COLOR_ARG(0, A
);
588 R200_COLOR_ARG(1, C
);
591 color_combine
= (R200_TXC_OP_LERP
);
592 R200_COLOR_ARG(0, B
);
593 R200_COLOR_ARG(1, A
);
594 R200_COLOR_ARG(2, C
);
597 case GL_DOT3_RGB_EXT
:
598 case GL_DOT3_RGBA_EXT
:
599 /* The EXT version of the DOT3 extension does not support the
600 * scale factor, but the ARB version (and the version in OpenGL
608 /* DOT3 works differently on R200 than on R100. On R100, just
609 * setting the DOT3 mode did everything for you. On R200, the
610 * driver has to enable the biasing and scale in the inputs to
611 * put them in the proper [-1,1] range. This is what the 4x and
612 * the -0.5 in the DOT3 spec do. The post-scale is then set
616 color_combine
= (R200_TXC_ARG_C_ZERO
|
618 R200_TXC_BIAS_ARG_A
|
619 R200_TXC_BIAS_ARG_B
|
620 R200_TXC_SCALE_ARG_A
|
621 R200_TXC_SCALE_ARG_B
);
622 R200_COLOR_ARG(0, A
);
623 R200_COLOR_ARG(1, B
);
626 case GL_MODULATE_ADD_ATI
:
627 color_combine
= (R200_TXC_OP_MADD
);
628 R200_COLOR_ARG(0, A
);
629 R200_COLOR_ARG(1, C
);
630 R200_COLOR_ARG(2, B
);
632 case GL_MODULATE_SIGNED_ADD_ATI
:
633 color_combine
= (R200_TXC_BIAS_ARG_C
| /* new */
634 R200_TXC_OP_MADD
); /* was ADDSIGNED */
635 R200_COLOR_ARG(0, A
);
636 R200_COLOR_ARG(1, C
);
637 R200_COLOR_ARG(2, B
);
639 case GL_MODULATE_SUBTRACT_ATI
:
640 color_combine
= (R200_TXC_NEG_ARG_C
| R200_TXC_OP_MADD
);
641 R200_COLOR_ARG(0, A
);
642 R200_COLOR_ARG(1, C
);
643 R200_COLOR_ARG(2, B
);
649 switch (texUnit
->_CurrentCombine
->ModeA
) {
651 alpha_combine
= (R200_TXA_ARG_A_ZERO
|
652 R200_TXA_ARG_B_ZERO
|
654 R200_ALPHA_ARG(0, C
);
657 alpha_combine
= (R200_TXA_ARG_C_ZERO
|
659 R200_ALPHA_ARG(0, A
);
660 R200_ALPHA_ARG(1, B
);
663 alpha_combine
= (R200_TXA_ARG_B_ZERO
|
664 R200_TXA_COMP_ARG_B
|
666 R200_ALPHA_ARG(0, A
);
667 R200_ALPHA_ARG(1, C
);
670 alpha_combine
= (R200_TXA_ARG_B_ZERO
| R200_TXA_COMP_ARG_B
| R200_TXA_BIAS_ARG_C
| /* new */
671 R200_TXA_OP_MADD
); /* was ADDSIGNED */
672 R200_ALPHA_ARG(0, A
);
673 R200_ALPHA_ARG(1, C
);
676 alpha_combine
= (R200_TXA_ARG_B_ZERO
|
677 R200_TXA_COMP_ARG_B
|
678 R200_TXA_NEG_ARG_C
| R200_TXA_OP_MADD
);
679 R200_ALPHA_ARG(0, A
);
680 R200_ALPHA_ARG(1, C
);
683 alpha_combine
= (R200_TXA_OP_LERP
);
684 R200_ALPHA_ARG(0, B
);
685 R200_ALPHA_ARG(1, A
);
686 R200_ALPHA_ARG(2, C
);
689 case GL_MODULATE_ADD_ATI
:
690 alpha_combine
= (R200_TXA_OP_MADD
);
691 R200_ALPHA_ARG(0, A
);
692 R200_ALPHA_ARG(1, C
);
693 R200_ALPHA_ARG(2, B
);
695 case GL_MODULATE_SIGNED_ADD_ATI
:
696 alpha_combine
= (R200_TXA_BIAS_ARG_C
| /* new */
697 R200_TXA_OP_MADD
); /* was ADDSIGNED */
698 R200_ALPHA_ARG(0, A
);
699 R200_ALPHA_ARG(1, C
);
700 R200_ALPHA_ARG(2, B
);
702 case GL_MODULATE_SUBTRACT_ATI
:
703 alpha_combine
= (R200_TXA_NEG_ARG_C
| R200_TXA_OP_MADD
);
704 R200_ALPHA_ARG(0, A
);
705 R200_ALPHA_ARG(1, C
);
706 R200_ALPHA_ARG(2, B
);
712 if ((texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGBA_EXT
)
713 || (texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGBA
)) {
714 alpha_scale
|= R200_TXA_DOT_ALPHA
;
719 * Apply the scale factor.
721 color_scale
|= (RGBshift
<< R200_TXC_SCALE_SHIFT
);
722 alpha_scale
|= (Ashift
<< R200_TXA_SCALE_SHIFT
);
728 if (rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXCBLEND
] != color_combine
||
729 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXABLEND
] != alpha_combine
||
730 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXCBLEND2
] != color_scale
||
731 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXABLEND2
] != alpha_scale
) {
732 R300_STATECHANGE(rmesa
, pix
[unit
]);
733 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXCBLEND
] = color_combine
;
734 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXABLEND
] = alpha_combine
;
735 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXCBLEND2
] = color_scale
;
736 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXABLEND2
] = alpha_scale
;
744 #define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK | \
745 R200_MIN_FILTER_MASK | \
746 R200_MAG_FILTER_MASK | \
747 R200_MAX_ANISO_MASK | \
749 R200_YUV_TEMPERATURE_MASK | \
750 R200_CLAMP_S_MASK | \
751 R200_CLAMP_T_MASK | \
752 R200_BORDER_MODE_D3D )
754 #define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK | \
755 R200_TXFORMAT_HEIGHT_MASK | \
756 R200_TXFORMAT_FORMAT_MASK | \
757 R200_TXFORMAT_F5_WIDTH_MASK | \
758 R200_TXFORMAT_F5_HEIGHT_MASK | \
759 R200_TXFORMAT_ALPHA_IN_MAP | \
760 R200_TXFORMAT_CUBIC_MAP_ENABLE | \
761 R200_TXFORMAT_NON_POWER2)
763 #define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK | \
764 R200_TEXCOORD_MASK | \
765 R200_CLAMP_Q_MASK | \
766 R200_VOLUME_FILTER_MASK)
768 static void import_tex_obj_state(r300ContextPtr rmesa
,
769 int unit
, r300TexObjPtr texobj
)
771 #if 0 /* needs fixing.. or should be done elsewhere */
772 GLuint
*cmd
= R300_DB_STATE(tex
[unit
]);
774 cmd
[TEX_PP_TXFILTER
] &= ~TEXOBJ_TXFILTER_MASK
;
775 cmd
[TEX_PP_TXFILTER
] |= texobj
->filter
& TEXOBJ_TXFILTER_MASK
;
776 cmd
[TEX_PP_TXFORMAT
] &= ~TEXOBJ_TXFORMAT_MASK
;
777 cmd
[TEX_PP_TXFORMAT
] |= texobj
->format
& TEXOBJ_TXFORMAT_MASK
;
778 cmd
[TEX_PP_TXFORMAT_X
] &= ~TEXOBJ_TXFORMAT_X_MASK
;
779 cmd
[TEX_PP_TXFORMAT_X
] |=
780 texobj
->format_x
& TEXOBJ_TXFORMAT_X_MASK
;
781 cmd
[TEX_PP_TXSIZE
] = texobj
->size
; /* NPOT only! */
782 cmd
[TEX_PP_TXPITCH
] = texobj
->pitch
; /* NPOT only! */
783 cmd
[TEX_PP_TXOFFSET
] = texobj
->pp_txoffset
;
784 cmd
[TEX_PP_BORDER_COLOR
] = texobj
->pp_border_color
;
785 R200_DB_STATECHANGE(rmesa
, &rmesa
->hw
.tex
[unit
]);
787 if (texobj
->base
.tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
788 GLuint
*cube_cmd
= R200_DB_STATE(cube
[unit
]);
789 GLuint bytesPerFace
= texobj
->base
.totalSize
/ 6;
790 ASSERT(texobj
->totalSize
% 6 == 0);
791 cube_cmd
[CUBE_PP_CUBIC_FACES
] = texobj
->pp_cubic_faces
;
792 cube_cmd
[CUBE_PP_CUBIC_OFFSET_F1
] =
793 texobj
->pp_txoffset
+ 1 * bytesPerFace
;
794 cube_cmd
[CUBE_PP_CUBIC_OFFSET_F2
] =
795 texobj
->pp_txoffset
+ 2 * bytesPerFace
;
796 cube_cmd
[CUBE_PP_CUBIC_OFFSET_F3
] =
797 texobj
->pp_txoffset
+ 3 * bytesPerFace
;
798 cube_cmd
[CUBE_PP_CUBIC_OFFSET_F4
] =
799 texobj
->pp_txoffset
+ 4 * bytesPerFace
;
800 cube_cmd
[CUBE_PP_CUBIC_OFFSET_F5
] =
801 texobj
->pp_txoffset
+ 5 * bytesPerFace
;
802 R200_DB_STATECHANGE(rmesa
, &rmesa
->hw
.cube
[unit
]);
805 texobj
->dirty_state
&= ~(1 << unit
);
809 static void set_texgen_matrix(r300ContextPtr rmesa
,
811 const GLfloat
* s_plane
,
812 const GLfloat
* t_plane
, const GLfloat
* r_plane
)
814 static const GLfloat scale_identity
[4] = { 1, 1, 1, 1 };
816 if (!TEST_EQ_4V(s_plane
, scale_identity
) ||
817 !TEST_EQ_4V(t_plane
, scale_identity
) ||
818 !TEST_EQ_4V(r_plane
, scale_identity
)) {
819 rmesa
->TexGenEnabled
|= R200_TEXMAT_0_ENABLE
<< unit
;
820 rmesa
->TexGenMatrix
[unit
].m
[0] = s_plane
[0];
821 rmesa
->TexGenMatrix
[unit
].m
[4] = s_plane
[1];
822 rmesa
->TexGenMatrix
[unit
].m
[8] = s_plane
[2];
823 rmesa
->TexGenMatrix
[unit
].m
[12] = s_plane
[3];
825 rmesa
->TexGenMatrix
[unit
].m
[1] = t_plane
[0];
826 rmesa
->TexGenMatrix
[unit
].m
[5] = t_plane
[1];
827 rmesa
->TexGenMatrix
[unit
].m
[9] = t_plane
[2];
828 rmesa
->TexGenMatrix
[unit
].m
[13] = t_plane
[3];
830 /* NOTE: r_plane goes in the 4th row, not 3rd! */
831 rmesa
->TexGenMatrix
[unit
].m
[3] = r_plane
[0];
832 rmesa
->TexGenMatrix
[unit
].m
[7] = r_plane
[1];
833 rmesa
->TexGenMatrix
[unit
].m
[11] = r_plane
[2];
834 rmesa
->TexGenMatrix
[unit
].m
[15] = r_plane
[3];
836 //rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
840 /* Need this special matrix to get correct reflection map coords */
841 static void set_texgen_reflection_matrix(r300ContextPtr rmesa
, GLuint unit
)
843 static const GLfloat m
[16] = {
849 _math_matrix_loadf(&(rmesa
->TexGenMatrix
[unit
]), m
);
850 _math_matrix_analyse(&(rmesa
->TexGenMatrix
[unit
]));
851 rmesa
->TexGenEnabled
|= R200_TEXMAT_0_ENABLE
<< unit
;
854 /* Need this special matrix to get correct normal map coords */
855 static void set_texgen_normal_map_matrix(r300ContextPtr rmesa
, GLuint unit
)
857 static const GLfloat m
[16] = {
863 _math_matrix_loadf(&(rmesa
->TexGenMatrix
[unit
]), m
);
864 _math_matrix_analyse(&(rmesa
->TexGenMatrix
[unit
]));
865 rmesa
->TexGenEnabled
|= R200_TEXMAT_0_ENABLE
<< unit
;
868 /* Ignoring the Q texcoord for now.
870 * Returns GL_FALSE if fallback required.
872 static GLboolean
r300_validate_texgen(GLcontext
* ctx
, GLuint unit
)
874 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
875 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
876 GLuint inputshift
= R200_TEXGEN_0_INPUT_SHIFT
+ unit
* 4;
877 GLuint tmp
= rmesa
->TexGenEnabled
;
879 rmesa
->TexGenCompSel
&= ~(R200_OUTPUT_TEX_0
<< unit
);
880 rmesa
->TexGenEnabled
&= ~(R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
);
881 rmesa
->TexGenEnabled
&= ~(R200_TEXMAT_0_ENABLE
<< unit
);
882 rmesa
->TexGenInputs
&= ~(R200_TEXGEN_INPUT_MASK
<< inputshift
);
883 rmesa
->TexGenNeedNormals
[unit
] = 0;
886 fprintf(stderr
, "%s unit %d\n", __FUNCTION__
, unit
);
888 if ((texUnit
->TexGenEnabled
& (S_BIT
| T_BIT
| R_BIT
)) == 0) {
889 /* Disabled, no fallback:
891 rmesa
->TexGenInputs
|=
892 (R200_TEXGEN_INPUT_TEXCOORD_0
+ unit
) << inputshift
;
894 } else if (texUnit
->TexGenEnabled
& Q_BIT
) {
895 /* Very easy to do this, in fact would remove a fallback case
896 * elsewhere, but I haven't done it yet... Fallback:
898 /*fprintf(stderr, "fallback Q_BIT\n"); */
900 } else if (texUnit
->TexGenEnabled
== (S_BIT
| T_BIT
) &&
901 texUnit
->GenModeS
== texUnit
->GenModeT
) {
903 rmesa
->TexGenEnabled
|= R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
;
905 } else if (texUnit
->TexGenEnabled
== (S_BIT
| T_BIT
| R_BIT
) &&
906 texUnit
->GenModeS
== texUnit
->GenModeT
&&
907 texUnit
->GenModeT
== texUnit
->GenModeR
) {
909 rmesa
->TexGenEnabled
|= R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
;
912 /* Mixed modes, fallback:
914 /* fprintf(stderr, "fallback mixed texgen\n"); */
918 rmesa
->TexGenEnabled
|= R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
;
920 switch (texUnit
->GenModeS
) {
921 case GL_OBJECT_LINEAR
:
922 rmesa
->TexGenInputs
|= R200_TEXGEN_INPUT_OBJ
<< inputshift
;
923 set_texgen_matrix(rmesa
, unit
,
924 texUnit
->ObjectPlaneS
,
925 texUnit
->ObjectPlaneT
, texUnit
->ObjectPlaneR
);
929 rmesa
->TexGenInputs
|= R200_TEXGEN_INPUT_EYE
<< inputshift
;
930 set_texgen_matrix(rmesa
, unit
,
932 texUnit
->EyePlaneT
, texUnit
->EyePlaneR
);
935 case GL_REFLECTION_MAP_NV
:
936 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
937 rmesa
->TexGenInputs
|=
938 R200_TEXGEN_INPUT_EYE_REFLECT
<< inputshift
;
939 set_texgen_reflection_matrix(rmesa
, unit
);
942 case GL_NORMAL_MAP_NV
:
943 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
944 rmesa
->TexGenInputs
|=
945 R200_TEXGEN_INPUT_EYE_NORMAL
<< inputshift
;
946 set_texgen_normal_map_matrix(rmesa
, unit
);
950 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
951 rmesa
->TexGenInputs
|= R200_TEXGEN_INPUT_SPHERE
<< inputshift
;
955 /* Unsupported mode, fallback:
957 /* fprintf(stderr, "fallback unsupported texgen\n"); */
961 rmesa
->TexGenCompSel
|= R200_OUTPUT_TEX_0
<< unit
;
963 if (tmp
!= rmesa
->TexGenEnabled
) {
964 //rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
970 static void disable_tex(GLcontext
* ctx
, int unit
)
972 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
974 #if 0 /* This needs to be redone.. or done elsewhere */
975 if (rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & (R200_TEX_0_ENABLE
<< unit
)) {
976 /* Texture unit disabled */
977 if (rmesa
->state
.texture
.unit
[unit
].texobj
!= NULL
) {
978 /* The old texture is no longer bound to this texture unit.
982 rmesa
->state
.texture
.unit
[unit
].texobj
->base
.bound
&=
984 rmesa
->state
.texture
.unit
[unit
].texobj
= NULL
;
987 R300_STATECHANGE(rmesa
, ctx
);
988 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~((R200_TEX_0_ENABLE
|
989 R200_TEX_BLEND_0_ENABLE
) <<
991 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_TEX_BLEND_0_ENABLE
;
993 R300_STATECHANGE(rmesa
, tcl
);
994 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_1
] &=
997 if (rmesa
->radeon
.TclFallback
& (RADEON_TCL_FALLBACK_TEXGEN_0
<< unit
)) {
998 TCL_FALLBACK(ctx
, (RADEON_TCL_FALLBACK_TEXGEN_0
<< unit
),
1002 /* Actually want to keep all units less than max active texture
1003 * enabled, right? Fix this for >2 texunits.
1005 /* FIXME: What should happen here if r300UpdateTextureEnv fails? */
1007 r300UpdateTextureEnv(ctx
, unit
);
1011 R200_TEXGEN_0_INPUT_SHIFT
+ unit
* 4;
1012 GLuint tmp
= rmesa
->TexGenEnabled
;
1014 rmesa
->TexGenEnabled
&=
1015 ~(R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
);
1016 rmesa
->TexGenEnabled
&= ~(R200_TEXMAT_0_ENABLE
<< unit
);
1017 rmesa
->TexGenEnabled
&=
1018 ~(R200_TEXGEN_INPUT_MASK
<< inputshift
);
1019 rmesa
->TexGenNeedNormals
[unit
] = 0;
1020 rmesa
->TexGenCompSel
&= ~(R200_OUTPUT_TEX_0
<< unit
);
1021 rmesa
->TexGenInputs
&=
1022 ~(R200_TEXGEN_INPUT_MASK
<< inputshift
);
1024 if (tmp
!= rmesa
->TexGenEnabled
) {
1025 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1026 rmesa
->NewGLState
|= _NEW_TEXTURE_MATRIX
;
1033 static GLboolean
enable_tex_2d(GLcontext
* ctx
, int unit
)
1035 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1036 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1037 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1038 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
1040 /* Need to load the 2d images associated with this unit.
1042 if (t
->format
& R200_TXFORMAT_NON_POWER2
) {
1043 t
->format
&= ~R200_TXFORMAT_NON_POWER2
;
1044 t
->base
.dirty_images
[0] = ~0;
1047 ASSERT(tObj
->Target
== GL_TEXTURE_2D
|| tObj
->Target
== GL_TEXTURE_1D
);
1049 if (t
->base
.dirty_images
[0]) {
1050 R300_FIREVERTICES(rmesa
);
1051 r300SetTexImages(rmesa
, tObj
);
1052 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
1053 if (!t
->base
.memBlock
)
1060 #if ENABLE_HW_3D_TEXTURE
1061 static GLboolean
enable_tex_3d(GLcontext
* ctx
, int unit
)
1063 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1064 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1065 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1066 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
1068 /* Need to load the 3d images associated with this unit.
1070 if (t
->format
& R200_TXFORMAT_NON_POWER2
) {
1071 t
->format
&= ~R200_TXFORMAT_NON_POWER2
;
1072 t
->base
.dirty_images
[0] = ~0;
1075 ASSERT(tObj
->Target
== GL_TEXTURE_3D
);
1077 /* R100 & R200 do not support mipmaps for 3D textures.
1079 if ((tObj
->MinFilter
!= GL_NEAREST
) && (tObj
->MinFilter
!= GL_LINEAR
)) {
1083 if (t
->base
.dirty_images
[0]) {
1084 R300_FIREVERTICES(rmesa
);
1085 r300SetTexImages(rmesa
, tObj
);
1086 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
1087 if (!t
->base
.memBlock
)
1095 static GLboolean
enable_tex_cube(GLcontext
* ctx
, int unit
)
1097 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1098 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1099 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1100 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
1103 /* Need to load the 2d images associated with this unit.
1105 if (t
->format
& R200_TXFORMAT_NON_POWER2
) {
1106 t
->format
&= ~R200_TXFORMAT_NON_POWER2
;
1107 for (face
= 0; face
< 6; face
++)
1108 t
->base
.dirty_images
[face
] = ~0;
1111 ASSERT(tObj
->Target
== GL_TEXTURE_CUBE_MAP
);
1113 if (t
->base
.dirty_images
[0] || t
->base
.dirty_images
[1] ||
1114 t
->base
.dirty_images
[2] || t
->base
.dirty_images
[3] ||
1115 t
->base
.dirty_images
[4] || t
->base
.dirty_images
[5]) {
1117 R300_FIREVERTICES(rmesa
);
1118 /* layout memory space, once for all faces */
1119 r300SetTexImages(rmesa
, tObj
);
1122 /* upload (per face) */
1123 for (face
= 0; face
< 6; face
++) {
1124 if (t
->base
.dirty_images
[face
]) {
1125 r300UploadTexImages(rmesa
,
1126 (r300TexObjPtr
) tObj
->DriverData
,
1131 if (!t
->base
.memBlock
) {
1132 /* texmem alloc failed, use s/w fallback */
1139 static GLboolean
enable_tex_rect(GLcontext
* ctx
, int unit
)
1141 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1142 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1143 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1144 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
1146 if (!(t
->format
& R200_TXFORMAT_NON_POWER2
)) {
1147 t
->format
|= R200_TXFORMAT_NON_POWER2
;
1148 t
->base
.dirty_images
[0] = ~0;
1151 ASSERT(tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
);
1153 if (t
->base
.dirty_images
[0]) {
1154 R300_FIREVERTICES(rmesa
);
1155 r300SetTexImages(rmesa
, tObj
);
1156 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
1157 if (!t
->base
.memBlock
&& !rmesa
->prefer_gart_client_texturing
)
1164 static GLboolean
update_tex_common(GLcontext
* ctx
, int unit
)
1166 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1167 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1168 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1169 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
1172 /* Fallback if there's a texture border */
1173 if (tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0)
1176 /* Update state if this is a different texture object to last
1179 if (rmesa
->state
.texture
.unit
[unit
].texobj
!= t
) {
1180 if (rmesa
->state
.texture
.unit
[unit
].texobj
!= NULL
) {
1181 /* The old texture is no longer bound to this texture unit.
1185 rmesa
->state
.texture
.unit
[unit
].texobj
->base
.bound
&=
1189 rmesa
->state
.texture
.unit
[unit
].texobj
= t
;
1190 t
->base
.bound
|= (1UL << unit
);
1191 t
->dirty_state
|= 1 << unit
;
1192 driUpdateTextureLRU((driTextureObject
*) t
); /* XXX: should be locked! */
1195 #if 0 /* do elsewhere ? */
1200 cmd
[CTX_PP_CNTL
] & (R200_TEX_0_ENABLE
<< unit
))) {
1201 R300_STATECHANGE(rmesa
, ctx
);
1202 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= (R200_TEX_0_ENABLE
|
1203 R200_TEX_BLEND_0_ENABLE
) <<
1206 R300_STATECHANGE(rmesa
, vtx
);
1207 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_1
] |= 4 << (unit
* 3);
1209 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1212 if (t
->dirty_state
& (1 << unit
)) {
1213 import_tex_obj_state(rmesa
, unit
, t
);
1216 if (rmesa
->recheck_texgen
[unit
]) {
1217 GLboolean fallback
= !r300_validate_texgen(ctx
, unit
);
1218 TCL_FALLBACK(ctx
, (RADEON_TCL_FALLBACK_TEXGEN_0
<< unit
),
1220 rmesa
->recheck_texgen
[unit
] = 0;
1221 rmesa
->NewGLState
|= _NEW_TEXTURE_MATRIX
;
1224 format
= tObj
->Image
[0][tObj
->BaseLevel
]->Format
;
1225 if (rmesa
->state
.texture
.unit
[unit
].format
!= format
||
1226 rmesa
->state
.texture
.unit
[unit
].envMode
!= texUnit
->EnvMode
) {
1227 rmesa
->state
.texture
.unit
[unit
].format
= format
;
1228 rmesa
->state
.texture
.unit
[unit
].envMode
= texUnit
->EnvMode
;
1229 if (!r300UpdateTextureEnv(ctx
, unit
)) {
1235 FALLBACK(&rmesa
->radeon
, RADEON_FALLBACK_BORDER_MODE
, t
->border_fallback
);
1236 return !t
->border_fallback
;
1239 static GLboolean
r300UpdateTextureUnit(GLcontext
* ctx
, int unit
)
1241 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1243 if (texUnit
->_ReallyEnabled
& (TEXTURE_RECT_BIT
)) {
1244 return (enable_tex_rect(ctx
, unit
) &&
1245 update_tex_common(ctx
, unit
));
1246 } else if (texUnit
->_ReallyEnabled
& (TEXTURE_1D_BIT
| TEXTURE_2D_BIT
)) {
1247 return (enable_tex_2d(ctx
, unit
) &&
1248 update_tex_common(ctx
, unit
));
1250 #if ENABLE_HW_3D_TEXTURE
1251 else if (texUnit
->_ReallyEnabled
& (TEXTURE_3D_BIT
)) {
1252 return (enable_tex_3d(ctx
, unit
) &&
1253 update_tex_common(ctx
, unit
));
1256 else if (texUnit
->_ReallyEnabled
& (TEXTURE_CUBE_BIT
)) {
1257 return (enable_tex_cube(ctx
, unit
) &&
1258 update_tex_common(ctx
, unit
));
1259 } else if (texUnit
->_ReallyEnabled
) {
1262 disable_tex(ctx
, unit
);
1267 void r300UpdateTextureState(GLcontext
* ctx
)
1269 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1274 ok
= (r300UpdateTextureUnit(ctx
, 0) &&
1275 r300UpdateTextureUnit(ctx
, 1) &&
1276 r300UpdateTextureUnit(ctx
, 2) &&
1277 r300UpdateTextureUnit(ctx
, 3) &&
1278 r300UpdateTextureUnit(ctx
, 4) &&
1279 r300UpdateTextureUnit(ctx
, 5) &&
1280 r300UpdateTextureUnit(ctx
, 6) &&
1281 r300UpdateTextureUnit(ctx
, 7)
1284 FALLBACK(&rmesa
->radeon
, RADEON_FALLBACK_TEXTURE
, !ok
);
1286 /* This needs correction, or just be done elsewhere
1287 if (rmesa->radeon.TclFallback)
1288 r300ChooseVertexState(ctx);
1291 #if 0 /* Workaround - disable.. */
1292 if (GET_CHIP(rmesa
->radeon
.radeonScreen
) == RADEON_CHIP_REAL_R200
) {
1294 * T0 hang workaround -------------
1295 * not needed for r300 derivatives?
1297 if ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_ENABLE_MASK
) ==
1299 && (rmesa
->hw
.tex
[0].
1300 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
) >
1301 R200_MIN_FILTER_LINEAR
) {
1303 R300_STATECHANGE(rmesa
, ctx
);
1304 R300_STATECHANGE(rmesa
, tex
[1]);
1305 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_TEX_1_ENABLE
;
1306 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] &=
1307 ~TEXOBJ_TXFORMAT_MASK
;
1308 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] |= 0x08000000;
1310 if ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_1_ENABLE
)
1311 && (rmesa
->hw
.tex
[1].
1312 cmd
[TEX_PP_TXFORMAT
] & 0x08000000)) {
1313 R300_STATECHANGE(rmesa
, tex
[1]);
1314 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] &=
1319 /* maybe needs to be done pairwise due to 2 parallel (physical) tex units ?
1320 looks like that's not the case, if 8500/9100 owners don't complain remove this...
1321 for ( i = 0; i < ctx->Const.MaxTextureUnits; i += 2) {
1322 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & ((R200_TEX_0_ENABLE |
1323 R200_TEX_1_ENABLE ) << i)) == (R200_TEX_0_ENABLE << i)) &&
1324 ((rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) >
1325 R200_MIN_FILTER_LINEAR)) {
1326 R300_STATECHANGE(rmesa, ctx);
1327 R300_STATECHANGE(rmesa, tex[i+1]);
1328 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_1_ENABLE << i);
1329 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1330 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] |= 0x08000000;
1333 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE << i)) &&
1334 (rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) {
1335 R300_STATECHANGE(rmesa, tex[i+1]);
1336 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000;
1342 * Texture cache LRU hang workaround -------------
1343 * not needed for r300 derivatives?
1347 if (((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & (R200_TEX_0_ENABLE
)) &&
1348 ((((rmesa
->hw
.tex
[0].
1349 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) & 0x04)
1351 || ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_2_ENABLE
)
1353 ((((rmesa
->hw
.tex
[2].
1354 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
1356 || ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_4_ENABLE
)
1358 ((((rmesa
->hw
.tex
[4].
1359 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
1364 if (((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & (R200_TEX_1_ENABLE
)) &&
1365 ((((rmesa
->hw
.tex
[1].
1366 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) & 0x04)
1368 || ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_3_ENABLE
)
1370 ((((rmesa
->hw
.tex
[3].
1371 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
1373 || ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_5_ENABLE
)
1375 ((((rmesa
->hw
.tex
[5].
1376 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
1381 if (dbg
!= rmesa
->hw
.tam
.cmd
[TAM_DEBUG3
]) {
1382 R300_STATECHANGE(rmesa
, tam
);
1383 rmesa
->hw
.tam
.cmd
[TAM_DEBUG3
] = dbg
;
1385 printf("TEXCACHE LRU HANG WORKAROUND %x\n",