1 /* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_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 "r200_context.h"
44 #include "r200_state.h"
45 #include "r200_ioctl.h"
46 #include "r200_swtcl.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
56 #define R200_TXFORMAT_RGB_DXT1 R200_TXFORMAT_DXT1
57 #define R200_TXFORMAT_RGBA_DXT1 R200_TXFORMAT_DXT1
58 #define R200_TXFORMAT_RGBA_DXT3 R200_TXFORMAT_DXT23
59 #define R200_TXFORMAT_RGBA_DXT5 R200_TXFORMAT_DXT45
62 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, 0 }
63 #define _COLOR_REV(f) \
64 [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f, 0 }
66 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
67 #define _ALPHA_REV(f) \
68 [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
70 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, R200_YUV_TO_RGB }
72 [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
73 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \
74 && (tx_table[f].format != 0xffffffff) )
77 GLuint format
, filter
;
113 * This function computes the number of bytes of storage needed for
114 * the given texture object (all mipmap levels, all cube faces).
115 * The \c image[face][level].x/y/width/height parameters for upload/blitting
116 * are computed here. \c pp_txfilter, \c pp_txformat, etc. will be set here
119 * \param rmesa Context pointer
120 * \param tObj GL texture object whose images are to be posted to
123 static void r200SetTexImages( r200ContextPtr rmesa
,
124 struct gl_texture_object
*tObj
)
126 r200TexObjPtr t
= (r200TexObjPtr
)tObj
->DriverData
;
127 const struct gl_texture_image
*baseImage
= tObj
->Image
[0][tObj
->BaseLevel
];
131 GLint log2Width
, log2Height
, log2Depth
;
133 /* Set the hardware texture format
136 t
->pp_txformat
&= ~(R200_TXFORMAT_FORMAT_MASK
|
137 R200_TXFORMAT_ALPHA_IN_MAP
);
138 t
->pp_txfilter
&= ~R200_YUV_TO_RGB
;
140 if ( VALID_FORMAT( baseImage
->TexFormat
->MesaFormat
) ) {
141 t
->pp_txformat
|= tx_table
[ baseImage
->TexFormat
->MesaFormat
].format
;
142 t
->pp_txfilter
|= tx_table
[ baseImage
->TexFormat
->MesaFormat
].filter
;
145 _mesa_problem(NULL
, "unexpected texture format in %s", __FUNCTION__
);
150 /* Compute which mipmap levels we really want to send to the hardware.
153 driCalculateTextureFirstLastLevel( (driTextureObject
*) t
);
154 log2Width
= tObj
->Image
[0][t
->base
.firstLevel
]->WidthLog2
;
155 log2Height
= tObj
->Image
[0][t
->base
.firstLevel
]->HeightLog2
;
156 log2Depth
= tObj
->Image
[0][t
->base
.firstLevel
]->DepthLog2
;
158 numLevels
= t
->base
.lastLevel
- t
->base
.firstLevel
+ 1;
160 assert(numLevels
<= RADEON_MAX_TEXTURE_LEVELS
);
162 /* Calculate mipmap offsets and dimensions for blitting (uploading)
163 * The idea is that we lay out the mipmap levels within a block of
164 * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
168 for (i
= 0; i
< numLevels
; i
++) {
169 const struct gl_texture_image
*texImage
;
172 texImage
= tObj
->Image
[0][i
+ t
->base
.firstLevel
];
176 /* find image size in bytes */
177 if (texImage
->IsCompressed
) {
178 /* need to calculate the size AFTER padding even though the texture is
179 submitted without padding.
180 Only handle pot textures currently - don't know if npot is even possible,
181 size calculation would certainly need (trivial) adjustments.
182 Align (and later pad) to 32byte, not sure what that 64byte blit width is
184 if ((t
->pp_txformat
& R200_TXFORMAT_FORMAT_MASK
) == R200_TXFORMAT_DXT1
) {
185 /* RGB_DXT1/RGBA_DXT1, 8 bytes per block */
186 if ((texImage
->Width
+ 3) < 8) /* width one block */
187 size
= texImage
->CompressedSize
* 4;
188 else if ((texImage
->Width
+ 3) < 16)
189 size
= texImage
->CompressedSize
* 2;
190 else size
= texImage
->CompressedSize
;
192 else /* DXT3/5, 16 bytes per block */
193 if ((texImage
->Width
+ 3) < 8)
194 size
= texImage
->CompressedSize
* 2;
195 else size
= texImage
->CompressedSize
;
197 else if (tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
) {
198 size
= ((texImage
->Width
* texImage
->TexFormat
->TexelBytes
+ 63)
199 & ~63) * texImage
->Height
;
202 int w
= texImage
->Width
* texImage
->TexFormat
->TexelBytes
;
205 size
= w
* texImage
->Height
* texImage
->Depth
;
210 /* Align to 32-byte offset. It is faster to do this unconditionally
211 * (no branch penalty).
214 curOffset
= (curOffset
+ 0x1f) & ~0x1f;
216 t
->image
[0][i
].x
= curOffset
% BLIT_WIDTH_BYTES
;
217 t
->image
[0][i
].y
= curOffset
/ BLIT_WIDTH_BYTES
;
218 t
->image
[0][i
].width
= MIN2(size
, BLIT_WIDTH_BYTES
);
219 t
->image
[0][i
].height
= size
/ t
->image
[0][i
].width
;
222 /* for debugging only and only applicable to non-rectangle targets */
223 assert(size
% t
->image
[0][i
].width
== 0);
224 assert(t
->image
[0][i
].x
== 0
225 || (size
< BLIT_WIDTH_BYTES
&& t
->image
[0][i
].height
== 1));
230 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
231 i
, texImage
->Width
, texImage
->Height
,
232 t
->image
[0][i
].x
, t
->image
[0][i
].y
,
233 t
->image
[0][i
].width
, t
->image
[0][i
].height
, size
, curOffset
);
239 /* Align the total size of texture memory block.
241 t
->base
.totalSize
= (curOffset
+ RADEON_OFFSET_MASK
) & ~RADEON_OFFSET_MASK
;
243 /* Setup remaining cube face blits, if needed */
244 if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
245 /* Round totalSize up to multiple of BLIT_WIDTH_BYTES */
246 const GLuint faceSize
= (t
->base
.totalSize
+ BLIT_WIDTH_BYTES
- 1)
247 & ~(BLIT_WIDTH_BYTES
-1);
248 const GLuint lines
= faceSize
/ BLIT_WIDTH_BYTES
;
250 /* reuse face 0 x/y/width/height - just adjust y */
251 for (face
= 1; face
< 6; face
++) {
252 for (i
= 0; i
< numLevels
; i
++) {
253 t
->image
[face
][i
].x
= t
->image
[0][i
].x
;
254 t
->image
[face
][i
].y
= t
->image
[0][i
].y
+ face
* lines
;
255 t
->image
[face
][i
].width
= t
->image
[0][i
].width
;
256 t
->image
[face
][i
].height
= t
->image
[0][i
].height
;
259 t
->base
.totalSize
= 6 * faceSize
; /* total texmem needed */
265 t
->pp_txfilter
&= ~R200_MAX_MIP_LEVEL_MASK
;
266 t
->pp_txfilter
|= (numLevels
- 1) << R200_MAX_MIP_LEVEL_SHIFT
;
268 t
->pp_txformat
&= ~(R200_TXFORMAT_WIDTH_MASK
|
269 R200_TXFORMAT_HEIGHT_MASK
|
270 R200_TXFORMAT_CUBIC_MAP_ENABLE
|
271 R200_TXFORMAT_F5_WIDTH_MASK
|
272 R200_TXFORMAT_F5_HEIGHT_MASK
);
273 t
->pp_txformat
|= ((log2Width
<< R200_TXFORMAT_WIDTH_SHIFT
) |
274 (log2Height
<< R200_TXFORMAT_HEIGHT_SHIFT
));
276 t
->pp_txformat_x
&= ~(R200_DEPTH_LOG2_MASK
| R200_TEXCOORD_MASK
);
277 if (tObj
->Target
== GL_TEXTURE_3D
) {
278 t
->pp_txformat_x
|= (log2Depth
<< R200_DEPTH_LOG2_SHIFT
);
279 t
->pp_txformat_x
|= R200_TEXCOORD_VOLUME
;
281 else if (tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
282 ASSERT(log2Width
== log2height
);
283 t
->pp_txformat
|= ((log2Width
<< R200_TXFORMAT_F5_WIDTH_SHIFT
) |
284 (log2Height
<< R200_TXFORMAT_F5_HEIGHT_SHIFT
) |
285 (R200_TXFORMAT_CUBIC_MAP_ENABLE
));
286 t
->pp_txformat_x
|= R200_TEXCOORD_CUBIC_ENV
;
287 t
->pp_cubic_faces
= ((log2Width
<< R200_FACE_WIDTH_1_SHIFT
) |
288 (log2Height
<< R200_FACE_HEIGHT_1_SHIFT
) |
289 (log2Width
<< R200_FACE_WIDTH_2_SHIFT
) |
290 (log2Height
<< R200_FACE_HEIGHT_2_SHIFT
) |
291 (log2Width
<< R200_FACE_WIDTH_3_SHIFT
) |
292 (log2Height
<< R200_FACE_HEIGHT_3_SHIFT
) |
293 (log2Width
<< R200_FACE_WIDTH_4_SHIFT
) |
294 (log2Height
<< R200_FACE_HEIGHT_4_SHIFT
));
297 t
->pp_txsize
= (((tObj
->Image
[0][t
->base
.firstLevel
]->Width
- 1) << 0) |
298 ((tObj
->Image
[0][t
->base
.firstLevel
]->Height
- 1) << 16));
300 /* Only need to round to nearest 32 for textures, but the blitter
301 * requires 64-byte aligned pitches, and we may/may not need the
302 * blitter. NPOT only!
304 if (baseImage
->IsCompressed
)
305 t
->pp_txpitch
= (tObj
->Image
[0][t
->base
.firstLevel
]->Width
+ 63) & ~(63);
307 t
->pp_txpitch
= ((tObj
->Image
[0][t
->base
.firstLevel
]->Width
* baseImage
->TexFormat
->TexelBytes
) + 63) & ~(63);
310 t
->dirty_state
= TEX_ALL
;
312 /* FYI: r200UploadTexImages( rmesa, t ) used to be called here */
317 /* ================================================================
318 * Texture combine functions
321 /* GL_ARB_texture_env_combine support
324 /* The color tables have combine functions for GL_SRC_COLOR,
325 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
327 static GLuint r200_register_color
[][R200_MAX_TEXTURE_UNITS
] =
330 R200_TXC_ARG_A_R0_COLOR
,
331 R200_TXC_ARG_A_R1_COLOR
,
332 R200_TXC_ARG_A_R2_COLOR
,
333 R200_TXC_ARG_A_R3_COLOR
,
334 R200_TXC_ARG_A_R4_COLOR
,
335 R200_TXC_ARG_A_R5_COLOR
338 R200_TXC_ARG_A_R0_COLOR
| R200_TXC_COMP_ARG_A
,
339 R200_TXC_ARG_A_R1_COLOR
| R200_TXC_COMP_ARG_A
,
340 R200_TXC_ARG_A_R2_COLOR
| R200_TXC_COMP_ARG_A
,
341 R200_TXC_ARG_A_R3_COLOR
| R200_TXC_COMP_ARG_A
,
342 R200_TXC_ARG_A_R4_COLOR
| R200_TXC_COMP_ARG_A
,
343 R200_TXC_ARG_A_R5_COLOR
| R200_TXC_COMP_ARG_A
346 R200_TXC_ARG_A_R0_ALPHA
,
347 R200_TXC_ARG_A_R1_ALPHA
,
348 R200_TXC_ARG_A_R2_ALPHA
,
349 R200_TXC_ARG_A_R3_ALPHA
,
350 R200_TXC_ARG_A_R4_ALPHA
,
351 R200_TXC_ARG_A_R5_ALPHA
354 R200_TXC_ARG_A_R0_ALPHA
| R200_TXC_COMP_ARG_A
,
355 R200_TXC_ARG_A_R1_ALPHA
| R200_TXC_COMP_ARG_A
,
356 R200_TXC_ARG_A_R2_ALPHA
| R200_TXC_COMP_ARG_A
,
357 R200_TXC_ARG_A_R3_ALPHA
| R200_TXC_COMP_ARG_A
,
358 R200_TXC_ARG_A_R4_ALPHA
| R200_TXC_COMP_ARG_A
,
359 R200_TXC_ARG_A_R5_ALPHA
| R200_TXC_COMP_ARG_A
363 static GLuint r200_tfactor_color
[] =
365 R200_TXC_ARG_A_TFACTOR_COLOR
,
366 R200_TXC_ARG_A_TFACTOR_COLOR
| R200_TXC_COMP_ARG_A
,
367 R200_TXC_ARG_A_TFACTOR_ALPHA
,
368 R200_TXC_ARG_A_TFACTOR_ALPHA
| R200_TXC_COMP_ARG_A
371 static GLuint r200_primary_color
[] =
373 R200_TXC_ARG_A_DIFFUSE_COLOR
,
374 R200_TXC_ARG_A_DIFFUSE_COLOR
| R200_TXC_COMP_ARG_A
,
375 R200_TXC_ARG_A_DIFFUSE_ALPHA
,
376 R200_TXC_ARG_A_DIFFUSE_ALPHA
| R200_TXC_COMP_ARG_A
379 /* GL_ZERO table - indices 0-3
380 * GL_ONE table - indices 1-4
382 static GLuint r200_zero_color
[] =
385 R200_TXC_ARG_A_ZERO
| R200_TXC_COMP_ARG_A
,
387 R200_TXC_ARG_A_ZERO
| R200_TXC_COMP_ARG_A
,
391 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
393 static GLuint r200_register_alpha
[][R200_MAX_TEXTURE_UNITS
] =
396 R200_TXA_ARG_A_R0_ALPHA
,
397 R200_TXA_ARG_A_R1_ALPHA
,
398 R200_TXA_ARG_A_R2_ALPHA
,
399 R200_TXA_ARG_A_R3_ALPHA
,
400 R200_TXA_ARG_A_R4_ALPHA
,
401 R200_TXA_ARG_A_R5_ALPHA
404 R200_TXA_ARG_A_R0_ALPHA
| R200_TXA_COMP_ARG_A
,
405 R200_TXA_ARG_A_R1_ALPHA
| R200_TXA_COMP_ARG_A
,
406 R200_TXA_ARG_A_R2_ALPHA
| R200_TXA_COMP_ARG_A
,
407 R200_TXA_ARG_A_R3_ALPHA
| R200_TXA_COMP_ARG_A
,
408 R200_TXA_ARG_A_R4_ALPHA
| R200_TXA_COMP_ARG_A
,
409 R200_TXA_ARG_A_R5_ALPHA
| R200_TXA_COMP_ARG_A
413 static GLuint r200_tfactor_alpha
[] =
415 R200_TXA_ARG_A_TFACTOR_ALPHA
,
416 R200_TXA_ARG_A_TFACTOR_ALPHA
| R200_TXA_COMP_ARG_A
419 static GLuint r200_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 r200_zero_alpha
[] =
431 R200_TXA_ARG_A_ZERO
| R200_TXA_COMP_ARG_A
,
436 /* Extract the arg from slot A, shift it into the correct argument slot
437 * and set the corresponding complement bit.
439 #define R200_COLOR_ARG( n, arg ) \
442 ((color_arg[n] & R200_TXC_ARG_A_MASK) \
443 << R200_TXC_ARG_##arg##_SHIFT); \
445 ((color_arg[n] >> R200_TXC_COMP_ARG_A_SHIFT) \
446 << R200_TXC_COMP_ARG_##arg##_SHIFT); \
449 #define R200_ALPHA_ARG( n, arg ) \
452 ((alpha_arg[n] & R200_TXA_ARG_A_MASK) \
453 << R200_TXA_ARG_##arg##_SHIFT); \
455 ((alpha_arg[n] >> R200_TXA_COMP_ARG_A_SHIFT) \
456 << R200_TXA_COMP_ARG_##arg##_SHIFT); \
460 /* ================================================================
461 * Texture unit state management
464 static GLboolean
r200UpdateTextureEnv( GLcontext
*ctx
, int unit
)
466 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
467 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
468 GLuint color_combine
, alpha_combine
;
469 GLuint color_scale
= rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXCBLEND2
] &
470 ~(R200_TXC_SCALE_MASK
);
471 GLuint alpha_scale
= rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXABLEND2
] &
472 ~(R200_TXA_DOT_ALPHA
| R200_TXA_SCALE_MASK
);
474 /* texUnit->_Current can be NULL if and only if the texture unit is
475 * not actually enabled.
477 assert( (texUnit
->_ReallyEnabled
== 0)
478 || (texUnit
->_Current
!= NULL
) );
480 if ( R200_DEBUG
& DEBUG_TEXTURE
) {
481 fprintf( stderr
, "%s( %p, %d )\n", __FUNCTION__
, (void *)ctx
, unit
);
484 /* Set the texture environment state. Isn't this nice and clean?
485 * The chip will automagically set the texture alpha to 0xff when
486 * the texture format does not include an alpha component. This
487 * reduces the amount of special-casing we have to do, alpha-only
488 * textures being a notable exception.
490 /* Don't cache these results.
492 rmesa
->state
.texture
.unit
[unit
].format
= 0;
493 rmesa
->state
.texture
.unit
[unit
].envMode
= 0;
495 if ( !texUnit
->_ReallyEnabled
) {
497 color_combine
= R200_TXC_ARG_A_ZERO
| R200_TXC_ARG_B_ZERO
498 | R200_TXC_ARG_C_DIFFUSE_COLOR
| R200_TXC_OP_MADD
;
499 alpha_combine
= R200_TXA_ARG_A_ZERO
| R200_TXA_ARG_B_ZERO
500 | R200_TXA_ARG_C_DIFFUSE_ALPHA
| R200_TXA_OP_MADD
;
503 color_combine
= R200_TXC_ARG_A_ZERO
| R200_TXC_ARG_B_ZERO
504 | R200_TXC_ARG_C_R0_COLOR
| R200_TXC_OP_MADD
;
505 alpha_combine
= R200_TXA_ARG_A_ZERO
| R200_TXA_ARG_B_ZERO
506 | R200_TXA_ARG_C_R0_ALPHA
| R200_TXA_OP_MADD
;
510 GLuint color_arg
[3], alpha_arg
[3];
512 const GLuint numColorArgs
= texUnit
->_CurrentCombine
->_NumArgsRGB
;
513 const GLuint numAlphaArgs
= texUnit
->_CurrentCombine
->_NumArgsA
;
514 GLuint RGBshift
= texUnit
->_CurrentCombine
->ScaleShiftRGB
;
515 GLuint Ashift
= texUnit
->_CurrentCombine
->ScaleShiftA
;
519 * Extract the color and alpha combine function arguments.
521 for ( i
= 0 ; i
< numColorArgs
; i
++ ) {
522 const GLint op
= texUnit
->_CurrentCombine
->OperandRGB
[i
] - GL_SRC_COLOR
;
525 switch ( texUnit
->_CurrentCombine
->SourceRGB
[i
] ) {
527 color_arg
[i
] = r200_register_color
[op
][unit
];
530 color_arg
[i
] = r200_tfactor_color
[op
];
532 case GL_PRIMARY_COLOR
:
533 color_arg
[i
] = r200_primary_color
[op
];
537 color_arg
[i
] = r200_primary_color
[op
];
539 color_arg
[i
] = r200_register_color
[op
][0];
542 color_arg
[i
] = r200_zero_color
[op
];
545 color_arg
[i
] = r200_zero_color
[op
+1];
552 for ( i
= 0 ; i
< numAlphaArgs
; i
++ ) {
553 const GLint op
= texUnit
->_CurrentCombine
->OperandA
[i
] - GL_SRC_ALPHA
;
556 switch ( texUnit
->_CurrentCombine
->SourceA
[i
] ) {
558 alpha_arg
[i
] = r200_register_alpha
[op
][unit
];
561 alpha_arg
[i
] = r200_tfactor_alpha
[op
];
563 case GL_PRIMARY_COLOR
:
564 alpha_arg
[i
] = r200_primary_alpha
[op
];
568 alpha_arg
[i
] = r200_primary_alpha
[op
];
570 alpha_arg
[i
] = r200_register_alpha
[op
][0];
573 alpha_arg
[i
] = r200_zero_alpha
[op
];
576 alpha_arg
[i
] = r200_zero_alpha
[op
+1];
584 * Build up the color and alpha combine functions.
586 switch ( texUnit
->_CurrentCombine
->ModeRGB
) {
588 color_combine
= (R200_TXC_ARG_A_ZERO
|
589 R200_TXC_ARG_B_ZERO
|
591 R200_COLOR_ARG( 0, C
);
594 color_combine
= (R200_TXC_ARG_C_ZERO
|
596 R200_COLOR_ARG( 0, A
);
597 R200_COLOR_ARG( 1, B
);
600 color_combine
= (R200_TXC_ARG_B_ZERO
|
601 R200_TXC_COMP_ARG_B
|
603 R200_COLOR_ARG( 0, A
);
604 R200_COLOR_ARG( 1, C
);
607 color_combine
= (R200_TXC_ARG_B_ZERO
|
608 R200_TXC_COMP_ARG_B
|
609 R200_TXC_BIAS_ARG_C
| /* new */
610 R200_TXC_OP_MADD
); /* was ADDSIGNED */
611 R200_COLOR_ARG( 0, A
);
612 R200_COLOR_ARG( 1, C
);
615 color_combine
= (R200_TXC_ARG_B_ZERO
|
616 R200_TXC_COMP_ARG_B
|
619 R200_COLOR_ARG( 0, A
);
620 R200_COLOR_ARG( 1, C
);
623 color_combine
= (R200_TXC_OP_LERP
);
624 R200_COLOR_ARG( 0, B
);
625 R200_COLOR_ARG( 1, A
);
626 R200_COLOR_ARG( 2, C
);
629 case GL_DOT3_RGB_EXT
:
630 case GL_DOT3_RGBA_EXT
:
631 /* The EXT version of the DOT3 extension does not support the
632 * scale factor, but the ARB version (and the version in OpenGL
640 /* DOT3 works differently on R200 than on R100. On R100, just
641 * setting the DOT3 mode did everything for you. On R200, the
642 * driver has to enable the biasing and scale in the inputs to
643 * put them in the proper [-1,1] range. This is what the 4x and
644 * the -0.5 in the DOT3 spec do. The post-scale is then set
648 color_combine
= (R200_TXC_ARG_C_ZERO
|
650 R200_TXC_BIAS_ARG_A
|
651 R200_TXC_BIAS_ARG_B
|
652 R200_TXC_SCALE_ARG_A
|
653 R200_TXC_SCALE_ARG_B
);
654 R200_COLOR_ARG( 0, A
);
655 R200_COLOR_ARG( 1, B
);
658 case GL_MODULATE_ADD_ATI
:
659 color_combine
= (R200_TXC_OP_MADD
);
660 R200_COLOR_ARG( 0, A
);
661 R200_COLOR_ARG( 1, C
);
662 R200_COLOR_ARG( 2, B
);
664 case GL_MODULATE_SIGNED_ADD_ATI
:
665 color_combine
= (R200_TXC_BIAS_ARG_C
| /* new */
666 R200_TXC_OP_MADD
); /* was ADDSIGNED */
667 R200_COLOR_ARG( 0, A
);
668 R200_COLOR_ARG( 1, C
);
669 R200_COLOR_ARG( 2, B
);
671 case GL_MODULATE_SUBTRACT_ATI
:
672 color_combine
= (R200_TXC_NEG_ARG_C
|
674 R200_COLOR_ARG( 0, A
);
675 R200_COLOR_ARG( 1, C
);
676 R200_COLOR_ARG( 2, B
);
682 switch ( texUnit
->_CurrentCombine
->ModeA
) {
684 alpha_combine
= (R200_TXA_ARG_A_ZERO
|
685 R200_TXA_ARG_B_ZERO
|
687 R200_ALPHA_ARG( 0, C
);
690 alpha_combine
= (R200_TXA_ARG_C_ZERO
|
692 R200_ALPHA_ARG( 0, A
);
693 R200_ALPHA_ARG( 1, B
);
696 alpha_combine
= (R200_TXA_ARG_B_ZERO
|
697 R200_TXA_COMP_ARG_B
|
699 R200_ALPHA_ARG( 0, A
);
700 R200_ALPHA_ARG( 1, C
);
703 alpha_combine
= (R200_TXA_ARG_B_ZERO
|
704 R200_TXA_COMP_ARG_B
|
705 R200_TXA_BIAS_ARG_C
| /* new */
706 R200_TXA_OP_MADD
); /* was ADDSIGNED */
707 R200_ALPHA_ARG( 0, A
);
708 R200_ALPHA_ARG( 1, C
);
711 alpha_combine
= (R200_TXA_ARG_B_ZERO
|
712 R200_TXA_COMP_ARG_B
|
715 R200_ALPHA_ARG( 0, A
);
716 R200_ALPHA_ARG( 1, C
);
719 alpha_combine
= (R200_TXA_OP_LERP
);
720 R200_ALPHA_ARG( 0, B
);
721 R200_ALPHA_ARG( 1, A
);
722 R200_ALPHA_ARG( 2, C
);
725 case GL_MODULATE_ADD_ATI
:
726 alpha_combine
= (R200_TXA_OP_MADD
);
727 R200_ALPHA_ARG( 0, A
);
728 R200_ALPHA_ARG( 1, C
);
729 R200_ALPHA_ARG( 2, B
);
731 case GL_MODULATE_SIGNED_ADD_ATI
:
732 alpha_combine
= (R200_TXA_BIAS_ARG_C
| /* new */
733 R200_TXA_OP_MADD
); /* was ADDSIGNED */
734 R200_ALPHA_ARG( 0, A
);
735 R200_ALPHA_ARG( 1, C
);
736 R200_ALPHA_ARG( 2, B
);
738 case GL_MODULATE_SUBTRACT_ATI
:
739 alpha_combine
= (R200_TXA_NEG_ARG_C
|
741 R200_ALPHA_ARG( 0, A
);
742 R200_ALPHA_ARG( 1, C
);
743 R200_ALPHA_ARG( 2, B
);
749 if ( (texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGBA_EXT
)
750 || (texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGBA
) ) {
751 alpha_scale
|= R200_TXA_DOT_ALPHA
;
756 * Apply the scale factor.
758 color_scale
|= (RGBshift
<< R200_TXC_SCALE_SHIFT
);
759 alpha_scale
|= (Ashift
<< R200_TXA_SCALE_SHIFT
);
765 if ( rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXCBLEND
] != color_combine
||
766 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXABLEND
] != alpha_combine
||
767 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXCBLEND2
] != color_scale
||
768 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXABLEND2
] != alpha_scale
) {
769 R200_STATECHANGE( rmesa
, pix
[unit
] );
770 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXCBLEND
] = color_combine
;
771 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXABLEND
] = alpha_combine
;
772 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXCBLEND2
] = color_scale
;
773 rmesa
->hw
.pix
[unit
].cmd
[PIX_PP_TXABLEND2
] = alpha_scale
;
779 #define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK | \
780 R200_MIN_FILTER_MASK | \
781 R200_MAG_FILTER_MASK | \
782 R200_MAX_ANISO_MASK | \
784 R200_YUV_TEMPERATURE_MASK | \
785 R200_CLAMP_S_MASK | \
786 R200_CLAMP_T_MASK | \
787 R200_BORDER_MODE_D3D )
789 #define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK | \
790 R200_TXFORMAT_HEIGHT_MASK | \
791 R200_TXFORMAT_FORMAT_MASK | \
792 R200_TXFORMAT_F5_WIDTH_MASK | \
793 R200_TXFORMAT_F5_HEIGHT_MASK | \
794 R200_TXFORMAT_ALPHA_IN_MAP | \
795 R200_TXFORMAT_CUBIC_MAP_ENABLE | \
796 R200_TXFORMAT_NON_POWER2)
798 #define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK | \
799 R200_TEXCOORD_MASK | \
800 R200_CLAMP_Q_MASK | \
801 R200_VOLUME_FILTER_MASK)
804 static void import_tex_obj_state( r200ContextPtr rmesa
,
806 r200TexObjPtr texobj
)
808 GLuint
*cmd
= R200_DB_STATE( tex
[unit
] );
810 cmd
[TEX_PP_TXFILTER
] &= ~TEXOBJ_TXFILTER_MASK
;
811 cmd
[TEX_PP_TXFILTER
] |= texobj
->pp_txfilter
& TEXOBJ_TXFILTER_MASK
;
812 cmd
[TEX_PP_TXFORMAT
] &= ~TEXOBJ_TXFORMAT_MASK
;
813 cmd
[TEX_PP_TXFORMAT
] |= texobj
->pp_txformat
& TEXOBJ_TXFORMAT_MASK
;
814 cmd
[TEX_PP_TXFORMAT_X
] &= ~TEXOBJ_TXFORMAT_X_MASK
;
815 cmd
[TEX_PP_TXFORMAT_X
] |= texobj
->pp_txformat_x
& TEXOBJ_TXFORMAT_X_MASK
;
816 cmd
[TEX_PP_TXSIZE
] = texobj
->pp_txsize
; /* NPOT only! */
817 cmd
[TEX_PP_TXPITCH
] = texobj
->pp_txpitch
; /* NPOT only! */
818 cmd
[TEX_PP_TXOFFSET
] = texobj
->pp_txoffset
;
819 cmd
[TEX_PP_BORDER_COLOR
] = texobj
->pp_border_color
;
820 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.tex
[unit
] );
822 if (texobj
->base
.tObj
->Target
== GL_TEXTURE_CUBE_MAP
) {
823 GLuint
*cube_cmd
= R200_DB_STATE( cube
[unit
] );
824 GLuint bytesPerFace
= texobj
->base
.totalSize
/ 6;
825 ASSERT(texobj
->totalSize
% 6 == 0);
826 cube_cmd
[CUBE_PP_CUBIC_FACES
] = texobj
->pp_cubic_faces
;
827 cube_cmd
[CUBE_PP_CUBIC_OFFSET_F1
] = texobj
->pp_txoffset
+ 1 * bytesPerFace
;
828 cube_cmd
[CUBE_PP_CUBIC_OFFSET_F2
] = texobj
->pp_txoffset
+ 2 * bytesPerFace
;
829 cube_cmd
[CUBE_PP_CUBIC_OFFSET_F3
] = texobj
->pp_txoffset
+ 3 * bytesPerFace
;
830 cube_cmd
[CUBE_PP_CUBIC_OFFSET_F4
] = texobj
->pp_txoffset
+ 4 * bytesPerFace
;
831 cube_cmd
[CUBE_PP_CUBIC_OFFSET_F5
] = texobj
->pp_txoffset
+ 5 * bytesPerFace
;
832 R200_DB_STATECHANGE( rmesa
, &rmesa
->hw
.cube
[unit
] );
835 texobj
->dirty_state
&= ~(1<<unit
);
841 static void set_texgen_matrix( r200ContextPtr rmesa
,
843 const GLfloat
*s_plane
,
844 const GLfloat
*t_plane
,
845 const GLfloat
*r_plane
)
847 static const GLfloat scale_identity
[4] = { 1,1,1,1 };
849 if (!TEST_EQ_4V( s_plane
, scale_identity
) ||
850 !TEST_EQ_4V( t_plane
, scale_identity
) ||
851 !TEST_EQ_4V( r_plane
, scale_identity
)) {
852 rmesa
->TexGenEnabled
|= R200_TEXMAT_0_ENABLE
<<unit
;
853 rmesa
->TexGenMatrix
[unit
].m
[0] = s_plane
[0];
854 rmesa
->TexGenMatrix
[unit
].m
[4] = s_plane
[1];
855 rmesa
->TexGenMatrix
[unit
].m
[8] = s_plane
[2];
856 rmesa
->TexGenMatrix
[unit
].m
[12] = s_plane
[3];
858 rmesa
->TexGenMatrix
[unit
].m
[1] = t_plane
[0];
859 rmesa
->TexGenMatrix
[unit
].m
[5] = t_plane
[1];
860 rmesa
->TexGenMatrix
[unit
].m
[9] = t_plane
[2];
861 rmesa
->TexGenMatrix
[unit
].m
[13] = t_plane
[3];
863 /* NOTE: r_plane goes in the 4th row, not 3rd! */
864 rmesa
->TexGenMatrix
[unit
].m
[3] = r_plane
[0];
865 rmesa
->TexGenMatrix
[unit
].m
[7] = r_plane
[1];
866 rmesa
->TexGenMatrix
[unit
].m
[11] = r_plane
[2];
867 rmesa
->TexGenMatrix
[unit
].m
[15] = r_plane
[3];
869 rmesa
->NewGLState
|= _NEW_TEXTURE_MATRIX
;
873 /* Need this special matrix to get correct reflection map coords */
875 set_texgen_reflection_matrix( r200ContextPtr rmesa
, GLuint unit
)
877 static const GLfloat m
[16] = {
882 _math_matrix_loadf( &(rmesa
->TexGenMatrix
[unit
]), m
);
883 _math_matrix_analyse( &(rmesa
->TexGenMatrix
[unit
]) );
884 rmesa
->TexGenEnabled
|= R200_TEXMAT_0_ENABLE
<<unit
;
887 /* Need this special matrix to get correct normal map coords */
889 set_texgen_normal_map_matrix( r200ContextPtr rmesa
, GLuint unit
)
891 static const GLfloat m
[16] = {
896 _math_matrix_loadf( &(rmesa
->TexGenMatrix
[unit
]), m
);
897 _math_matrix_analyse( &(rmesa
->TexGenMatrix
[unit
]) );
898 rmesa
->TexGenEnabled
|= R200_TEXMAT_0_ENABLE
<<unit
;
902 /* Ignoring the Q texcoord for now.
904 * Returns GL_FALSE if fallback required.
906 static GLboolean
r200_validate_texgen( GLcontext
*ctx
, GLuint unit
)
908 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
909 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
910 GLuint inputshift
= R200_TEXGEN_0_INPUT_SHIFT
+ unit
*4;
911 GLuint tmp
= rmesa
->TexGenEnabled
;
913 rmesa
->TexGenCompSel
&= ~(R200_OUTPUT_TEX_0
<< unit
);
914 rmesa
->TexGenEnabled
&= ~(R200_TEXGEN_TEXMAT_0_ENABLE
<<unit
);
915 rmesa
->TexGenEnabled
&= ~(R200_TEXMAT_0_ENABLE
<<unit
);
916 rmesa
->TexGenInputs
&= ~(R200_TEXGEN_INPUT_MASK
<<inputshift
);
917 rmesa
->TexGenNeedNormals
[unit
] = 0;
920 fprintf(stderr
, "%s unit %d\n", __FUNCTION__
, unit
);
922 if ((texUnit
->TexGenEnabled
& (S_BIT
|T_BIT
|R_BIT
)) == 0) {
923 /* Disabled, no fallback:
925 rmesa
->TexGenInputs
|=
926 (R200_TEXGEN_INPUT_TEXCOORD_0
+unit
) << inputshift
;
929 else if (texUnit
->TexGenEnabled
& Q_BIT
) {
930 /* Very easy to do this, in fact would remove a fallback case
931 * elsewhere, but I haven't done it yet... Fallback:
933 /*fprintf(stderr, "fallback Q_BIT\n");*/
936 else if (texUnit
->TexGenEnabled
== (S_BIT
|T_BIT
) &&
937 texUnit
->GenModeS
== texUnit
->GenModeT
) {
939 rmesa
->TexGenEnabled
|= R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
;
942 else if (texUnit
->TexGenEnabled
== (S_BIT
|T_BIT
|R_BIT
) &&
943 texUnit
->GenModeS
== texUnit
->GenModeT
&&
944 texUnit
->GenModeT
== texUnit
->GenModeR
) {
946 rmesa
->TexGenEnabled
|= R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
;
950 /* Mixed modes, fallback:
952 /* fprintf(stderr, "fallback mixed texgen\n"); */
956 rmesa
->TexGenEnabled
|= R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
;
958 switch (texUnit
->GenModeS
) {
959 case GL_OBJECT_LINEAR
:
960 rmesa
->TexGenInputs
|= R200_TEXGEN_INPUT_OBJ
<< inputshift
;
961 set_texgen_matrix( rmesa
, unit
,
962 texUnit
->ObjectPlaneS
,
963 texUnit
->ObjectPlaneT
,
964 texUnit
->ObjectPlaneR
);
968 rmesa
->TexGenInputs
|= R200_TEXGEN_INPUT_EYE
<< inputshift
;
969 set_texgen_matrix( rmesa
, unit
,
975 case GL_REFLECTION_MAP_NV
:
976 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
977 rmesa
->TexGenInputs
|= R200_TEXGEN_INPUT_EYE_REFLECT
<<inputshift
;
978 set_texgen_reflection_matrix(rmesa
, unit
);
981 case GL_NORMAL_MAP_NV
:
982 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
983 rmesa
->TexGenInputs
|= R200_TEXGEN_INPUT_EYE_NORMAL
<<inputshift
;
984 set_texgen_normal_map_matrix(rmesa
, unit
);
988 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
989 rmesa
->TexGenInputs
|= R200_TEXGEN_INPUT_SPHERE
<<inputshift
;
993 /* Unsupported mode, fallback:
995 /* fprintf(stderr, "fallback unsupported texgen\n"); */
999 rmesa
->TexGenCompSel
|= R200_OUTPUT_TEX_0
<< unit
;
1001 if (tmp
!= rmesa
->TexGenEnabled
) {
1002 rmesa
->NewGLState
|= _NEW_TEXTURE_MATRIX
;
1009 static void disable_tex( GLcontext
*ctx
, int unit
)
1011 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1013 if (rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & (R200_TEX_0_ENABLE
<<unit
)) {
1014 /* Texture unit disabled */
1015 if ( rmesa
->state
.texture
.unit
[unit
].texobj
!= NULL
) {
1016 /* The old texture is no longer bound to this texture unit.
1020 rmesa
->state
.texture
.unit
[unit
].texobj
->base
.bound
&= ~(1UL << unit
);
1021 rmesa
->state
.texture
.unit
[unit
].texobj
= NULL
;
1024 R200_STATECHANGE( rmesa
, ctx
);
1025 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~((R200_TEX_0_ENABLE
|
1026 R200_TEX_BLEND_0_ENABLE
) << unit
);
1027 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_TEX_BLEND_0_ENABLE
;
1029 R200_STATECHANGE( rmesa
, vtx
);
1030 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_1
] &= ~(7 << (unit
* 3));
1032 if (rmesa
->TclFallback
& (R200_TCL_FALLBACK_TEXGEN_0
<<unit
)) {
1033 TCL_FALLBACK( ctx
, (R200_TCL_FALLBACK_TEXGEN_0
<<unit
), GL_FALSE
);
1036 /* Actually want to keep all units less than max active texture
1037 * enabled, right? Fix this for >2 texunits.
1039 /* FIXME: What should happen here if r200UpdateTextureEnv fails? */
1041 r200UpdateTextureEnv( ctx
, unit
);
1045 GLuint inputshift
= R200_TEXGEN_0_INPUT_SHIFT
+ unit
*4;
1046 GLuint tmp
= rmesa
->TexGenEnabled
;
1048 rmesa
->TexGenEnabled
&= ~(R200_TEXGEN_TEXMAT_0_ENABLE
<<unit
);
1049 rmesa
->TexGenEnabled
&= ~(R200_TEXMAT_0_ENABLE
<<unit
);
1050 rmesa
->TexGenEnabled
&= ~(R200_TEXGEN_INPUT_MASK
<<inputshift
);
1051 rmesa
->TexGenNeedNormals
[unit
] = 0;
1052 rmesa
->TexGenCompSel
&= ~(R200_OUTPUT_TEX_0
<< unit
);
1053 rmesa
->TexGenInputs
&= ~(R200_TEXGEN_INPUT_MASK
<<inputshift
);
1055 if (tmp
!= rmesa
->TexGenEnabled
) {
1056 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1057 rmesa
->NewGLState
|= _NEW_TEXTURE_MATRIX
;
1063 static GLboolean
enable_tex_2d( GLcontext
*ctx
, int unit
)
1065 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1066 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1067 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1068 r200TexObjPtr t
= (r200TexObjPtr
) tObj
->DriverData
;
1070 /* Need to load the 2d images associated with this unit.
1072 if (t
->pp_txformat
& R200_TXFORMAT_NON_POWER2
) {
1073 t
->pp_txformat
&= ~R200_TXFORMAT_NON_POWER2
;
1074 t
->base
.dirty_images
[0] = ~0;
1077 ASSERT(tObj
->Target
== GL_TEXTURE_2D
|| tObj
->Target
== GL_TEXTURE_1D
);
1079 if ( t
->base
.dirty_images
[0] ) {
1080 R200_FIREVERTICES( rmesa
);
1081 r200SetTexImages( rmesa
, tObj
);
1082 r200UploadTexImages( rmesa
, (r200TexObjPtr
) tObj
->DriverData
, 0 );
1083 if ( !t
->base
.memBlock
)
1090 #if ENABLE_HW_3D_TEXTURE
1091 static GLboolean
enable_tex_3d( GLcontext
*ctx
, int unit
)
1093 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1094 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1095 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1096 r200TexObjPtr t
= (r200TexObjPtr
) tObj
->DriverData
;
1098 /* Need to load the 3d images associated with this unit.
1100 if (t
->pp_txformat
& R200_TXFORMAT_NON_POWER2
) {
1101 t
->pp_txformat
&= ~R200_TXFORMAT_NON_POWER2
;
1102 t
->base
.dirty_images
[0] = ~0;
1105 ASSERT(tObj
->Target
== GL_TEXTURE_3D
);
1107 /* R100 & R200 do not support mipmaps for 3D textures.
1109 if ( (tObj
->MinFilter
!= GL_NEAREST
) && (tObj
->MinFilter
!= GL_LINEAR
) ) {
1113 if ( t
->base
.dirty_images
[0] ) {
1114 R200_FIREVERTICES( rmesa
);
1115 r200SetTexImages( rmesa
, tObj
);
1116 r200UploadTexImages( rmesa
, (r200TexObjPtr
) tObj
->DriverData
, 0 );
1117 if ( !t
->base
.memBlock
)
1125 static GLboolean
enable_tex_cube( GLcontext
*ctx
, int unit
)
1127 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1128 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1129 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1130 r200TexObjPtr t
= (r200TexObjPtr
) tObj
->DriverData
;
1133 /* Need to load the 2d images associated with this unit.
1135 if (t
->pp_txformat
& R200_TXFORMAT_NON_POWER2
) {
1136 t
->pp_txformat
&= ~R200_TXFORMAT_NON_POWER2
;
1137 for (face
= 0; face
< 6; face
++)
1138 t
->base
.dirty_images
[face
] = ~0;
1141 ASSERT(tObj
->Target
== GL_TEXTURE_CUBE_MAP
);
1143 if ( t
->base
.dirty_images
[0] || t
->base
.dirty_images
[1] ||
1144 t
->base
.dirty_images
[2] || t
->base
.dirty_images
[3] ||
1145 t
->base
.dirty_images
[4] || t
->base
.dirty_images
[5] ) {
1147 R200_FIREVERTICES( rmesa
);
1148 /* layout memory space, once for all faces */
1149 r200SetTexImages( rmesa
, tObj
);
1152 /* upload (per face) */
1153 for (face
= 0; face
< 6; face
++) {
1154 if (t
->base
.dirty_images
[face
]) {
1155 r200UploadTexImages( rmesa
, (r200TexObjPtr
) tObj
->DriverData
, face
);
1159 if ( !t
->base
.memBlock
) {
1160 /* texmem alloc failed, use s/w fallback */
1167 static GLboolean
enable_tex_rect( GLcontext
*ctx
, int unit
)
1169 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1170 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1171 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1172 r200TexObjPtr t
= (r200TexObjPtr
) tObj
->DriverData
;
1174 if (!(t
->pp_txformat
& R200_TXFORMAT_NON_POWER2
)) {
1175 t
->pp_txformat
|= R200_TXFORMAT_NON_POWER2
;
1176 t
->base
.dirty_images
[0] = ~0;
1179 ASSERT(tObj
->Target
== GL_TEXTURE_RECTANGLE_NV
);
1181 if ( t
->base
.dirty_images
[0] ) {
1182 R200_FIREVERTICES( rmesa
);
1183 r200SetTexImages( rmesa
, tObj
);
1184 r200UploadTexImages( rmesa
, (r200TexObjPtr
) tObj
->DriverData
, 0 );
1185 if ( !t
->base
.memBlock
&& !rmesa
->prefer_gart_client_texturing
)
1193 static GLboolean
update_tex_common( GLcontext
*ctx
, int unit
)
1195 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1196 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1197 struct gl_texture_object
*tObj
= texUnit
->_Current
;
1198 r200TexObjPtr t
= (r200TexObjPtr
) tObj
->DriverData
;
1201 /* Fallback if there's a texture border */
1202 if ( tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0 )
1205 /* Update state if this is a different texture object to last
1208 if ( rmesa
->state
.texture
.unit
[unit
].texobj
!= t
) {
1209 if ( rmesa
->state
.texture
.unit
[unit
].texobj
!= NULL
) {
1210 /* The old texture is no longer bound to this texture unit.
1214 rmesa
->state
.texture
.unit
[unit
].texobj
->base
.bound
&=
1218 rmesa
->state
.texture
.unit
[unit
].texobj
= t
;
1219 t
->base
.bound
|= (1UL << unit
);
1220 t
->dirty_state
|= 1<<unit
;
1221 driUpdateTextureLRU( (driTextureObject
*) t
); /* XXX: should be locked! */
1227 if ( 1|| !(rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & (R200_TEX_0_ENABLE
<<unit
))) {
1228 R200_STATECHANGE( rmesa
, ctx
);
1229 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= (R200_TEX_0_ENABLE
|
1230 R200_TEX_BLEND_0_ENABLE
) << unit
;
1232 R200_STATECHANGE( rmesa
, vtx
);
1233 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_1
] |= 4 << (unit
* 3);
1235 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1238 if (t
->dirty_state
& (1<<unit
)) {
1239 import_tex_obj_state( rmesa
, unit
, t
);
1242 if (rmesa
->recheck_texgen
[unit
]) {
1243 GLboolean fallback
= !r200_validate_texgen( ctx
, unit
);
1244 TCL_FALLBACK( ctx
, (R200_TCL_FALLBACK_TEXGEN_0
<<unit
), fallback
);
1245 rmesa
->recheck_texgen
[unit
] = 0;
1246 rmesa
->NewGLState
|= _NEW_TEXTURE_MATRIX
;
1249 format
= tObj
->Image
[0][tObj
->BaseLevel
]->Format
;
1250 if ( rmesa
->state
.texture
.unit
[unit
].format
!= format
||
1251 rmesa
->state
.texture
.unit
[unit
].envMode
!= texUnit
->EnvMode
) {
1252 rmesa
->state
.texture
.unit
[unit
].format
= format
;
1253 rmesa
->state
.texture
.unit
[unit
].envMode
= texUnit
->EnvMode
;
1254 if ( ! r200UpdateTextureEnv( ctx
, unit
) ) {
1259 FALLBACK( rmesa
, R200_FALLBACK_BORDER_MODE
, t
->border_fallback
);
1260 return !t
->border_fallback
;
1265 static GLboolean
r200UpdateTextureUnit( GLcontext
*ctx
, int unit
)
1267 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1269 if ( texUnit
->_ReallyEnabled
& (TEXTURE_RECT_BIT
) ) {
1270 return (enable_tex_rect( ctx
, unit
) &&
1271 update_tex_common( ctx
, unit
));
1273 else if ( texUnit
->_ReallyEnabled
& (TEXTURE_1D_BIT
| TEXTURE_2D_BIT
) ) {
1274 return (enable_tex_2d( ctx
, unit
) &&
1275 update_tex_common( ctx
, unit
));
1277 #if ENABLE_HW_3D_TEXTURE
1278 else if ( texUnit
->_ReallyEnabled
& (TEXTURE_3D_BIT
) ) {
1279 return (enable_tex_3d( ctx
, unit
) &&
1280 update_tex_common( ctx
, unit
));
1283 else if ( texUnit
->_ReallyEnabled
& (TEXTURE_CUBE_BIT
) ) {
1284 return (enable_tex_cube( ctx
, unit
) &&
1285 update_tex_common( ctx
, unit
));
1287 else if ( texUnit
->_ReallyEnabled
) {
1291 disable_tex( ctx
, unit
);
1297 void r200UpdateTextureState( GLcontext
*ctx
)
1299 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1303 ok
= (r200UpdateTextureUnit( ctx
, 0 ) &&
1304 r200UpdateTextureUnit( ctx
, 1 ) &&
1305 r200UpdateTextureUnit( ctx
, 2 ) &&
1306 r200UpdateTextureUnit( ctx
, 3 ) &&
1307 r200UpdateTextureUnit( ctx
, 4 ) &&
1308 r200UpdateTextureUnit( ctx
, 5 ));
1310 FALLBACK( rmesa
, R200_FALLBACK_TEXTURE
, !ok
);
1312 if (rmesa
->TclFallback
)
1313 r200ChooseVertexState( ctx
);
1316 if (rmesa
->r200Screen
->chipset
& R200_CHIPSET_REAL_R200
) {
1319 * T0 hang workaround -------------
1320 * not needed for r200 derivatives?
1322 if ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_ENABLE_MASK
) == R200_TEX_0_ENABLE
&&
1323 (rmesa
->hw
.tex
[0].cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
) > R200_MIN_FILTER_LINEAR
) {
1325 R200_STATECHANGE(rmesa
, ctx
);
1326 R200_STATECHANGE(rmesa
, tex
[1]);
1327 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_TEX_1_ENABLE
;
1328 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] &= ~TEXOBJ_TXFORMAT_MASK
;
1329 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] |= 0x08000000;
1332 if ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_1_ENABLE
) &&
1333 (rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] & 0x08000000)) {
1334 R200_STATECHANGE(rmesa
, tex
[1]);
1335 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] &= ~0x08000000;
1339 /* maybe needs to be done pairwise due to 2 parallel (physical) tex units ?
1340 looks like that's not the case, if 8500/9100 owners don't complain remove this...
1341 for ( i = 0; i < ctx->Const.MaxTextureUnits; i += 2) {
1342 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & ((R200_TEX_0_ENABLE |
1343 R200_TEX_1_ENABLE ) << i)) == (R200_TEX_0_ENABLE << i)) &&
1344 ((rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) >
1345 R200_MIN_FILTER_LINEAR)) {
1346 R200_STATECHANGE(rmesa, ctx);
1347 R200_STATECHANGE(rmesa, tex[i+1]);
1348 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_1_ENABLE << i);
1349 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1350 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] |= 0x08000000;
1353 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE << i)) &&
1354 (rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) {
1355 R200_STATECHANGE(rmesa, tex[i+1]);
1356 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000;
1362 * Texture cache LRU hang workaround -------------
1363 * not needed for r200 derivatives?
1367 if (((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & (R200_TEX_0_ENABLE
)) &&
1368 ((((rmesa
->hw
.tex
[0].cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
1370 ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_2_ENABLE
) &&
1371 ((((rmesa
->hw
.tex
[2].cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
1373 ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_4_ENABLE
) &&
1374 ((((rmesa
->hw
.tex
[4].cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
1380 if (((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & (R200_TEX_1_ENABLE
)) &&
1381 ((((rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
1383 ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_3_ENABLE
) &&
1384 ((((rmesa
->hw
.tex
[3].cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
1386 ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_5_ENABLE
) &&
1387 ((((rmesa
->hw
.tex
[5].cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
)) &
1393 if (dbg
!= rmesa
->hw
.tam
.cmd
[TAM_DEBUG3
]) {
1394 R200_STATECHANGE( rmesa
, tam
);
1395 rmesa
->hw
.tam
.cmd
[TAM_DEBUG3
] = dbg
;
1396 if (0) printf("TEXCACHE LRU HANG WORKAROUND %x\n", dbg
);