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"
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
58 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, 0 }
59 #define _COLOR_REV(f) \
60 [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f, 0 }
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 }
66 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, R200_YUV_TO_RGB }
68 [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
69 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_YCBCR_REV) \
70 && (tx_table[f].format != 0xffffffff) )
73 GLuint format
, filter
;
90 _ALPHA(I8
), _INVALID(CI8
), _YUV(YCBCR
), _YUV(YCBCR_REV
),};
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
103 * \param rmesa Context pointer
104 * \param tObj GL texture object whose images are to be posted to
107 static void r300SetTexImages(r300ContextPtr rmesa
,
108 struct gl_texture_object
*tObj
)
110 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
111 const struct gl_texture_image
*baseImage
=
112 tObj
->Image
[0][tObj
->BaseLevel
];
116 GLint log2Width
, log2Height
, log2Depth
;
118 /* Set the hardware texture format
121 t
->format
&= ~(R200_TXFORMAT_FORMAT_MASK
|
122 R200_TXFORMAT_ALPHA_IN_MAP
);
123 t
->filter
&= ~R200_YUV_TO_RGB
;
125 if (VALID_FORMAT(baseImage
->TexFormat
->MesaFormat
)) {
127 tx_table
[baseImage
->TexFormat
->MesaFormat
].format
;
129 tx_table
[baseImage
->TexFormat
->MesaFormat
].filter
;
131 _mesa_problem(NULL
, "unexpected texture format in %s",
136 /* Compute which mipmap levels we really want to send to the hardware.
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
;
144 numLevels
= t
->base
.lastLevel
- t
->base
.firstLevel
+ 1;
146 assert(numLevels
<= RADEON_MAX_TEXTURE_LEVELS
);
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.
154 for (i
= 0; i
< numLevels
; i
++) {
155 const struct gl_texture_image
*texImage
;
158 texImage
= tObj
->Image
[0][i
+ t
->base
.firstLevel
];
162 /* find image size in bytes */
163 if (texImage
->IsCompressed
) {
164 size
= texImage
->CompressedSize
;
165 } else if (tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
) {
168 texImage
->TexFormat
->TexelBytes
+ 63)
169 & ~63) * texImage
->Height
;
172 texImage
->Width
* texImage
->TexFormat
->TexelBytes
;
175 size
= w
* texImage
->Height
* texImage
->Depth
;
179 /* Align to 32-byte offset. It is faster to do this unconditionally
180 * (no branch penalty).
183 curOffset
= (curOffset
+ 0x1f) & ~0x1f;
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
;
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));
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
,
210 /* Align the total size of texture memory block.
213 (curOffset
+ RADEON_OFFSET_MASK
) & ~RADEON_OFFSET_MASK
;
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
;
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
;
234 t
->base
.totalSize
= 6 * faceSize
; /* total texmem needed */
239 t
->filter
&= ~R200_MAX_MIP_LEVEL_MASK
;
240 t
->filter
|= (numLevels
- 1) << R200_MAX_MIP_LEVEL_SHIFT
;
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
));
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
));
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
);
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!
278 if (baseImage
->IsCompressed
)
280 (tObj
->Image
[0][t
->base
.firstLevel
]->Width
+ 63) & ~(63);
283 ((tObj
->Image
[0][t
->base
.firstLevel
]->Width
*
284 baseImage
->TexFormat
->TexelBytes
) + 63) & ~(63);
287 t
->dirty_state
= TEX_ALL
;
289 /* FYI: r300UploadTexImages( rmesa, t ) used to be called here */
292 /* ================================================================
293 * Texture combine functions
296 /* GL_ARB_texture_env_combine support
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.
302 static GLuint r300_register_color
[][R200_MAX_TEXTURE_UNITS
] = {
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
},
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
},
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
},
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
},
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
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
347 /* GL_ZERO table - indices 0-3
348 * GL_ONE table - indices 1-4
350 static GLuint r300_zero_color
[] = {
352 R200_TXC_ARG_A_ZERO
| R200_TXC_COMP_ARG_A
,
354 R200_TXC_ARG_A_ZERO
| R200_TXC_COMP_ARG_A
,
358 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
360 static GLuint r300_register_alpha
[][R200_MAX_TEXTURE_UNITS
] = {
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
},
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
},
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
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
387 /* GL_ZERO table - indices 0-1
388 * GL_ONE table - indices 1-2
390 static GLuint r300_zero_alpha
[] = {
392 R200_TXA_ARG_A_ZERO
| R200_TXA_COMP_ARG_A
,
396 /* Extract the arg from slot A, shift it into the correct argument slot
397 * and set the corresponding complement bit.
399 #define R200_COLOR_ARG( n, arg ) \
402 ((color_arg[n] & R200_TXC_ARG_A_MASK) \
403 << R200_TXC_ARG_##arg##_SHIFT); \
405 ((color_arg[n] >> R200_TXC_COMP_ARG_A_SHIFT) \
406 << R200_TXC_COMP_ARG_##arg##_SHIFT); \
409 #define R200_ALPHA_ARG( n, arg ) \
412 ((alpha_arg[n] & R200_TXA_ARG_A_MASK) \
413 << R200_TXA_ARG_##arg##_SHIFT); \
415 ((alpha_arg[n] >> R200_TXA_COMP_ARG_A_SHIFT) \
416 << R200_TXA_COMP_ARG_##arg##_SHIFT); \
419 /* ================================================================
420 * Texture unit state management
423 static GLboolean
r300UpdateTextureEnv(GLcontext
* ctx
, int unit
)
425 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
426 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
427 GLuint color_combine
, alpha_combine
;
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
);
435 /* texUnit->_Current can be NULL if and only if the texture unit is
436 * not actually enabled.
438 assert((texUnit
->_ReallyEnabled
== 0)
439 || (texUnit
->_Current
!= NULL
));
441 if (RADEON_DEBUG
& DEBUG_TEXTURE
) {
442 fprintf(stderr
, "%s( %p, %d )\n", __FUNCTION__
, (void *)ctx
,
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.
452 /* Don't cache these results.
454 rmesa
->state
.texture
.unit
[unit
].format
= 0;
455 rmesa
->state
.texture
.unit
[unit
].envMode
= 0;
457 if (!texUnit
->_ReallyEnabled
) {
460 R200_TXC_ARG_A_ZERO
| R200_TXC_ARG_B_ZERO
|
461 R200_TXC_ARG_C_DIFFUSE_COLOR
| R200_TXC_OP_MADD
;
463 R200_TXA_ARG_A_ZERO
| R200_TXA_ARG_B_ZERO
|
464 R200_TXA_ARG_C_DIFFUSE_ALPHA
| R200_TXA_OP_MADD
;
467 R200_TXC_ARG_A_ZERO
| R200_TXC_ARG_B_ZERO
|
468 R200_TXC_ARG_C_R0_COLOR
| R200_TXC_OP_MADD
;
470 R200_TXA_ARG_A_ZERO
| R200_TXA_ARG_B_ZERO
|
471 R200_TXA_ARG_C_R0_ALPHA
| R200_TXA_OP_MADD
;
474 GLuint color_arg
[3], alpha_arg
[3];
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
;
483 * Extract the color and alpha combine function arguments.
485 for (i
= 0; i
< numColorArgs
; i
++) {
487 texUnit
->_CurrentCombine
->OperandRGB
[i
] -
491 switch (texUnit
->_CurrentCombine
->SourceRGB
[i
]) {
493 color_arg
[i
] = r300_register_color
[op
][unit
];
496 color_arg
[i
] = r300_tfactor_color
[op
];
498 case GL_PRIMARY_COLOR
:
499 color_arg
[i
] = r300_primary_color
[op
];
503 color_arg
[i
] = r300_primary_color
[op
];
506 r300_register_color
[op
][0];
509 color_arg
[i
] = r300_zero_color
[op
];
512 color_arg
[i
] = r300_zero_color
[op
+ 1];
519 for (i
= 0; i
< numAlphaArgs
; i
++) {
521 texUnit
->_CurrentCombine
->OperandA
[i
] -
525 switch (texUnit
->_CurrentCombine
->SourceA
[i
]) {
527 alpha_arg
[i
] = r300_register_alpha
[op
][unit
];
530 alpha_arg
[i
] = r300_tfactor_alpha
[op
];
532 case GL_PRIMARY_COLOR
:
533 alpha_arg
[i
] = r300_primary_alpha
[op
];
537 alpha_arg
[i
] = r300_primary_alpha
[op
];
540 r300_register_alpha
[op
][0];
543 alpha_arg
[i
] = r300_zero_alpha
[op
];
546 alpha_arg
[i
] = r300_zero_alpha
[op
+ 1];
554 * Build up the color and alpha combine functions.
556 switch (texUnit
->_CurrentCombine
->ModeRGB
) {
558 color_combine
= (R200_TXC_ARG_A_ZERO
|
559 R200_TXC_ARG_B_ZERO
|
561 R200_COLOR_ARG(0, C
);
564 color_combine
= (R200_TXC_ARG_C_ZERO
|
566 R200_COLOR_ARG(0, A
);
567 R200_COLOR_ARG(1, B
);
570 color_combine
= (R200_TXC_ARG_B_ZERO
|
571 R200_TXC_COMP_ARG_B
|
573 R200_COLOR_ARG(0, A
);
574 R200_COLOR_ARG(1, C
);
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
);
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
);
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
);
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
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
615 color_combine
= (R200_TXC_ARG_C_ZERO
|
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
);
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
);
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
);
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
);
648 switch (texUnit
->_CurrentCombine
->ModeA
) {
650 alpha_combine
= (R200_TXA_ARG_A_ZERO
|
651 R200_TXA_ARG_B_ZERO
|
653 R200_ALPHA_ARG(0, C
);
656 alpha_combine
= (R200_TXA_ARG_C_ZERO
|
658 R200_ALPHA_ARG(0, A
);
659 R200_ALPHA_ARG(1, B
);
662 alpha_combine
= (R200_TXA_ARG_B_ZERO
|
663 R200_TXA_COMP_ARG_B
|
665 R200_ALPHA_ARG(0, A
);
666 R200_ALPHA_ARG(1, C
);
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
);
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
);
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
);
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
);
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
);
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
);
711 if ((texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGBA_EXT
)
712 || (texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGBA
)) {
713 alpha_scale
|= R200_TXA_DOT_ALPHA
;
718 * Apply the scale factor.
720 color_scale
|= (RGBshift
<< R200_TXC_SCALE_SHIFT
);
721 alpha_scale
|= (Ashift
<< R200_TXA_SCALE_SHIFT
);
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
;
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 | \
748 R200_YUV_TEMPERATURE_MASK | \
749 R200_CLAMP_S_MASK | \
750 R200_CLAMP_T_MASK | \
751 R200_BORDER_MODE_D3D )
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)
762 #define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK | \
763 R200_TEXCOORD_MASK | \
764 R200_CLAMP_Q_MASK | \
765 R200_VOLUME_FILTER_MASK)
767 static void import_tex_obj_state(r300ContextPtr rmesa
,
768 int unit
, r300TexObjPtr texobj
)
770 #if 0 /* needs fixing.. or should be done elsewhere */
771 GLuint
*cmd
= R300_DB_STATE(tex
[unit
]);
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
]);
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
]);
804 texobj
->dirty_state
&= ~(1 << unit
);
808 static void set_texgen_matrix(r300ContextPtr rmesa
,
810 const GLfloat
* s_plane
,
811 const GLfloat
* t_plane
, const GLfloat
* r_plane
)
813 static const GLfloat scale_identity
[4] = { 1, 1, 1, 1 };
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];
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];
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];
835 //rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
839 /* Need this special matrix to get correct reflection map coords */
840 static void set_texgen_reflection_matrix(r300ContextPtr rmesa
, GLuint unit
)
842 static const GLfloat m
[16] = {
848 _math_matrix_loadf(&(rmesa
->TexGenMatrix
[unit
]), m
);
849 _math_matrix_analyse(&(rmesa
->TexGenMatrix
[unit
]));
850 rmesa
->TexGenEnabled
|= R200_TEXMAT_0_ENABLE
<< unit
;
853 /* Need this special matrix to get correct normal map coords */
854 static void set_texgen_normal_map_matrix(r300ContextPtr rmesa
, GLuint unit
)
856 static const GLfloat m
[16] = {
862 _math_matrix_loadf(&(rmesa
->TexGenMatrix
[unit
]), m
);
863 _math_matrix_analyse(&(rmesa
->TexGenMatrix
[unit
]));
864 rmesa
->TexGenEnabled
|= R200_TEXMAT_0_ENABLE
<< unit
;
867 /* Ignoring the Q texcoord for now.
869 * Returns GL_FALSE if fallback required.
871 static GLboolean
r300_validate_texgen(GLcontext
* ctx
, GLuint unit
)
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
;
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;
885 fprintf(stderr
, "%s unit %d\n", __FUNCTION__
, unit
);
887 if ((texUnit
->TexGenEnabled
& (S_BIT
| T_BIT
| R_BIT
)) == 0) {
888 /* Disabled, no fallback:
890 rmesa
->TexGenInputs
|=
891 (R200_TEXGEN_INPUT_TEXCOORD_0
+ unit
) << inputshift
;
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:
897 /*fprintf(stderr, "fallback Q_BIT\n"); */
899 } else if (texUnit
->TexGenEnabled
== (S_BIT
| T_BIT
) &&
900 texUnit
->GenModeS
== texUnit
->GenModeT
) {
902 rmesa
->TexGenEnabled
|= R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
;
904 } else if (texUnit
->TexGenEnabled
== (S_BIT
| T_BIT
| R_BIT
) &&
905 texUnit
->GenModeS
== texUnit
->GenModeT
&&
906 texUnit
->GenModeT
== texUnit
->GenModeR
) {
908 rmesa
->TexGenEnabled
|= R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
;
911 /* Mixed modes, fallback:
913 /* fprintf(stderr, "fallback mixed texgen\n"); */
917 rmesa
->TexGenEnabled
|= R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
;
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
);
928 rmesa
->TexGenInputs
|= R200_TEXGEN_INPUT_EYE
<< inputshift
;
929 set_texgen_matrix(rmesa
, unit
,
931 texUnit
->EyePlaneT
, texUnit
->EyePlaneR
);
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
);
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
);
949 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
950 rmesa
->TexGenInputs
|= R200_TEXGEN_INPUT_SPHERE
<< inputshift
;
954 /* Unsupported mode, fallback:
956 /* fprintf(stderr, "fallback unsupported texgen\n"); */
960 rmesa
->TexGenCompSel
|= R200_OUTPUT_TEX_0
<< unit
;
962 if (tmp
!= rmesa
->TexGenEnabled
) {
963 //rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
969 static void disable_tex(GLcontext
* ctx
, int unit
)
971 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
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.
981 rmesa
->state
.texture
.unit
[unit
].texobj
->base
.bound
&=
983 rmesa
->state
.texture
.unit
[unit
].texobj
= NULL
;
986 R300_STATECHANGE(rmesa
, ctx
);
987 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~((R200_TEX_0_ENABLE
|
988 R200_TEX_BLEND_0_ENABLE
) <<
990 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_TEX_BLEND_0_ENABLE
;
992 R300_STATECHANGE(rmesa
, tcl
);
993 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_1
] &=
996 if (rmesa
->radeon
.TclFallback
& (RADEON_TCL_FALLBACK_TEXGEN_0
<< unit
)) {
997 TCL_FALLBACK(ctx
, (RADEON_TCL_FALLBACK_TEXGEN_0
<< unit
),
1001 /* Actually want to keep all units less than max active texture
1002 * enabled, right? Fix this for >2 texunits.
1004 /* FIXME: What should happen here if r300UpdateTextureEnv fails? */
1006 r300UpdateTextureEnv(ctx
, unit
);
1010 R200_TEXGEN_0_INPUT_SHIFT
+ unit
* 4;
1011 GLuint tmp
= rmesa
->TexGenEnabled
;
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
);
1023 if (tmp
!= rmesa
->TexGenEnabled
) {
1024 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1025 rmesa
->NewGLState
|= _NEW_TEXTURE_MATRIX
;
1032 static GLboolean
enable_tex_2d(GLcontext
* ctx
, int unit
)
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
;
1039 /* Need to load the 2d images associated with this unit.
1041 if (t
->format
& R200_TXFORMAT_NON_POWER2
) {
1042 t
->format
&= ~R200_TXFORMAT_NON_POWER2
;
1043 t
->base
.dirty_images
[0] = ~0;
1046 ASSERT(tObj
->Target
== GL_TEXTURE_2D
|| tObj
->Target
== GL_TEXTURE_1D
);
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
)
1059 #if ENABLE_HW_3D_TEXTURE
1060 static GLboolean
enable_tex_3d(GLcontext
* ctx
, int unit
)
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
;
1067 /* Need to load the 3d images associated with this unit.
1069 if (t
->format
& R200_TXFORMAT_NON_POWER2
) {
1070 t
->format
&= ~R200_TXFORMAT_NON_POWER2
;
1071 t
->base
.dirty_images
[0] = ~0;
1074 ASSERT(tObj
->Target
== GL_TEXTURE_3D
);
1076 /* R100 & R200 do not support mipmaps for 3D textures.
1078 if ((tObj
->MinFilter
!= GL_NEAREST
) && (tObj
->MinFilter
!= GL_LINEAR
)) {
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
)
1094 static GLboolean
enable_tex_cube(GLcontext
* ctx
, int unit
)
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
;
1102 /* Need to load the 2d images associated with this unit.
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;
1110 ASSERT(tObj
->Target
== GL_TEXTURE_CUBE_MAP
);
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]) {
1116 R300_FIREVERTICES(rmesa
);
1117 /* layout memory space, once for all faces */
1118 r300SetTexImages(rmesa
, tObj
);
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
,
1130 if (!t
->base
.memBlock
) {
1131 /* texmem alloc failed, use s/w fallback */
1138 static GLboolean
enable_tex_rect(GLcontext
* ctx
, int unit
)
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
;
1145 if (!(t
->format
& R200_TXFORMAT_NON_POWER2
)) {
1146 t
->format
|= R200_TXFORMAT_NON_POWER2
;
1147 t
->base
.dirty_images
[0] = ~0;
1150 ASSERT(tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
);
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
)
1163 static GLboolean
update_tex_common(GLcontext
* ctx
, int unit
)
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
;
1171 /* Fallback if there's a texture border */
1172 if (tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0)
1175 /* Update state if this is a different texture object to last
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.
1184 rmesa
->state
.texture
.unit
[unit
].texobj
->base
.bound
&=
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! */
1194 #if 0 /* do elsewhere ? */
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
) <<
1205 R300_STATECHANGE(rmesa
, vtx
);
1206 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_1
] |= 4 << (unit
* 3);
1208 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1211 if (t
->dirty_state
& (1 << unit
)) {
1212 import_tex_obj_state(rmesa
, unit
, t
);
1215 if (rmesa
->recheck_texgen
[unit
]) {
1216 GLboolean fallback
= !r300_validate_texgen(ctx
, unit
);
1217 TCL_FALLBACK(ctx
, (RADEON_TCL_FALLBACK_TEXGEN_0
<< unit
),
1219 rmesa
->recheck_texgen
[unit
] = 0;
1220 rmesa
->NewGLState
|= _NEW_TEXTURE_MATRIX
;
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
)) {
1234 FALLBACK(&rmesa
->radeon
, RADEON_FALLBACK_BORDER_MODE
, t
->border_fallback
);
1235 return !t
->border_fallback
;
1238 static GLboolean
r300UpdateTextureUnit(GLcontext
* ctx
, int unit
)
1240 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
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
));
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
));
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
) {
1261 disable_tex(ctx
, unit
);
1266 void r300UpdateTextureState(GLcontext
* ctx
)
1268 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
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)
1283 FALLBACK(&rmesa
->radeon
, RADEON_FALLBACK_TEXTURE
, !ok
);
1285 /* This needs correction, or just be done elsewhere
1286 if (rmesa->radeon.TclFallback)
1287 r300ChooseVertexState(ctx);
1290 #if 0 /* Workaround - disable.. */
1291 if (GET_CHIP(rmesa
->radeon
.radeonScreen
) == RADEON_CHIP_REAL_R200
) {
1293 * T0 hang workaround -------------
1294 * not needed for r300 derivatives?
1296 if ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_ENABLE_MASK
) ==
1298 && (rmesa
->hw
.tex
[0].
1299 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
) >
1300 R200_MIN_FILTER_LINEAR
) {
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;
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
] &=
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;
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;
1341 * Texture cache LRU hang workaround -------------
1342 * not needed for r300 derivatives?
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)
1350 || ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_2_ENABLE
)
1352 ((((rmesa
->hw
.tex
[2].
1353 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
1355 || ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_4_ENABLE
)
1357 ((((rmesa
->hw
.tex
[4].
1358 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
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)
1367 || ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_3_ENABLE
)
1369 ((((rmesa
->hw
.tex
[3].
1370 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
1372 || ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_5_ENABLE
)
1374 ((((rmesa
->hw
.tex
[5].
1375 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
1380 if (dbg
!= rmesa
->hw
.tam
.cmd
[TAM_DEBUG3
]) {
1381 R300_STATECHANGE(rmesa
, tam
);
1382 rmesa
->hw
.tam
.cmd
[TAM_DEBUG3
] = dbg
;
1384 printf("TEXCACHE LRU HANG WORKAROUND %x\n",