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 "r300_ioctl.h"
46 #include "radeon_ioctl.h"
47 //#include "r300_swtcl.h"
49 //#include "r300_tcl.h"
52 #define R200_TXFORMAT_A8 R200_TXFORMAT_I8
53 #define R200_TXFORMAT_L8 R200_TXFORMAT_I8
54 #define R200_TXFORMAT_AL88 R200_TXFORMAT_AI88
55 #define R200_TXFORMAT_YCBCR R200_TXFORMAT_YVYU422
56 #define R200_TXFORMAT_YCBCR_REV R200_TXFORMAT_VYUY422
59 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, 0 }
60 #define _COLOR_REV(f) \
61 [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f, 0 }
63 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
64 #define _ALPHA_REV(f) \
65 [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
67 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, R200_YUV_TO_RGB }
69 [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
70 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_YCBCR_REV) \
71 && (tx_table[f].format != 0xffffffff) )
74 GLuint format
, filter
;
91 _ALPHA(I8
), _INVALID(CI8
), _YUV(YCBCR
), _YUV(YCBCR_REV
),};
94 GLuint format
, filter
;
96 {R300_EASY_TX_FORMAT(Y
, Z
, W
, X
, W8Z8Y8X8
), 0},
124 * This function computes the number of bytes of storage needed for
125 * the given texture object (all mipmap levels, all cube faces).
126 * The \c image[face][level].x/y/width/height parameters for upload/blitting
127 * are computed here. \c filter, \c format, etc. will be set here
130 * \param rmesa Context pointer
131 * \param tObj GL texture object whose images are to be posted to
134 static void r300SetTexImages(r300ContextPtr rmesa
,
135 struct gl_texture_object
*tObj
)
137 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
138 const struct gl_texture_image
*baseImage
=
139 tObj
->Image
[0][tObj
->BaseLevel
];
143 GLint log2Width
, log2Height
, log2Depth
;
145 /* Set the hardware texture format
148 t
->format
&= ~(R200_TXFORMAT_FORMAT_MASK
|
149 R200_TXFORMAT_ALPHA_IN_MAP
);
151 t
->filter
&= ~R200_YUV_TO_RGB
;
153 if (VALID_FORMAT(baseImage
->TexFormat
->MesaFormat
)) {
155 tx_table
[baseImage
->TexFormat
->MesaFormat
].format
;
158 tx_table
[baseImage
->TexFormat
->MesaFormat
].filter
;
161 _mesa_problem(NULL
, "unexpected texture format in %s",
166 /* Compute which mipmap levels we really want to send to the hardware.
169 driCalculateTextureFirstLastLevel((driTextureObject
*) t
);
170 log2Width
= tObj
->Image
[0][t
->base
.firstLevel
]->WidthLog2
;
171 log2Height
= tObj
->Image
[0][t
->base
.firstLevel
]->HeightLog2
;
172 log2Depth
= tObj
->Image
[0][t
->base
.firstLevel
]->DepthLog2
;
174 numLevels
= t
->base
.lastLevel
- t
->base
.firstLevel
+ 1;
176 assert(numLevels
<= RADEON_MAX_TEXTURE_LEVELS
);
178 /* Calculate mipmap offsets and dimensions for blitting (uploading)
179 * The idea is that we lay out the mipmap levels within a block of
180 * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
184 for (i
= 0; i
< numLevels
; i
++) {
185 const struct gl_texture_image
*texImage
;
188 texImage
= tObj
->Image
[0][i
+ t
->base
.firstLevel
];
192 /* find image size in bytes */
193 if (texImage
->IsCompressed
) {
194 size
= texImage
->CompressedSize
;
195 } else if (tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
) {
198 texImage
->TexFormat
->TexelBytes
+ 63)
199 & ~63) * texImage
->Height
;
202 texImage
->Width
* texImage
->TexFormat
->TexelBytes
;
205 size
= w
* texImage
->Height
* texImage
->Depth
;
210 fprintf(stderr
, "w=%d h=%d d=%d tb=%d intFormat=%d\n", texImage
->Width
, texImage
->Height
,
211 texImage
->Depth
, texImage
->TexFormat
->TexelBytes
,
212 texImage
->IntFormat
);
214 /* Align to 32-byte offset. It is faster to do this unconditionally
215 * (no branch penalty).
218 curOffset
= (curOffset
+ 0x1f) & ~0x1f;
220 t
->image
[0][i
].x
= curOffset
% BLIT_WIDTH_BYTES
;
221 t
->image
[0][i
].y
= curOffset
/ BLIT_WIDTH_BYTES
;
222 t
->image
[0][i
].width
= MIN2(size
, BLIT_WIDTH_BYTES
);
223 t
->image
[0][i
].height
= size
/ t
->image
[0][i
].width
;
226 /* for debugging only and only applicable to non-rectangle targets */
227 assert(size
% t
->image
[0][i
].width
== 0);
228 assert(t
->image
[0][i
].x
== 0
229 || (size
< BLIT_WIDTH_BYTES
230 && t
->image
[0][i
].height
== 1));
235 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
236 i
, texImage
->Width
, texImage
->Height
,
237 t
->image
[0][i
].x
, t
->image
[0][i
].y
,
238 t
->image
[0][i
].width
, t
->image
[0][i
].height
,
245 /* Align the total size of texture memory block.
248 (curOffset
+ RADEON_OFFSET_MASK
) & ~RADEON_OFFSET_MASK
;
250 /* Setup remaining cube face blits, if needed */
251 if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
252 /* Round totalSize up to multiple of BLIT_WIDTH_BYTES */
253 const GLuint faceSize
=
254 (t
->base
.totalSize
+ BLIT_WIDTH_BYTES
- 1)
255 & ~(BLIT_WIDTH_BYTES
- 1);
256 const GLuint lines
= faceSize
/ BLIT_WIDTH_BYTES
;
258 /* reuse face 0 x/y/width/height - just adjust y */
259 for (face
= 1; face
< 6; face
++) {
260 for (i
= 0; i
< numLevels
; i
++) {
261 t
->image
[face
][i
].x
= t
->image
[0][i
].x
;
262 t
->image
[face
][i
].y
=
263 t
->image
[0][i
].y
+ face
* lines
;
264 t
->image
[face
][i
].width
= t
->image
[0][i
].width
;
265 t
->image
[face
][i
].height
=
266 t
->image
[0][i
].height
;
269 t
->base
.totalSize
= 6 * faceSize
; /* total texmem needed */
275 t
->filter
&= ~R200_MAX_MIP_LEVEL_MASK
;
276 t
->filter
|= (numLevels
- 1) << R200_MAX_MIP_LEVEL_SHIFT
;
279 t
->format
&= ~(R200_TXFORMAT_WIDTH_MASK
|
280 R200_TXFORMAT_HEIGHT_MASK
|
281 R200_TXFORMAT_CUBIC_MAP_ENABLE
|
282 R200_TXFORMAT_F5_WIDTH_MASK
|
283 R200_TXFORMAT_F5_HEIGHT_MASK
);
284 t
->format
|= ((log2Width
<< R200_TXFORMAT_WIDTH_SHIFT
) |
285 (log2Height
<< R200_TXFORMAT_HEIGHT_SHIFT
));
288 t
->format_x
&= ~(R200_DEPTH_LOG2_MASK
| R200_TEXCOORD_MASK
);
289 if (tObj
->Target
== GL_TEXTURE_3D
) {
290 t
->format_x
|= (log2Depth
<< R200_DEPTH_LOG2_SHIFT
);
291 t
->format_x
|= R200_TEXCOORD_VOLUME
;
292 } else if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
293 ASSERT(log2Width
== log2Height
);
294 t
->format
|= ((log2Width
<< R200_TXFORMAT_F5_WIDTH_SHIFT
) |
295 (log2Height
<< R200_TXFORMAT_F5_HEIGHT_SHIFT
)
296 | (R200_TXFORMAT_CUBIC_MAP_ENABLE
));
297 t
->format_x
|= R200_TEXCOORD_CUBIC_ENV
;
298 t
->pp_cubic_faces
= ((log2Width
<< R200_FACE_WIDTH_1_SHIFT
) |
299 (log2Height
<< R200_FACE_HEIGHT_1_SHIFT
) |
300 (log2Width
<< R200_FACE_WIDTH_2_SHIFT
) |
301 (log2Height
<< R200_FACE_HEIGHT_2_SHIFT
) |
302 (log2Width
<< R200_FACE_WIDTH_3_SHIFT
) |
303 (log2Height
<< R200_FACE_HEIGHT_3_SHIFT
) |
304 (log2Width
<< R200_FACE_WIDTH_4_SHIFT
) |
305 (log2Height
<< R200_FACE_HEIGHT_4_SHIFT
));
308 t
->size
= (((tObj
->Image
[0][t
->base
.firstLevel
]->Width
- 1) << R300_TX_WIDTHMASK_SHIFT
)
309 |((tObj
->Image
[0][t
->base
.firstLevel
]->Height
- 1) << R300_TX_HEIGHTMASK_SHIFT
)
310 |((log2Width
>log2Height
)?log2Width
:log2Height
)<<R300_TX_SIZE_SHIFT
);
312 /* Only need to round to nearest 32 for textures, but the blitter
313 * requires 64-byte aligned pitches, and we may/may not need the
314 * blitter. NPOT only!
316 if (baseImage
->IsCompressed
)
318 (tObj
->Image
[0][t
->base
.firstLevel
]->Width
+ 63) & ~(63);
321 ((tObj
->Image
[0][t
->base
.firstLevel
]->Width
*
322 baseImage
->TexFormat
->TexelBytes
) + 63) & ~(63);
325 t
->dirty_state
= TEX_ALL
;
327 /* FYI: r300UploadTexImages( rmesa, t ) used to be called here */
330 /* ================================================================
331 * Texture combine functions
334 /* GL_ARB_texture_env_combine support
337 /* The color tables have combine functions for GL_SRC_COLOR,
338 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
340 static GLuint r300_register_color
[][R200_MAX_TEXTURE_UNITS
] = {
342 R200_TXC_ARG_A_R0_COLOR
,
343 R200_TXC_ARG_A_R1_COLOR
,
344 R200_TXC_ARG_A_R2_COLOR
,
345 R200_TXC_ARG_A_R3_COLOR
,
346 R200_TXC_ARG_A_R4_COLOR
,
347 R200_TXC_ARG_A_R5_COLOR
},
349 R200_TXC_ARG_A_R0_COLOR
| R200_TXC_COMP_ARG_A
,
350 R200_TXC_ARG_A_R1_COLOR
| R200_TXC_COMP_ARG_A
,
351 R200_TXC_ARG_A_R2_COLOR
| R200_TXC_COMP_ARG_A
,
352 R200_TXC_ARG_A_R3_COLOR
| R200_TXC_COMP_ARG_A
,
353 R200_TXC_ARG_A_R4_COLOR
| R200_TXC_COMP_ARG_A
,
354 R200_TXC_ARG_A_R5_COLOR
| R200_TXC_COMP_ARG_A
},
356 R200_TXC_ARG_A_R0_ALPHA
,
357 R200_TXC_ARG_A_R1_ALPHA
,
358 R200_TXC_ARG_A_R2_ALPHA
,
359 R200_TXC_ARG_A_R3_ALPHA
,
360 R200_TXC_ARG_A_R4_ALPHA
,
361 R200_TXC_ARG_A_R5_ALPHA
},
363 R200_TXC_ARG_A_R0_ALPHA
| R200_TXC_COMP_ARG_A
,
364 R200_TXC_ARG_A_R1_ALPHA
| R200_TXC_COMP_ARG_A
,
365 R200_TXC_ARG_A_R2_ALPHA
| R200_TXC_COMP_ARG_A
,
366 R200_TXC_ARG_A_R3_ALPHA
| R200_TXC_COMP_ARG_A
,
367 R200_TXC_ARG_A_R4_ALPHA
| R200_TXC_COMP_ARG_A
,
368 R200_TXC_ARG_A_R5_ALPHA
| R200_TXC_COMP_ARG_A
},
371 static GLuint r300_tfactor_color
[] = {
372 R200_TXC_ARG_A_TFACTOR_COLOR
,
373 R200_TXC_ARG_A_TFACTOR_COLOR
| R200_TXC_COMP_ARG_A
,
374 R200_TXC_ARG_A_TFACTOR_ALPHA
,
375 R200_TXC_ARG_A_TFACTOR_ALPHA
| R200_TXC_COMP_ARG_A
378 static GLuint r300_primary_color
[] = {
379 R200_TXC_ARG_A_DIFFUSE_COLOR
,
380 R200_TXC_ARG_A_DIFFUSE_COLOR
| R200_TXC_COMP_ARG_A
,
381 R200_TXC_ARG_A_DIFFUSE_ALPHA
,
382 R200_TXC_ARG_A_DIFFUSE_ALPHA
| R200_TXC_COMP_ARG_A
385 /* GL_ZERO table - indices 0-3
386 * GL_ONE table - indices 1-4
388 static GLuint r300_zero_color
[] = {
390 R200_TXC_ARG_A_ZERO
| R200_TXC_COMP_ARG_A
,
392 R200_TXC_ARG_A_ZERO
| R200_TXC_COMP_ARG_A
,
396 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
398 static GLuint r300_register_alpha
[][R200_MAX_TEXTURE_UNITS
] = {
400 R200_TXA_ARG_A_R0_ALPHA
,
401 R200_TXA_ARG_A_R1_ALPHA
,
402 R200_TXA_ARG_A_R2_ALPHA
,
403 R200_TXA_ARG_A_R3_ALPHA
,
404 R200_TXA_ARG_A_R4_ALPHA
,
405 R200_TXA_ARG_A_R5_ALPHA
},
407 R200_TXA_ARG_A_R0_ALPHA
| R200_TXA_COMP_ARG_A
,
408 R200_TXA_ARG_A_R1_ALPHA
| R200_TXA_COMP_ARG_A
,
409 R200_TXA_ARG_A_R2_ALPHA
| R200_TXA_COMP_ARG_A
,
410 R200_TXA_ARG_A_R3_ALPHA
| R200_TXA_COMP_ARG_A
,
411 R200_TXA_ARG_A_R4_ALPHA
| R200_TXA_COMP_ARG_A
,
412 R200_TXA_ARG_A_R5_ALPHA
| R200_TXA_COMP_ARG_A
},
415 static GLuint r300_tfactor_alpha
[] = {
416 R200_TXA_ARG_A_TFACTOR_ALPHA
,
417 R200_TXA_ARG_A_TFACTOR_ALPHA
| R200_TXA_COMP_ARG_A
420 static GLuint r300_primary_alpha
[] = {
421 R200_TXA_ARG_A_DIFFUSE_ALPHA
,
422 R200_TXA_ARG_A_DIFFUSE_ALPHA
| R200_TXA_COMP_ARG_A
425 /* GL_ZERO table - indices 0-1
426 * GL_ONE table - indices 1-2
428 static GLuint r300_zero_alpha
[] = {
430 R200_TXA_ARG_A_ZERO
| R200_TXA_COMP_ARG_A
,
434 /* Extract the arg from slot A, shift it into the correct argument slot
435 * and set the corresponding complement bit.
437 #define R200_COLOR_ARG( n, arg ) \
440 ((color_arg[n] & R200_TXC_ARG_A_MASK) \
441 << R200_TXC_ARG_##arg##_SHIFT); \
443 ((color_arg[n] >> R200_TXC_COMP_ARG_A_SHIFT) \
444 << R200_TXC_COMP_ARG_##arg##_SHIFT); \
447 #define R200_ALPHA_ARG( n, arg ) \
450 ((alpha_arg[n] & R200_TXA_ARG_A_MASK) \
451 << R200_TXA_ARG_##arg##_SHIFT); \
453 ((alpha_arg[n] >> R200_TXA_COMP_ARG_A_SHIFT) \
454 << R200_TXA_COMP_ARG_##arg##_SHIFT); \
457 /* ================================================================
458 * Texture unit state management
461 static GLboolean
r300UpdateTextureEnv(GLcontext
* ctx
, int unit
)
463 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
464 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
465 GLuint color_combine
, alpha_combine
;
467 #if 0 /* disable for now.. */
468 GLuint color_scale
= rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXCBLEND2
] &
469 ~(R200_TXC_SCALE_MASK
);
470 GLuint alpha_scale
= rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXABLEND2
] &
471 ~(R200_TXA_DOT_ALPHA
| R200_TXA_SCALE_MASK
);
474 GLuint color_scale
=0, alpha_scale
=0;
476 /* texUnit->_Current can be NULL if and only if the texture unit is
477 * not actually enabled.
479 assert((texUnit
->_ReallyEnabled
== 0)
480 || (texUnit
->_Current
!= NULL
));
482 if (RADEON_DEBUG
& DEBUG_TEXTURE
) {
483 fprintf(stderr
, "%s( %p, %d )\n", __FUNCTION__
, (void *)ctx
,
487 /* Set the texture environment state. Isn't this nice and clean?
488 * The chip will automagically set the texture alpha to 0xff when
489 * the texture format does not include an alpha component. This
490 * reduces the amount of special-casing we have to do, alpha-only
491 * textures being a notable exception.
493 /* Don't cache these results.
496 rmesa
->state
.texture
.unit
[unit
].format
= 0;
498 rmesa
->state
.texture
.unit
[unit
].envMode
= 0;
501 if (!texUnit
->_ReallyEnabled
) {
504 R200_TXC_ARG_A_ZERO
| R200_TXC_ARG_B_ZERO
|
505 R200_TXC_ARG_C_DIFFUSE_COLOR
| R200_TXC_OP_MADD
;
507 R200_TXA_ARG_A_ZERO
| R200_TXA_ARG_B_ZERO
|
508 R200_TXA_ARG_C_DIFFUSE_ALPHA
| R200_TXA_OP_MADD
;
511 R200_TXC_ARG_A_ZERO
| R200_TXC_ARG_B_ZERO
|
512 R200_TXC_ARG_C_R0_COLOR
| R200_TXC_OP_MADD
;
514 R200_TXA_ARG_A_ZERO
| R200_TXA_ARG_B_ZERO
|
515 R200_TXA_ARG_C_R0_ALPHA
| R200_TXA_OP_MADD
;
518 GLuint color_arg
[3], alpha_arg
[3];
520 const GLuint numColorArgs
=
521 texUnit
->_CurrentCombine
->_NumArgsRGB
;
522 const GLuint numAlphaArgs
= texUnit
->_CurrentCombine
->_NumArgsA
;
523 GLuint RGBshift
= texUnit
->_CurrentCombine
->ScaleShiftRGB
;
524 GLuint Ashift
= texUnit
->_CurrentCombine
->ScaleShiftA
;
527 * Extract the color and alpha combine function arguments.
529 for (i
= 0; i
< numColorArgs
; i
++) {
531 texUnit
->_CurrentCombine
->OperandRGB
[i
] -
535 switch (texUnit
->_CurrentCombine
->SourceRGB
[i
]) {
537 color_arg
[i
] = r300_register_color
[op
][unit
];
540 color_arg
[i
] = r300_tfactor_color
[op
];
542 case GL_PRIMARY_COLOR
:
543 color_arg
[i
] = r300_primary_color
[op
];
547 color_arg
[i
] = r300_primary_color
[op
];
550 r300_register_color
[op
][0];
553 color_arg
[i
] = r300_zero_color
[op
];
556 color_arg
[i
] = r300_zero_color
[op
+ 1];
563 for (i
= 0; i
< numAlphaArgs
; i
++) {
565 texUnit
->_CurrentCombine
->OperandA
[i
] -
569 switch (texUnit
->_CurrentCombine
->SourceA
[i
]) {
571 alpha_arg
[i
] = r300_register_alpha
[op
][unit
];
574 alpha_arg
[i
] = r300_tfactor_alpha
[op
];
576 case GL_PRIMARY_COLOR
:
577 alpha_arg
[i
] = r300_primary_alpha
[op
];
581 alpha_arg
[i
] = r300_primary_alpha
[op
];
584 r300_register_alpha
[op
][0];
587 alpha_arg
[i
] = r300_zero_alpha
[op
];
590 alpha_arg
[i
] = r300_zero_alpha
[op
+ 1];
598 * Build up the color and alpha combine functions.
600 switch (texUnit
->_CurrentCombine
->ModeRGB
) {
602 color_combine
= (R200_TXC_ARG_A_ZERO
|
603 R200_TXC_ARG_B_ZERO
|
605 R200_COLOR_ARG(0, C
);
608 color_combine
= (R200_TXC_ARG_C_ZERO
|
610 R200_COLOR_ARG(0, A
);
611 R200_COLOR_ARG(1, B
);
614 color_combine
= (R200_TXC_ARG_B_ZERO
|
615 R200_TXC_COMP_ARG_B
|
617 R200_COLOR_ARG(0, A
);
618 R200_COLOR_ARG(1, C
);
621 color_combine
= (R200_TXC_ARG_B_ZERO
| R200_TXC_COMP_ARG_B
| R200_TXC_BIAS_ARG_C
| /* new */
622 R200_TXC_OP_MADD
); /* was ADDSIGNED */
623 R200_COLOR_ARG(0, A
);
624 R200_COLOR_ARG(1, C
);
627 color_combine
= (R200_TXC_ARG_B_ZERO
|
628 R200_TXC_COMP_ARG_B
|
629 R200_TXC_NEG_ARG_C
| R200_TXC_OP_MADD
);
630 R200_COLOR_ARG(0, A
);
631 R200_COLOR_ARG(1, C
);
634 color_combine
= (R200_TXC_OP_LERP
);
635 R200_COLOR_ARG(0, B
);
636 R200_COLOR_ARG(1, A
);
637 R200_COLOR_ARG(2, C
);
640 case GL_DOT3_RGB_EXT
:
641 case GL_DOT3_RGBA_EXT
:
642 /* The EXT version of the DOT3 extension does not support the
643 * scale factor, but the ARB version (and the version in OpenGL
651 /* DOT3 works differently on R200 than on R100. On R100, just
652 * setting the DOT3 mode did everything for you. On R200, the
653 * driver has to enable the biasing and scale in the inputs to
654 * put them in the proper [-1,1] range. This is what the 4x and
655 * the -0.5 in the DOT3 spec do. The post-scale is then set
659 color_combine
= (R200_TXC_ARG_C_ZERO
|
661 R200_TXC_BIAS_ARG_A
|
662 R200_TXC_BIAS_ARG_B
|
663 R200_TXC_SCALE_ARG_A
|
664 R200_TXC_SCALE_ARG_B
);
665 R200_COLOR_ARG(0, A
);
666 R200_COLOR_ARG(1, B
);
669 case GL_MODULATE_ADD_ATI
:
670 color_combine
= (R200_TXC_OP_MADD
);
671 R200_COLOR_ARG(0, A
);
672 R200_COLOR_ARG(1, C
);
673 R200_COLOR_ARG(2, B
);
675 case GL_MODULATE_SIGNED_ADD_ATI
:
676 color_combine
= (R200_TXC_BIAS_ARG_C
| /* new */
677 R200_TXC_OP_MADD
); /* was ADDSIGNED */
678 R200_COLOR_ARG(0, A
);
679 R200_COLOR_ARG(1, C
);
680 R200_COLOR_ARG(2, B
);
682 case GL_MODULATE_SUBTRACT_ATI
:
683 color_combine
= (R200_TXC_NEG_ARG_C
| R200_TXC_OP_MADD
);
684 R200_COLOR_ARG(0, A
);
685 R200_COLOR_ARG(1, C
);
686 R200_COLOR_ARG(2, B
);
692 switch (texUnit
->_CurrentCombine
->ModeA
) {
694 alpha_combine
= (R200_TXA_ARG_A_ZERO
|
695 R200_TXA_ARG_B_ZERO
|
697 R200_ALPHA_ARG(0, C
);
700 alpha_combine
= (R200_TXA_ARG_C_ZERO
|
702 R200_ALPHA_ARG(0, A
);
703 R200_ALPHA_ARG(1, B
);
706 alpha_combine
= (R200_TXA_ARG_B_ZERO
|
707 R200_TXA_COMP_ARG_B
|
709 R200_ALPHA_ARG(0, A
);
710 R200_ALPHA_ARG(1, C
);
713 alpha_combine
= (R200_TXA_ARG_B_ZERO
| R200_TXA_COMP_ARG_B
| R200_TXA_BIAS_ARG_C
| /* new */
714 R200_TXA_OP_MADD
); /* was ADDSIGNED */
715 R200_ALPHA_ARG(0, A
);
716 R200_ALPHA_ARG(1, C
);
719 alpha_combine
= (R200_TXA_ARG_B_ZERO
|
720 R200_TXA_COMP_ARG_B
|
721 R200_TXA_NEG_ARG_C
| R200_TXA_OP_MADD
);
722 R200_ALPHA_ARG(0, A
);
723 R200_ALPHA_ARG(1, C
);
726 alpha_combine
= (R200_TXA_OP_LERP
);
727 R200_ALPHA_ARG(0, B
);
728 R200_ALPHA_ARG(1, A
);
729 R200_ALPHA_ARG(2, C
);
732 case GL_MODULATE_ADD_ATI
:
733 alpha_combine
= (R200_TXA_OP_MADD
);
734 R200_ALPHA_ARG(0, A
);
735 R200_ALPHA_ARG(1, C
);
736 R200_ALPHA_ARG(2, B
);
738 case GL_MODULATE_SIGNED_ADD_ATI
:
739 alpha_combine
= (R200_TXA_BIAS_ARG_C
| /* new */
740 R200_TXA_OP_MADD
); /* was ADDSIGNED */
741 R200_ALPHA_ARG(0, A
);
742 R200_ALPHA_ARG(1, C
);
743 R200_ALPHA_ARG(2, B
);
745 case GL_MODULATE_SUBTRACT_ATI
:
746 alpha_combine
= (R200_TXA_NEG_ARG_C
| R200_TXA_OP_MADD
);
747 R200_ALPHA_ARG(0, A
);
748 R200_ALPHA_ARG(1, C
);
749 R200_ALPHA_ARG(2, B
);
755 if ((texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGBA_EXT
)
756 || (texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGBA
)) {
757 alpha_scale
|= R200_TXA_DOT_ALPHA
;
762 * Apply the scale factor.
764 color_scale
|= (RGBshift
<< R200_TXC_SCALE_SHIFT
);
765 alpha_scale
|= (Ashift
<< R200_TXA_SCALE_SHIFT
);
772 fprintf(stderr
, "color_combine=%08x alpha_combine=%08x color_scale=%08x alpha_scale=%08x\n",
773 color_combine
, alpha_combine
, color_scale
, alpha_scale
);
777 if (rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXCBLEND
] != color_combine
||
778 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXABLEND
] != alpha_combine
||
779 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXCBLEND2
] != color_scale
||
780 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXABLEND2
] != alpha_scale
) {
781 R300_STATECHANGE(rmesa
, pix
[unit
]);
782 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXCBLEND
] = color_combine
;
783 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXABLEND
] = alpha_combine
;
784 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXCBLEND2
] = color_scale
;
785 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXABLEND2
] = alpha_scale
;
793 #define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK | \
794 R200_MIN_FILTER_MASK | \
795 R200_MAG_FILTER_MASK | \
796 R200_MAX_ANISO_MASK | \
798 R200_YUV_TEMPERATURE_MASK | \
799 R200_CLAMP_S_MASK | \
800 R200_CLAMP_T_MASK | \
801 R200_BORDER_MODE_D3D )
803 #define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK | \
804 R200_TXFORMAT_HEIGHT_MASK | \
805 R200_TXFORMAT_FORMAT_MASK | \
806 R200_TXFORMAT_F5_WIDTH_MASK | \
807 R200_TXFORMAT_F5_HEIGHT_MASK | \
808 R200_TXFORMAT_ALPHA_IN_MAP | \
809 R200_TXFORMAT_CUBIC_MAP_ENABLE | \
810 R200_TXFORMAT_NON_POWER2)
812 #define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK | \
813 R200_TEXCOORD_MASK | \
814 R200_CLAMP_Q_MASK | \
815 R200_VOLUME_FILTER_MASK)
817 static void import_tex_obj_state(r300ContextPtr rmesa
,
818 int unit
, r300TexObjPtr texobj
)
820 #if 0 /* needs fixing.. or should be done elsewhere */
821 GLuint
*cmd
= R300_DB_STATE(tex
[unit
]);
823 cmd
[TEX_PP_TXFILTER
] &= ~TEXOBJ_TXFILTER_MASK
;
824 cmd
[TEX_PP_TXFILTER
] |= texobj
->filter
& TEXOBJ_TXFILTER_MASK
;
825 cmd
[TEX_PP_TXFORMAT
] &= ~TEXOBJ_TXFORMAT_MASK
;
826 cmd
[TEX_PP_TXFORMAT
] |= texobj
->format
& TEXOBJ_TXFORMAT_MASK
;
827 cmd
[TEX_PP_TXFORMAT_X
] &= ~TEXOBJ_TXFORMAT_X_MASK
;
828 cmd
[TEX_PP_TXFORMAT_X
] |=
829 texobj
->format_x
& TEXOBJ_TXFORMAT_X_MASK
;
830 cmd
[TEX_PP_TXSIZE
] = texobj
->size
; /* NPOT only! */
831 cmd
[TEX_PP_TXPITCH
] = texobj
->pitch
; /* NPOT only! */
832 cmd
[TEX_PP_TXOFFSET
] = texobj
->pp_txoffset
;
833 cmd
[TEX_PP_BORDER_COLOR
] = texobj
->pp_border_color
;
834 R200_DB_STATECHANGE(rmesa
, &rmesa
->hw
.tex
[unit
]);
836 if (texobj
->base
.tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
837 GLuint
*cube_cmd
= R200_DB_STATE(cube
[unit
]);
838 GLuint bytesPerFace
= texobj
->base
.totalSize
/ 6;
839 ASSERT(texobj
->totalSize
% 6 == 0);
840 cube_cmd
[CUBE_PP_CUBIC_FACES
] = texobj
->pp_cubic_faces
;
841 cube_cmd
[CUBE_PP_CUBIC_OFFSET_F1
] =
842 texobj
->pp_txoffset
+ 1 * bytesPerFace
;
843 cube_cmd
[CUBE_PP_CUBIC_OFFSET_F2
] =
844 texobj
->pp_txoffset
+ 2 * bytesPerFace
;
845 cube_cmd
[CUBE_PP_CUBIC_OFFSET_F3
] =
846 texobj
->pp_txoffset
+ 3 * bytesPerFace
;
847 cube_cmd
[CUBE_PP_CUBIC_OFFSET_F4
] =
848 texobj
->pp_txoffset
+ 4 * bytesPerFace
;
849 cube_cmd
[CUBE_PP_CUBIC_OFFSET_F5
] =
850 texobj
->pp_txoffset
+ 5 * bytesPerFace
;
851 R200_DB_STATECHANGE(rmesa
, &rmesa
->hw
.cube
[unit
]);
854 texobj
->dirty_state
&= ~(1 << unit
);
858 static void set_texgen_matrix(r300ContextPtr rmesa
,
860 const GLfloat
* s_plane
,
861 const GLfloat
* t_plane
, const GLfloat
* r_plane
)
863 static const GLfloat scale_identity
[4] = { 1, 1, 1, 1 };
865 if (!TEST_EQ_4V(s_plane
, scale_identity
) ||
866 !TEST_EQ_4V(t_plane
, scale_identity
) ||
867 !TEST_EQ_4V(r_plane
, scale_identity
)) {
868 rmesa
->TexGenEnabled
|= R200_TEXMAT_0_ENABLE
<< unit
;
869 rmesa
->TexGenMatrix
[unit
].m
[0] = s_plane
[0];
870 rmesa
->TexGenMatrix
[unit
].m
[4] = s_plane
[1];
871 rmesa
->TexGenMatrix
[unit
].m
[8] = s_plane
[2];
872 rmesa
->TexGenMatrix
[unit
].m
[12] = s_plane
[3];
874 rmesa
->TexGenMatrix
[unit
].m
[1] = t_plane
[0];
875 rmesa
->TexGenMatrix
[unit
].m
[5] = t_plane
[1];
876 rmesa
->TexGenMatrix
[unit
].m
[9] = t_plane
[2];
877 rmesa
->TexGenMatrix
[unit
].m
[13] = t_plane
[3];
879 /* NOTE: r_plane goes in the 4th row, not 3rd! */
880 rmesa
->TexGenMatrix
[unit
].m
[3] = r_plane
[0];
881 rmesa
->TexGenMatrix
[unit
].m
[7] = r_plane
[1];
882 rmesa
->TexGenMatrix
[unit
].m
[11] = r_plane
[2];
883 rmesa
->TexGenMatrix
[unit
].m
[15] = r_plane
[3];
885 //rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
889 /* Need this special matrix to get correct reflection map coords */
890 static void set_texgen_reflection_matrix(r300ContextPtr rmesa
, GLuint unit
)
892 static const GLfloat m
[16] = {
898 _math_matrix_loadf(&(rmesa
->TexGenMatrix
[unit
]), m
);
899 _math_matrix_analyse(&(rmesa
->TexGenMatrix
[unit
]));
900 rmesa
->TexGenEnabled
|= R200_TEXMAT_0_ENABLE
<< unit
;
903 /* Need this special matrix to get correct normal map coords */
904 static void set_texgen_normal_map_matrix(r300ContextPtr rmesa
, GLuint unit
)
906 static const GLfloat m
[16] = {
912 _math_matrix_loadf(&(rmesa
->TexGenMatrix
[unit
]), m
);
913 _math_matrix_analyse(&(rmesa
->TexGenMatrix
[unit
]));
914 rmesa
->TexGenEnabled
|= R200_TEXMAT_0_ENABLE
<< unit
;
917 /* Ignoring the Q texcoord for now.
919 * Returns GL_FALSE if fallback required.
921 static GLboolean
r300_validate_texgen(GLcontext
* ctx
, GLuint unit
)
923 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
924 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
925 GLuint inputshift
= R200_TEXGEN_0_INPUT_SHIFT
+ unit
* 4;
926 GLuint tmp
= rmesa
->TexGenEnabled
;
928 rmesa
->TexGenCompSel
&= ~(R200_OUTPUT_TEX_0
<< unit
);
929 rmesa
->TexGenEnabled
&= ~(R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
);
930 rmesa
->TexGenEnabled
&= ~(R200_TEXMAT_0_ENABLE
<< unit
);
931 rmesa
->TexGenInputs
&= ~(R200_TEXGEN_INPUT_MASK
<< inputshift
);
932 rmesa
->TexGenNeedNormals
[unit
] = 0;
935 fprintf(stderr
, "%s unit %d\n", __FUNCTION__
, unit
);
937 if ((texUnit
->TexGenEnabled
& (S_BIT
| T_BIT
| R_BIT
)) == 0) {
938 /* Disabled, no fallback:
940 rmesa
->TexGenInputs
|=
941 (R200_TEXGEN_INPUT_TEXCOORD_0
+ unit
) << inputshift
;
943 } else if (texUnit
->TexGenEnabled
& Q_BIT
) {
944 /* Very easy to do this, in fact would remove a fallback case
945 * elsewhere, but I haven't done it yet... Fallback:
947 /*fprintf(stderr, "fallback Q_BIT\n"); */
949 } else if (texUnit
->TexGenEnabled
== (S_BIT
| T_BIT
) &&
950 texUnit
->GenModeS
== texUnit
->GenModeT
) {
952 rmesa
->TexGenEnabled
|= R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
;
954 } else if (texUnit
->TexGenEnabled
== (S_BIT
| T_BIT
| R_BIT
) &&
955 texUnit
->GenModeS
== texUnit
->GenModeT
&&
956 texUnit
->GenModeT
== texUnit
->GenModeR
) {
958 rmesa
->TexGenEnabled
|= R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
;
961 /* Mixed modes, fallback:
963 /* fprintf(stderr, "fallback mixed texgen\n"); */
967 rmesa
->TexGenEnabled
|= R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
;
969 switch (texUnit
->GenModeS
) {
970 case GL_OBJECT_LINEAR
:
971 rmesa
->TexGenInputs
|= R200_TEXGEN_INPUT_OBJ
<< inputshift
;
972 set_texgen_matrix(rmesa
, unit
,
973 texUnit
->ObjectPlaneS
,
974 texUnit
->ObjectPlaneT
, texUnit
->ObjectPlaneR
);
978 rmesa
->TexGenInputs
|= R200_TEXGEN_INPUT_EYE
<< inputshift
;
979 set_texgen_matrix(rmesa
, unit
,
981 texUnit
->EyePlaneT
, texUnit
->EyePlaneR
);
984 case GL_REFLECTION_MAP_NV
:
985 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
986 rmesa
->TexGenInputs
|=
987 R200_TEXGEN_INPUT_EYE_REFLECT
<< inputshift
;
988 set_texgen_reflection_matrix(rmesa
, unit
);
991 case GL_NORMAL_MAP_NV
:
992 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
993 rmesa
->TexGenInputs
|=
994 R200_TEXGEN_INPUT_EYE_NORMAL
<< inputshift
;
995 set_texgen_normal_map_matrix(rmesa
, unit
);
999 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
1000 rmesa
->TexGenInputs
|= R200_TEXGEN_INPUT_SPHERE
<< inputshift
;
1004 /* Unsupported mode, fallback:
1006 /* fprintf(stderr, "fallback unsupported texgen\n"); */
1010 rmesa
->TexGenCompSel
|= R200_OUTPUT_TEX_0
<< unit
;
1012 if (tmp
!= rmesa
->TexGenEnabled
) {
1013 //rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
1019 static void disable_tex(GLcontext
* ctx
, int unit
)
1021 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1023 #if 0 /* This needs to be redone.. or done elsewhere */
1024 if (rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & (R200_TEX_0_ENABLE
<< unit
)) {
1025 /* Texture unit disabled */
1026 if (rmesa
->state
.texture
.unit
[unit
].texobj
!= NULL
) {
1027 /* The old texture is no longer bound to this texture unit.
1031 rmesa
->state
.texture
.unit
[unit
].texobj
->base
.bound
&=
1033 rmesa
->state
.texture
.unit
[unit
].texobj
= NULL
;
1036 R300_STATECHANGE(rmesa
, ctx
);
1037 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~((R200_TEX_0_ENABLE
|
1038 R200_TEX_BLEND_0_ENABLE
) <<
1040 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_TEX_BLEND_0_ENABLE
;
1042 R300_STATECHANGE(rmesa
, tcl
);
1043 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_1
] &=
1046 if (rmesa
->radeon
.TclFallback
& (RADEON_TCL_FALLBACK_TEXGEN_0
<< unit
)) {
1047 TCL_FALLBACK(ctx
, (RADEON_TCL_FALLBACK_TEXGEN_0
<< unit
),
1051 /* Actually want to keep all units less than max active texture
1052 * enabled, right? Fix this for >2 texunits.
1054 /* FIXME: What should happen here if r300UpdateTextureEnv fails? */
1056 r300UpdateTextureEnv(ctx
, unit
);
1060 R200_TEXGEN_0_INPUT_SHIFT
+ unit
* 4;
1061 GLuint tmp
= rmesa
->TexGenEnabled
;
1063 rmesa
->TexGenEnabled
&=
1064 ~(R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
);
1065 rmesa
->TexGenEnabled
&= ~(R200_TEXMAT_0_ENABLE
<< unit
);
1066 rmesa
->TexGenEnabled
&=
1067 ~(R200_TEXGEN_INPUT_MASK
<< inputshift
);
1068 rmesa
->TexGenNeedNormals
[unit
] = 0;
1069 rmesa
->TexGenCompSel
&= ~(R200_OUTPUT_TEX_0
<< unit
);
1070 rmesa
->TexGenInputs
&=
1071 ~(R200_TEXGEN_INPUT_MASK
<< inputshift
);
1073 if (tmp
!= rmesa
->TexGenEnabled
) {
1074 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1075 rmesa
->NewGLState
|= _NEW_TEXTURE_MATRIX
;
1082 static GLboolean
enable_tex_2d(GLcontext
* ctx
, int unit
)
1084 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1085 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1086 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1087 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
1089 /* Need to load the 2d images associated with this unit.
1091 if (t
->format
& R200_TXFORMAT_NON_POWER2
) {
1092 t
->format
&= ~R200_TXFORMAT_NON_POWER2
;
1093 t
->base
.dirty_images
[0] = ~0;
1096 ASSERT(tObj
->Target
== GL_TEXTURE_2D
|| tObj
->Target
== GL_TEXTURE_1D
);
1098 if (t
->base
.dirty_images
[0]) {
1099 R300_FIREVERTICES(rmesa
);
1100 r300SetTexImages(rmesa
, tObj
);
1101 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
1102 if (!t
->base
.memBlock
)
1109 #if ENABLE_HW_3D_TEXTURE
1110 static GLboolean
enable_tex_3d(GLcontext
* ctx
, int unit
)
1112 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1113 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1114 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1115 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
1117 /* Need to load the 3d images associated with this unit.
1119 if (t
->format
& R200_TXFORMAT_NON_POWER2
) {
1120 t
->format
&= ~R200_TXFORMAT_NON_POWER2
;
1121 t
->base
.dirty_images
[0] = ~0;
1124 ASSERT(tObj
->Target
== GL_TEXTURE_3D
);
1126 /* R100 & R200 do not support mipmaps for 3D textures.
1128 if ((tObj
->MinFilter
!= GL_NEAREST
) && (tObj
->MinFilter
!= GL_LINEAR
)) {
1132 if (t
->base
.dirty_images
[0]) {
1133 R300_FIREVERTICES(rmesa
);
1134 r300SetTexImages(rmesa
, tObj
);
1135 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
1136 if (!t
->base
.memBlock
)
1144 static GLboolean
enable_tex_cube(GLcontext
* ctx
, int unit
)
1146 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1147 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1148 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1149 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
1152 /* Need to load the 2d images associated with this unit.
1154 if (t
->format
& R200_TXFORMAT_NON_POWER2
) {
1155 t
->format
&= ~R200_TXFORMAT_NON_POWER2
;
1156 for (face
= 0; face
< 6; face
++)
1157 t
->base
.dirty_images
[face
] = ~0;
1160 ASSERT(tObj
->Target
== GL_TEXTURE_CUBE_MAP
);
1162 if (t
->base
.dirty_images
[0] || t
->base
.dirty_images
[1] ||
1163 t
->base
.dirty_images
[2] || t
->base
.dirty_images
[3] ||
1164 t
->base
.dirty_images
[4] || t
->base
.dirty_images
[5]) {
1166 R300_FIREVERTICES(rmesa
);
1167 /* layout memory space, once for all faces */
1168 r300SetTexImages(rmesa
, tObj
);
1171 /* upload (per face) */
1172 for (face
= 0; face
< 6; face
++) {
1173 if (t
->base
.dirty_images
[face
]) {
1174 r300UploadTexImages(rmesa
,
1175 (r300TexObjPtr
) tObj
->DriverData
,
1180 if (!t
->base
.memBlock
) {
1181 /* texmem alloc failed, use s/w fallback */
1188 static GLboolean
enable_tex_rect(GLcontext
* ctx
, int unit
)
1190 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1191 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1192 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1193 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
1195 if (!(t
->format
& R200_TXFORMAT_NON_POWER2
)) {
1196 t
->format
|= R200_TXFORMAT_NON_POWER2
;
1197 t
->base
.dirty_images
[0] = ~0;
1200 ASSERT(tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
);
1202 if (t
->base
.dirty_images
[0]) {
1203 R300_FIREVERTICES(rmesa
);
1204 r300SetTexImages(rmesa
, tObj
);
1205 r300UploadTexImages(rmesa
, (r300TexObjPtr
) tObj
->DriverData
, 0);
1206 if (!t
->base
.memBlock
&& !rmesa
->prefer_gart_client_texturing
)
1213 static GLboolean
update_tex_common(GLcontext
* ctx
, int unit
)
1215 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1216 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1217 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1218 r300TexObjPtr t
= (r300TexObjPtr
) tObj
->DriverData
;
1221 /* Fallback if there's a texture border */
1222 if (tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0)
1225 /* Update state if this is a different texture object to last
1228 if (rmesa
->state
.texture
.unit
[unit
].texobj
!= t
) {
1229 if (rmesa
->state
.texture
.unit
[unit
].texobj
!= NULL
) {
1230 /* The old texture is no longer bound to this texture unit.
1234 rmesa
->state
.texture
.unit
[unit
].texobj
->base
.bound
&=
1238 rmesa
->state
.texture
.unit
[unit
].texobj
= t
;
1239 t
->base
.bound
|= (1UL << unit
);
1240 t
->dirty_state
|= 1 << unit
;
1241 driUpdateTextureLRU((driTextureObject
*) t
); /* XXX: should be locked! */
1244 #if 0 /* do elsewhere ? */
1249 cmd
[CTX_PP_CNTL
] & (R200_TEX_0_ENABLE
<< unit
))) {
1250 R300_STATECHANGE(rmesa
, ctx
);
1251 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= (R200_TEX_0_ENABLE
|
1252 R200_TEX_BLEND_0_ENABLE
) <<
1255 R300_STATECHANGE(rmesa
, vtx
);
1256 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_1
] |= 4 << (unit
* 3);
1258 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1261 if (t
->dirty_state
& (1 << unit
)) {
1262 import_tex_obj_state(rmesa
, unit
, t
);
1265 if (rmesa
->recheck_texgen
[unit
]) {
1266 GLboolean fallback
= !r300_validate_texgen(ctx
, unit
);
1267 TCL_FALLBACK(ctx
, (RADEON_TCL_FALLBACK_TEXGEN_0
<< unit
),
1269 rmesa
->recheck_texgen
[unit
] = 0;
1270 rmesa
->NewGLState
|= _NEW_TEXTURE_MATRIX
;
1274 format
= tObj
->Image
[0][tObj
->BaseLevel
]->Format
;
1275 if (rmesa
->state
.texture
.unit
[unit
].format
!= format
||
1276 rmesa
->state
.texture
.unit
[unit
].envMode
!= texUnit
->EnvMode
) {
1277 //rmesa->state.texture.unit[unit].format = format;
1278 rmesa
->state
.texture
.unit
[unit
].envMode
= texUnit
->EnvMode
;
1279 if (!r300UpdateTextureEnv(ctx
, unit
)) {
1284 FALLBACK(&rmesa
->radeon
, RADEON_FALLBACK_BORDER_MODE
, t
->border_fallback
);
1285 return !t
->border_fallback
;
1288 static GLboolean
r300UpdateTextureUnit(GLcontext
* ctx
, int unit
)
1290 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1292 if (texUnit
->_ReallyEnabled
& (TEXTURE_RECT_BIT
)) {
1293 return (enable_tex_rect(ctx
, unit
) &&
1294 update_tex_common(ctx
, unit
));
1295 } else if (texUnit
->_ReallyEnabled
& (TEXTURE_1D_BIT
| TEXTURE_2D_BIT
)) {
1296 return (enable_tex_2d(ctx
, unit
) &&
1297 update_tex_common(ctx
, unit
));
1299 #if ENABLE_HW_3D_TEXTURE
1300 else if (texUnit
->_ReallyEnabled
& (TEXTURE_3D_BIT
)) {
1301 return (enable_tex_3d(ctx
, unit
) &&
1302 update_tex_common(ctx
, unit
));
1305 else if (texUnit
->_ReallyEnabled
& (TEXTURE_CUBE_BIT
)) {
1306 return (enable_tex_cube(ctx
, unit
) &&
1307 update_tex_common(ctx
, unit
));
1308 } else if (texUnit
->_ReallyEnabled
) {
1311 disable_tex(ctx
, unit
);
1316 void r300UpdateTextureState(GLcontext
* ctx
)
1318 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1323 ok
= (r300UpdateTextureUnit(ctx
, 0) &&
1324 r300UpdateTextureUnit(ctx
, 1) &&
1325 r300UpdateTextureUnit(ctx
, 2) &&
1326 r300UpdateTextureUnit(ctx
, 3) &&
1327 r300UpdateTextureUnit(ctx
, 4) &&
1328 r300UpdateTextureUnit(ctx
, 5) &&
1329 r300UpdateTextureUnit(ctx
, 6) &&
1330 r300UpdateTextureUnit(ctx
, 7)
1333 FALLBACK(&rmesa
->radeon
, RADEON_FALLBACK_TEXTURE
, !ok
);
1335 /* This needs correction, or just be done elsewhere
1336 if (rmesa->radeon.TclFallback)
1337 r300ChooseVertexState(ctx);
1340 #if 0 /* Workaround - disable.. */
1341 if (GET_CHIP(rmesa
->radeon
.radeonScreen
) == RADEON_CHIP_REAL_R200
) {
1343 * T0 hang workaround -------------
1344 * not needed for r200 derivatives?
1346 if ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_ENABLE_MASK
) ==
1348 && (rmesa
->hw
.tex
[0].
1349 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
) >
1350 R200_MIN_FILTER_LINEAR
) {
1352 R300_STATECHANGE(rmesa
, ctx
);
1353 R300_STATECHANGE(rmesa
, tex
[1]);
1354 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_TEX_1_ENABLE
;
1355 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] &=
1356 ~TEXOBJ_TXFORMAT_MASK
;
1357 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] |= 0x08000000;
1359 if ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_1_ENABLE
)
1360 && (rmesa
->hw
.tex
[1].
1361 cmd
[TEX_PP_TXFORMAT
] & 0x08000000)) {
1362 R300_STATECHANGE(rmesa
, tex
[1]);
1363 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] &=
1368 /* maybe needs to be done pairwise due to 2 parallel (physical) tex units ?
1369 looks like that's not the case, if 8500/9100 owners don't complain remove this...
1370 for ( i = 0; i < ctx->Const.MaxTextureUnits; i += 2) {
1371 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & ((R200_TEX_0_ENABLE |
1372 R200_TEX_1_ENABLE ) << i)) == (R200_TEX_0_ENABLE << i)) &&
1373 ((rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) >
1374 R200_MIN_FILTER_LINEAR)) {
1375 R300_STATECHANGE(rmesa, ctx);
1376 R300_STATECHANGE(rmesa, tex[i+1]);
1377 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_1_ENABLE << i);
1378 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1379 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] |= 0x08000000;
1382 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE << i)) &&
1383 (rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) {
1384 R300_STATECHANGE(rmesa, tex[i+1]);
1385 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000;
1391 * Texture cache LRU hang workaround -------------
1392 * not needed for r200 derivatives?
1396 if (((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & (R200_TEX_0_ENABLE
)) &&
1397 ((((rmesa
->hw
.tex
[0].
1398 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) & 0x04)
1400 || ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_2_ENABLE
)
1402 ((((rmesa
->hw
.tex
[2].
1403 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
1405 || ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_4_ENABLE
)
1407 ((((rmesa
->hw
.tex
[4].
1408 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
1413 if (((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & (R200_TEX_1_ENABLE
)) &&
1414 ((((rmesa
->hw
.tex
[1].
1415 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) & 0x04)
1417 || ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_3_ENABLE
)
1419 ((((rmesa
->hw
.tex
[3].
1420 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
1422 || ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_5_ENABLE
)
1424 ((((rmesa
->hw
.tex
[5].
1425 cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
1430 if (dbg
!= rmesa
->hw
.tam
.cmd
[TAM_DEBUG3
]) {
1431 R300_STATECHANGE(rmesa
, tam
);
1432 rmesa
->hw
.tam
.cmd
[TAM_DEBUG3
] = dbg
;
1434 printf("TEXCACHE LRU HANG WORKAROUND %x\n",