-/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c,v 1.6 2002/12/16 16:18:59 dawes Exp $ */
/**************************************************************************
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
* Gareth Hughes <gareth@valinux.com>
*/
-#include "glheader.h"
-#include "imports.h"
-#include "colormac.h"
-#include "context.h"
-#include "macros.h"
-#include "texformat.h"
-#include "enums.h"
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/colormac.h"
+#include "main/context.h"
+#include "main/macros.h"
+#include "main/texformat.h"
+#include "main/texobj.h"
+#include "main/enums.h"
#include "radeon_context.h"
+#include "radeon_mipmap_tree.h"
#include "radeon_state.h"
#include "radeon_ioctl.h"
#include "radeon_swtcl.h"
#include "radeon_tcl.h"
+#define RADEON_TXFORMAT_A8 RADEON_TXFORMAT_I8
+#define RADEON_TXFORMAT_L8 RADEON_TXFORMAT_I8
#define RADEON_TXFORMAT_AL88 RADEON_TXFORMAT_AI88
#define RADEON_TXFORMAT_YCBCR RADEON_TXFORMAT_YVYU422
#define RADEON_TXFORMAT_YCBCR_REV RADEON_TXFORMAT_VYUY422
+#define RADEON_TXFORMAT_RGB_DXT1 RADEON_TXFORMAT_DXT1
+#define RADEON_TXFORMAT_RGBA_DXT1 RADEON_TXFORMAT_DXT1
+#define RADEON_TXFORMAT_RGBA_DXT3 RADEON_TXFORMAT_DXT23
+#define RADEON_TXFORMAT_RGBA_DXT5 RADEON_TXFORMAT_DXT45
#define _COLOR(f) \
[ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, 0 }
+#define _COLOR_REV(f) \
+ [ MESA_FORMAT_ ## f ## _REV ] = { RADEON_TXFORMAT_ ## f, 0 }
#define _ALPHA(f) \
[ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 }
+#define _ALPHA_REV(f) \
+ [ MESA_FORMAT_ ## f ## _REV ] = { RADEON_TXFORMAT_ ## f | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 }
#define _YUV(f) \
[ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, RADEON_YUV_TO_RGB }
#define _INVALID(f) \
[ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
-#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_YCBCR_REV) \
+#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \
&& (tx_table[f].format != 0xffffffff) )
-static const struct {
+struct tx_table {
GLuint format, filter;
-}
-tx_table[] =
+};
+
+static const struct tx_table tx_table[] =
{
_ALPHA(RGBA8888),
+ _ALPHA_REV(RGBA8888),
_ALPHA(ARGB8888),
- _INVALID(RGB888),
+ _ALPHA_REV(ARGB8888),
+ [ MESA_FORMAT_RGB888 ] = { RADEON_TXFORMAT_ARGB8888, 0 },
_COLOR(RGB565),
+ _COLOR_REV(RGB565),
_ALPHA(ARGB4444),
+ _ALPHA_REV(ARGB4444),
_ALPHA(ARGB1555),
+ _ALPHA_REV(ARGB1555),
_ALPHA(AL88),
- _INVALID(A8),
- _INVALID(L8),
- _COLOR(I8),
+ _ALPHA_REV(AL88),
+ _ALPHA(A8),
+ _COLOR(L8),
+ _ALPHA(I8),
_INVALID(CI8),
_YUV(YCBCR),
_YUV(YCBCR_REV),
+ _INVALID(RGB_FXT1),
+ _INVALID(RGBA_FXT1),
+ _COLOR(RGB_DXT1),
+ _ALPHA(RGBA_DXT1),
+ _ALPHA(RGBA_DXT3),
+ _ALPHA(RGBA_DXT5),
};
#undef _COLOR
#undef _ALPHA
#undef _INVALID
-/**
- * This function computes the number of bytes of storage needed for
- * the given texture object (all mipmap levels, all cube faces).
- * The \c image[face][level].x/y/width/height parameters for upload/blitting
- * are computed here. \c pp_txfilter, \c pp_txformat, etc. will be set here
- * too.
- *
- * \param rmesa Context pointer
- * \param tObj GL texture object whose images are to be posted to
- * hardware state.
- */
-static void radeonSetTexImages( radeonContextPtr rmesa,
- struct gl_texture_object *tObj )
-{
- radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData;
- const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
- GLint curOffset;
- GLint i;
- GLint numLevels;
- GLint log2Width, log2Height, log2Depth;
-
- /* Set the hardware texture format
- */
-
- t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK |
- RADEON_TXFORMAT_ALPHA_IN_MAP);
- t->pp_txfilter &= ~RADEON_YUV_TO_RGB;
-
- if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) {
- t->pp_txformat |= tx_table[ baseImage->TexFormat->MesaFormat ].format;
- t->pp_txfilter |= tx_table[ baseImage->TexFormat->MesaFormat ].filter;
- }
- else {
- _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__);
- return;
- }
-
-
- /* Compute which mipmap levels we really want to send to the hardware.
- */
-
- driCalculateTextureFirstLastLevel( (driTextureObject *) t );
- log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
- log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
- log2Depth = tObj->Image[0][t->base.firstLevel]->DepthLog2;
-
- numLevels = t->base.lastLevel - t->base.firstLevel + 1;
-
- assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS);
-
- /* Calculate mipmap offsets and dimensions for blitting (uploading)
- * The idea is that we lay out the mipmap levels within a block of
- * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
- */
- curOffset = 0;
-
- for (i = 0; i < numLevels; i++) {
- const struct gl_texture_image *texImage;
- GLuint size;
-
- texImage = tObj->Image[0][i + t->base.firstLevel];
- if ( !texImage )
- break;
-
- /* find image size in bytes */
- if (texImage->IsCompressed) {
- size = texImage->CompressedSize;
- }
- else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
- size = ((texImage->Width * texImage->TexFormat->TexelBytes + 63)
- & ~63) * texImage->Height;
- }
- else {
- int w = texImage->Width * texImage->TexFormat->TexelBytes;
- if (w < 32)
- w = 32;
- size = w * texImage->Height * texImage->Depth;
- }
- assert(size > 0);
-
-
- /* Align to 32-byte offset. It is faster to do this unconditionally
- * (no branch penalty).
- */
-
- curOffset = (curOffset + 0x1f) & ~0x1f;
-
- t->image[0][i].x = curOffset % BLIT_WIDTH_BYTES;
- t->image[0][i].y = curOffset / BLIT_WIDTH_BYTES;
- t->image[0][i].width = MIN2(size, BLIT_WIDTH_BYTES);
- t->image[0][i].height = size / t->image[0][i].width;
-
-#if 0
- /* for debugging only and only applicable to non-rectangle targets */
- assert(size % t->image[0][i].width == 0);
- assert(t->image[0][i].x == 0
- || (size < BLIT_WIDTH_BYTES && t->image[0][i].height == 1));
-#endif
-
- if (0)
- fprintf(stderr,
- "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
- i, texImage->Width, texImage->Height,
- t->image[0][i].x, t->image[0][i].y,
- t->image[0][i].width, t->image[0][i].height, size, curOffset);
-
- curOffset += size;
-
- }
-
- /* Align the total size of texture memory block.
- */
- t->base.totalSize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
-
- /* Hardware state:
- */
- t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK;
- t->pp_txfilter |= (numLevels - 1) << RADEON_MAX_MIP_LEVEL_SHIFT;
-
- t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
- RADEON_TXFORMAT_HEIGHT_MASK |
- RADEON_TXFORMAT_CUBIC_MAP_ENABLE);
- t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) |
- (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT));
-
- t->pp_txsize = (((tObj->Image[0][t->base.firstLevel]->Width - 1) << 0) |
- ((tObj->Image[0][t->base.firstLevel]->Height - 1) << 16));
-
- /* Only need to round to nearest 32 for textures, but the blitter
- * requires 64-byte aligned pitches, and we may/may not need the
- * blitter. NPOT only!
- */
- if (baseImage->IsCompressed)
- t->pp_txpitch = (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63);
- else
- t->pp_txpitch = ((tObj->Image[0][t->base.firstLevel]->Width * baseImage->TexFormat->TexelBytes) + 63) & ~(63);
- t->pp_txpitch -= 32;
-
- t->dirty_state = TEX_ALL;
-
- /* FYI: radeonUploadTexImages( rmesa, t ); used to be called here */
-}
-
-
-
/* ================================================================
* Texture combine functions
*/
-#define RADEON_DISABLE 0
-#define RADEON_REPLACE 1
-#define RADEON_MODULATE 2
-#define RADEON_DECAL 3
-#define RADEON_BLEND 4
-#define RADEON_ADD 5
-#define RADEON_MAX_COMBFUNC 6
-
-static GLuint radeon_color_combine[][RADEON_MAX_COMBFUNC] =
-{
- /* Unit 0:
- */
- {
- /* Disable combiner stage
- */
- (RADEON_COLOR_ARG_A_ZERO |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_CURRENT_COLOR |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_REPLACE = 0x00802800
- */
- (RADEON_COLOR_ARG_A_ZERO |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_T0_COLOR |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_MODULATE = 0x00800142
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_T0_COLOR |
- RADEON_COLOR_ARG_C_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_DECAL = 0x008c2d42
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_T0_COLOR |
- RADEON_COLOR_ARG_C_T0_ALPHA |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_BLEND = 0x008c2902
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_TFACTOR_COLOR |
- RADEON_COLOR_ARG_C_T0_COLOR |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_ADD = 0x00812802
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_T0_COLOR |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
- },
-
- /* Unit 1:
- */
- {
- /* Disable combiner stage
- */
- (RADEON_COLOR_ARG_A_ZERO |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_CURRENT_COLOR |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_REPLACE = 0x00803000
- */
- (RADEON_COLOR_ARG_A_ZERO |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_T1_COLOR |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_MODULATE = 0x00800182
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_T1_COLOR |
- RADEON_COLOR_ARG_C_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_DECAL = 0x008c3582
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_T1_COLOR |
- RADEON_COLOR_ARG_C_T1_ALPHA |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_BLEND = 0x008c3102
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_TFACTOR_COLOR |
- RADEON_COLOR_ARG_C_T1_COLOR |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_ADD = 0x00813002
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_T1_COLOR |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
- },
-
- /* Unit 2:
- */
- {
- /* Disable combiner stage
- */
- (RADEON_COLOR_ARG_A_ZERO |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_CURRENT_COLOR |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_REPLACE = 0x00803800
- */
- (RADEON_COLOR_ARG_A_ZERO |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_T2_COLOR |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_MODULATE = 0x008001c2
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_T2_COLOR |
- RADEON_COLOR_ARG_C_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_DECAL = 0x008c3dc2
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_T2_COLOR |
- RADEON_COLOR_ARG_C_T2_ALPHA |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_BLEND = 0x008c3902
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_TFACTOR_COLOR |
- RADEON_COLOR_ARG_C_T2_COLOR |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_ADD = 0x00813802
- */
- (RADEON_COLOR_ARG_A_CURRENT_COLOR |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_COLOR_ARG_C_T2_COLOR |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
- }
-};
-
-static GLuint radeon_alpha_combine[][RADEON_MAX_COMBFUNC] =
-{
- /* Unit 0:
- */
- {
- /* Disable combiner stage
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_REPLACE = 0x00800500
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_T0_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_MODULATE = 0x00800051
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_T0_ALPHA |
- RADEON_ALPHA_ARG_C_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_DECAL = 0x00800100
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_BLEND = 0x00800051
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
- RADEON_ALPHA_ARG_C_T0_ALPHA |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_ADD = 0x00800051
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_T0_ALPHA |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
- },
-
- /* Unit 1:
- */
- {
- /* Disable combiner stage
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_REPLACE = 0x00800600
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_T1_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_MODULATE = 0x00800061
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_T1_ALPHA |
- RADEON_ALPHA_ARG_C_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_DECAL = 0x00800100
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_BLEND = 0x00800061
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
- RADEON_ALPHA_ARG_C_T1_ALPHA |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_ADD = 0x00800061
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_T1_ALPHA |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
- },
-
- /* Unit 2:
- */
- {
- /* Disable combiner stage
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_REPLACE = 0x00800700
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_T2_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_MODULATE = 0x00800071
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_T2_ALPHA |
- RADEON_ALPHA_ARG_C_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_DECAL = 0x00800100
- */
- (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_BLEND = 0x00800071
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
- RADEON_ALPHA_ARG_C_T2_ALPHA |
- RADEON_BLEND_CTL_BLEND |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
-
- /* GL_ADD = 0x00800021
- */
- (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_ALPHA_ARG_C_T2_ALPHA |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADD |
- RADEON_SCALE_1X |
- RADEON_CLAMP_TX),
- }
-};
-
-
/* GL_ARB_texture_env_combine support
*/
static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ r100ContextPtr rmesa = R100_CONTEXT(ctx);
const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
GLuint color_combine, alpha_combine;
+ const GLuint color_combine0 = RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO
+ | RADEON_COLOR_ARG_C_CURRENT_COLOR | RADEON_BLEND_CTL_ADD
+ | RADEON_SCALE_1X | RADEON_CLAMP_TX;
+ const GLuint alpha_combine0 = RADEON_ALPHA_ARG_A_ZERO | RADEON_ALPHA_ARG_B_ZERO
+ | RADEON_ALPHA_ARG_C_CURRENT_ALPHA | RADEON_BLEND_CTL_ADD
+ | RADEON_SCALE_1X | RADEON_CLAMP_TX;
+
/* texUnit->_Current can be NULL if and only if the texture unit is
* not actually enabled.
|| (texUnit->_Current != NULL) );
if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
- fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, ctx, unit );
+ fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx, unit );
}
/* Set the texture environment state. Isn't this nice and clean?
* The chip will automagically set the texture alpha to 0xff when
- * the texture format does not include an alpha component. This
+ * the texture format does not include an alpha component. This
* reduces the amount of special-casing we have to do, alpha-only
- * textures being a notable exception.
+ * textures being a notable exception. Doesn't work for luminance
+ * textures realized with I8 and ALPHA_IN_MAP not set neither (on r100).
*/
+ /* Don't cache these results.
+ */
+ rmesa->state.texture.unit[unit].format = 0;
+ rmesa->state.texture.unit[unit].envMode = 0;
+
if ( !texUnit->_ReallyEnabled ) {
- /* Don't cache these results.
- */
- rmesa->state.texture.unit[unit].format = 0;
- rmesa->state.texture.unit[unit].envMode = 0;
- color_combine = radeon_color_combine[unit][RADEON_DISABLE];
- alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
+ color_combine = color_combine0;
+ alpha_combine = alpha_combine0;
}
else {
- const struct gl_texture_object *tObj = texUnit->_Current;
- const GLenum format = tObj->Image[0][tObj->BaseLevel]->Format;
GLuint color_arg[3], alpha_arg[3];
- GLuint i, numColorArgs = 0, numAlphaArgs = 0;
- GLuint RGBshift = texUnit->CombineScaleShiftRGB;
- GLuint Ashift = texUnit->CombineScaleShiftA;
+ GLuint i;
+ const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
+ const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
+ GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB;
+ GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA;
- switch ( texUnit->EnvMode ) {
- case GL_REPLACE:
- switch ( format ) {
- case GL_RGBA:
- case GL_LUMINANCE_ALPHA:
- case GL_INTENSITY:
- color_combine = radeon_color_combine[unit][RADEON_REPLACE];
- alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE];
- break;
- case GL_ALPHA:
- color_combine = radeon_color_combine[unit][RADEON_DISABLE];
- alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE];
- break;
- case GL_LUMINANCE:
- case GL_RGB:
- case GL_YCBCR_MESA:
- color_combine = radeon_color_combine[unit][RADEON_REPLACE];
- alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
- break;
- case GL_COLOR_INDEX:
- default:
- return GL_FALSE;
- }
- break;
- case GL_MODULATE:
- switch ( format ) {
- case GL_RGBA:
- case GL_LUMINANCE_ALPHA:
- case GL_INTENSITY:
- color_combine = radeon_color_combine[unit][RADEON_MODULATE];
- alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+ /* Step 1:
+ * Extract the color and alpha combine function arguments.
+ */
+ for ( i = 0 ; i < numColorArgs ; i++ ) {
+ const GLint op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR;
+ const GLuint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i];
+ assert(op >= 0);
+ assert(op <= 3);
+ switch ( srcRGBi ) {
+ case GL_TEXTURE:
+ if (texUnit->_Current->Image[0][0]->_BaseFormat == GL_ALPHA)
+ color_arg[i] = radeon_zero_color[op];
+ else
+ color_arg[i] = radeon_texture_color[op][unit];
break;
- case GL_ALPHA:
- color_combine = radeon_color_combine[unit][RADEON_DISABLE];
- alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+ case GL_CONSTANT:
+ color_arg[i] = radeon_tfactor_color[op];
break;
- case GL_RGB:
- case GL_LUMINANCE:
- case GL_YCBCR_MESA:
- color_combine = radeon_color_combine[unit][RADEON_MODULATE];
- alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
+ case GL_PRIMARY_COLOR:
+ color_arg[i] = radeon_primary_color[op];
break;
- case GL_COLOR_INDEX:
- default:
- return GL_FALSE;
- }
- break;
-
- case GL_DECAL:
- switch ( format ) {
- case GL_RGBA:
- case GL_RGB:
- case GL_YCBCR_MESA:
- color_combine = radeon_color_combine[unit][RADEON_DECAL];
- alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
+ case GL_PREVIOUS:
+ color_arg[i] = radeon_previous_color[op];
break;
- case GL_ALPHA:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- case GL_INTENSITY:
- color_combine = radeon_color_combine[unit][RADEON_DISABLE];
- alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
- break;
- case GL_COLOR_INDEX:
- default:
- return GL_FALSE;
- }
- break;
-
- case GL_BLEND:
- switch ( format ) {
- case GL_RGBA:
- case GL_RGB:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- case GL_YCBCR_MESA:
- color_combine = radeon_color_combine[unit][RADEON_BLEND];
- alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+ case GL_ZERO:
+ color_arg[i] = radeon_zero_color[op];
break;
- case GL_ALPHA:
- color_combine = radeon_color_combine[unit][RADEON_DISABLE];
- alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+ case GL_ONE:
+ color_arg[i] = radeon_zero_color[op+1];
break;
- case GL_INTENSITY:
- color_combine = radeon_color_combine[unit][RADEON_BLEND];
- alpha_combine = radeon_alpha_combine[unit][RADEON_BLEND];
+ case GL_TEXTURE0:
+ case GL_TEXTURE1:
+ case GL_TEXTURE2: {
+ GLuint txunit = srcRGBi - GL_TEXTURE0;
+ if (ctx->Texture.Unit[txunit]._Current->Image[0][0]->_BaseFormat == GL_ALPHA)
+ color_arg[i] = radeon_zero_color[op];
+ else
+ /* implement ogl 1.4/1.5 core spec here, not specification of
+ * GL_ARB_texture_env_crossbar (which would require disabling blending
+ * instead of undefined results when referencing not enabled texunit) */
+ color_arg[i] = radeon_texture_color[op][txunit];
+ }
break;
- case GL_COLOR_INDEX:
default:
return GL_FALSE;
}
- break;
+ }
- case GL_ADD:
- switch ( format ) {
- case GL_RGBA:
- case GL_RGB:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- case GL_YCBCR_MESA:
- color_combine = radeon_color_combine[unit][RADEON_ADD];
- alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
- break;
- case GL_ALPHA:
- color_combine = radeon_color_combine[unit][RADEON_DISABLE];
- alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
- break;
- case GL_INTENSITY:
- color_combine = radeon_color_combine[unit][RADEON_ADD];
- alpha_combine = radeon_alpha_combine[unit][RADEON_ADD];
+ for ( i = 0 ; i < numAlphaArgs ; i++ ) {
+ const GLint op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA;
+ const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i];
+ assert(op >= 0);
+ assert(op <= 1);
+ switch ( srcAi ) {
+ case GL_TEXTURE:
+ if (texUnit->_Current->Image[0][0]->_BaseFormat == GL_LUMINANCE)
+ alpha_arg[i] = radeon_zero_alpha[op+1];
+ else
+ alpha_arg[i] = radeon_texture_alpha[op][unit];
break;
- case GL_COLOR_INDEX:
- default:
- return GL_FALSE;
- }
- break;
-
- case GL_COMBINE:
- /* Don't cache these results.
- */
- rmesa->state.texture.unit[unit].format = 0;
- rmesa->state.texture.unit[unit].envMode = 0;
-
- /* Step 0:
- * Calculate how many arguments we need to process.
- */
- switch ( texUnit->CombineModeRGB ) {
- case GL_REPLACE:
- numColorArgs = 1;
+ case GL_CONSTANT:
+ alpha_arg[i] = radeon_tfactor_alpha[op];
break;
- case GL_MODULATE:
- case GL_ADD:
- case GL_ADD_SIGNED:
- case GL_SUBTRACT:
- case GL_DOT3_RGB:
- case GL_DOT3_RGBA:
- case GL_DOT3_RGB_EXT:
- case GL_DOT3_RGBA_EXT:
- numColorArgs = 2;
+ case GL_PRIMARY_COLOR:
+ alpha_arg[i] = radeon_primary_alpha[op];
break;
- case GL_INTERPOLATE:
- case GL_MODULATE_ADD_ATI:
- case GL_MODULATE_SIGNED_ADD_ATI:
- case GL_MODULATE_SUBTRACT_ATI:
- numColorArgs = 3;
+ case GL_PREVIOUS:
+ alpha_arg[i] = radeon_previous_alpha[op];
break;
- default:
- return GL_FALSE;
- }
-
- switch ( texUnit->CombineModeA ) {
- case GL_REPLACE:
- numAlphaArgs = 1;
+ case GL_ZERO:
+ alpha_arg[i] = radeon_zero_alpha[op];
break;
- case GL_MODULATE:
- case GL_ADD:
- case GL_ADD_SIGNED:
- case GL_SUBTRACT:
- numAlphaArgs = 2;
+ case GL_ONE:
+ alpha_arg[i] = radeon_zero_alpha[op+1];
break;
- case GL_INTERPOLATE:
- case GL_MODULATE_ADD_ATI:
- case GL_MODULATE_SIGNED_ADD_ATI:
- case GL_MODULATE_SUBTRACT_ATI:
- numAlphaArgs = 3;
+ case GL_TEXTURE0:
+ case GL_TEXTURE1:
+ case GL_TEXTURE2: {
+ GLuint txunit = srcAi - GL_TEXTURE0;
+ if (ctx->Texture.Unit[txunit]._Current->Image[0][0]->_BaseFormat == GL_LUMINANCE)
+ alpha_arg[i] = radeon_zero_alpha[op+1];
+ else
+ alpha_arg[i] = radeon_texture_alpha[op][txunit];
+ }
break;
default:
return GL_FALSE;
}
+ }
- /* Step 1:
- * Extract the color and alpha combine function arguments.
- */
- for ( i = 0 ; i < numColorArgs ; i++ ) {
- const GLuint op = texUnit->CombineOperandRGB[i] - GL_SRC_COLOR;
- assert(op >= 0);
- assert(op <= 3);
- switch ( texUnit->CombineSourceRGB[i] ) {
- case GL_TEXTURE:
- color_arg[i] = radeon_texture_color[op][unit];
- break;
- case GL_CONSTANT:
- color_arg[i] = radeon_tfactor_color[op];
- break;
- case GL_PRIMARY_COLOR:
- color_arg[i] = radeon_primary_color[op];
- break;
- case GL_PREVIOUS:
- color_arg[i] = radeon_previous_color[op];
- break;
- case GL_ZERO:
- color_arg[i] = radeon_zero_color[op];
- break;
- case GL_ONE:
- color_arg[i] = radeon_zero_color[op+1];
- break;
- default:
- return GL_FALSE;
- }
- }
-
- for ( i = 0 ; i < numAlphaArgs ; i++ ) {
- const GLuint op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA;
- assert(op >= 0);
- assert(op <= 1);
- switch ( texUnit->CombineSourceA[i] ) {
- case GL_TEXTURE:
- alpha_arg[i] = radeon_texture_alpha[op][unit];
- break;
- case GL_CONSTANT:
- alpha_arg[i] = radeon_tfactor_alpha[op];
- break;
- case GL_PRIMARY_COLOR:
- alpha_arg[i] = radeon_primary_alpha[op];
- break;
- case GL_PREVIOUS:
- alpha_arg[i] = radeon_previous_alpha[op];
- break;
- case GL_ZERO:
- alpha_arg[i] = radeon_zero_alpha[op];
- break;
- case GL_ONE:
- alpha_arg[i] = radeon_zero_alpha[op+1];
- break;
- default:
- return GL_FALSE;
- }
- }
+ /* Step 2:
+ * Build up the color and alpha combine functions.
+ */
+ switch ( texUnit->_CurrentCombine->ModeRGB ) {
+ case GL_REPLACE:
+ color_combine = (RADEON_COLOR_ARG_A_ZERO |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, C );
+ break;
+ case GL_MODULATE:
+ color_combine = (RADEON_COLOR_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, B );
+ break;
+ case GL_ADD:
+ color_combine = (RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, C );
+ break;
+ case GL_ADD_SIGNED:
+ color_combine = (RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADDSIGNED |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, C );
+ break;
+ case GL_SUBTRACT:
+ color_combine = (RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_SUBTRACT |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, C );
+ break;
+ case GL_INTERPOLATE:
+ color_combine = (RADEON_BLEND_CTL_BLEND |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, B );
+ RADEON_COLOR_ARG( 1, A );
+ RADEON_COLOR_ARG( 2, C );
+ break;
- /* Step 2:
- * Build up the color and alpha combine functions.
+ case GL_DOT3_RGB_EXT:
+ case GL_DOT3_RGBA_EXT:
+ /* The EXT version of the DOT3 extension does not support the
+ * scale factor, but the ARB version (and the version in OpenGL
+ * 1.3) does.
*/
- switch ( texUnit->CombineModeRGB ) {
- case GL_REPLACE:
- color_combine = (RADEON_COLOR_ARG_A_ZERO |
- RADEON_COLOR_ARG_B_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_CLAMP_TX);
- RADEON_COLOR_ARG( 0, C );
- break;
- case GL_MODULATE:
- color_combine = (RADEON_COLOR_ARG_C_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_CLAMP_TX);
- RADEON_COLOR_ARG( 0, A );
- RADEON_COLOR_ARG( 1, B );
- break;
- case GL_ADD:
- color_combine = (RADEON_COLOR_ARG_B_ZERO |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADD |
- RADEON_CLAMP_TX);
- RADEON_COLOR_ARG( 0, A );
- RADEON_COLOR_ARG( 1, C );
- break;
- case GL_ADD_SIGNED:
- color_combine = (RADEON_COLOR_ARG_B_ZERO |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADDSIGNED |
- RADEON_CLAMP_TX);
- RADEON_COLOR_ARG( 0, A );
- RADEON_COLOR_ARG( 1, C );
- break;
- case GL_SUBTRACT:
- color_combine = (RADEON_COLOR_ARG_B_ZERO |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_SUBTRACT |
- RADEON_CLAMP_TX);
- RADEON_COLOR_ARG( 0, A );
- RADEON_COLOR_ARG( 1, C );
- break;
- case GL_INTERPOLATE:
- color_combine = (RADEON_BLEND_CTL_BLEND |
- RADEON_CLAMP_TX);
- RADEON_COLOR_ARG( 0, B );
- RADEON_COLOR_ARG( 1, A );
- RADEON_COLOR_ARG( 2, C );
- break;
-
- case GL_DOT3_RGB_EXT:
- case GL_DOT3_RGBA_EXT:
- /* The EXT version of the DOT3 extension does not support the
- * scale factor, but the ARB version (and the version in OpenGL
- * 1.3) does.
- */
- RGBshift = 0;
- Ashift = 0;
- /* FALLTHROUGH */
-
- case GL_DOT3_RGB:
- case GL_DOT3_RGBA:
- /* The R100 / RV200 only support a 1X multiplier in hardware
- * w/the ARB version.
- */
- if ( RGBshift != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) {
- return GL_FALSE;
- }
-
- RGBshift += 2;
- Ashift = RGBshift;
-
- color_combine = (RADEON_COLOR_ARG_C_ZERO |
- RADEON_BLEND_CTL_DOT3 |
- RADEON_CLAMP_TX);
- RADEON_COLOR_ARG( 0, A );
- RADEON_COLOR_ARG( 1, B );
- break;
+ RGBshift = 0;
+ /* FALLTHROUGH */
- case GL_MODULATE_ADD_ATI:
- color_combine = (RADEON_BLEND_CTL_ADD |
- RADEON_CLAMP_TX);
- RADEON_COLOR_ARG( 0, A );
- RADEON_COLOR_ARG( 1, C );
- RADEON_COLOR_ARG( 2, B );
- break;
- case GL_MODULATE_SIGNED_ADD_ATI:
- color_combine = (RADEON_BLEND_CTL_ADDSIGNED |
- RADEON_CLAMP_TX);
- RADEON_COLOR_ARG( 0, A );
- RADEON_COLOR_ARG( 1, C );
- RADEON_COLOR_ARG( 2, B );
- break;
- case GL_MODULATE_SUBTRACT_ATI:
- color_combine = (RADEON_BLEND_CTL_SUBTRACT |
- RADEON_CLAMP_TX);
- RADEON_COLOR_ARG( 0, A );
- RADEON_COLOR_ARG( 1, C );
- RADEON_COLOR_ARG( 2, B );
- break;
- default:
+ case GL_DOT3_RGB:
+ case GL_DOT3_RGBA:
+ /* The R100 / RV200 only support a 1X multiplier in hardware
+ * w/the ARB version.
+ */
+ if ( RGBshift != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) {
return GL_FALSE;
}
- switch ( texUnit->CombineModeA ) {
- case GL_REPLACE:
- alpha_combine = (RADEON_ALPHA_ARG_A_ZERO |
- RADEON_ALPHA_ARG_B_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_CLAMP_TX);
- RADEON_ALPHA_ARG( 0, C );
- break;
- case GL_MODULATE:
- alpha_combine = (RADEON_ALPHA_ARG_C_ZERO |
- RADEON_BLEND_CTL_ADD |
- RADEON_CLAMP_TX);
- RADEON_ALPHA_ARG( 0, A );
- RADEON_ALPHA_ARG( 1, B );
- break;
- case GL_ADD:
- alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADD |
- RADEON_CLAMP_TX);
- RADEON_ALPHA_ARG( 0, A );
- RADEON_ALPHA_ARG( 1, C );
- break;
- case GL_ADD_SIGNED:
- alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_ADDSIGNED |
- RADEON_CLAMP_TX);
- RADEON_ALPHA_ARG( 0, A );
- RADEON_ALPHA_ARG( 1, C );
- break;
- case GL_SUBTRACT:
- alpha_combine = (RADEON_COLOR_ARG_B_ZERO |
- RADEON_COMP_ARG_B |
- RADEON_BLEND_CTL_SUBTRACT |
- RADEON_CLAMP_TX);
- RADEON_ALPHA_ARG( 0, A );
- RADEON_ALPHA_ARG( 1, C );
- break;
- case GL_INTERPOLATE:
- alpha_combine = (RADEON_BLEND_CTL_BLEND |
- RADEON_CLAMP_TX);
- RADEON_ALPHA_ARG( 0, B );
- RADEON_ALPHA_ARG( 1, A );
- RADEON_ALPHA_ARG( 2, C );
- break;
-
- case GL_MODULATE_ADD_ATI:
- alpha_combine = (RADEON_BLEND_CTL_ADD |
- RADEON_CLAMP_TX);
- RADEON_ALPHA_ARG( 0, A );
- RADEON_ALPHA_ARG( 1, C );
- RADEON_ALPHA_ARG( 2, B );
- break;
- case GL_MODULATE_SIGNED_ADD_ATI:
- alpha_combine = (RADEON_BLEND_CTL_ADDSIGNED |
- RADEON_CLAMP_TX);
- RADEON_ALPHA_ARG( 0, A );
- RADEON_ALPHA_ARG( 1, C );
- RADEON_ALPHA_ARG( 2, B );
- break;
- case GL_MODULATE_SUBTRACT_ATI:
- alpha_combine = (RADEON_BLEND_CTL_SUBTRACT |
- RADEON_CLAMP_TX);
- RADEON_ALPHA_ARG( 0, A );
- RADEON_ALPHA_ARG( 1, C );
- RADEON_ALPHA_ARG( 2, B );
- break;
- default:
- return GL_FALSE;
+ RGBshift += 2;
+ if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT)
+ || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) {
+ /* is it necessary to set this or will it be ignored anyway? */
+ Ashift = RGBshift;
}
- if ( (texUnit->CombineModeRGB == GL_DOT3_RGB_EXT)
- || (texUnit->CombineModeRGB == GL_DOT3_RGB) ) {
- alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
- }
+ color_combine = (RADEON_COLOR_ARG_C_ZERO |
+ RADEON_BLEND_CTL_DOT3 |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, B );
+ break;
- /* Step 3:
- * Apply the scale factor.
- */
- color_combine |= (RGBshift << RADEON_SCALE_SHIFT);
- alpha_combine |= (Ashift << RADEON_SCALE_SHIFT);
+ case GL_MODULATE_ADD_ATI:
+ color_combine = (RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, C );
+ RADEON_COLOR_ARG( 2, B );
+ break;
+ case GL_MODULATE_SIGNED_ADD_ATI:
+ color_combine = (RADEON_BLEND_CTL_ADDSIGNED |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, C );
+ RADEON_COLOR_ARG( 2, B );
+ break;
+ case GL_MODULATE_SUBTRACT_ATI:
+ color_combine = (RADEON_BLEND_CTL_SUBTRACT |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, C );
+ RADEON_COLOR_ARG( 2, B );
+ break;
+ default:
+ return GL_FALSE;
+ }
- /* All done!
- */
+ switch ( texUnit->_CurrentCombine->ModeA ) {
+ case GL_REPLACE:
+ alpha_combine = (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, C );
+ break;
+ case GL_MODULATE:
+ alpha_combine = (RADEON_ALPHA_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, A );
+ RADEON_ALPHA_ARG( 1, B );
+ break;
+ case GL_ADD:
+ alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, A );
+ RADEON_ALPHA_ARG( 1, C );
+ break;
+ case GL_ADD_SIGNED:
+ alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADDSIGNED |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, A );
+ RADEON_ALPHA_ARG( 1, C );
+ break;
+ case GL_SUBTRACT:
+ alpha_combine = (RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_SUBTRACT |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, A );
+ RADEON_ALPHA_ARG( 1, C );
+ break;
+ case GL_INTERPOLATE:
+ alpha_combine = (RADEON_BLEND_CTL_BLEND |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, B );
+ RADEON_ALPHA_ARG( 1, A );
+ RADEON_ALPHA_ARG( 2, C );
break;
+ case GL_MODULATE_ADD_ATI:
+ alpha_combine = (RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, A );
+ RADEON_ALPHA_ARG( 1, C );
+ RADEON_ALPHA_ARG( 2, B );
+ break;
+ case GL_MODULATE_SIGNED_ADD_ATI:
+ alpha_combine = (RADEON_BLEND_CTL_ADDSIGNED |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, A );
+ RADEON_ALPHA_ARG( 1, C );
+ RADEON_ALPHA_ARG( 2, B );
+ break;
+ case GL_MODULATE_SUBTRACT_ATI:
+ alpha_combine = (RADEON_BLEND_CTL_SUBTRACT |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, A );
+ RADEON_ALPHA_ARG( 1, C );
+ RADEON_ALPHA_ARG( 2, B );
+ break;
default:
return GL_FALSE;
}
+
+ if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB_EXT)
+ || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB) ) {
+ alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
+ }
+
+ /* Step 3:
+ * Apply the scale factor.
+ */
+ color_combine |= (RGBshift << RADEON_SCALE_SHIFT);
+ alpha_combine |= (Ashift << RADEON_SCALE_SHIFT);
+
+ /* All done!
+ */
}
if ( rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] != color_combine ||
return GL_TRUE;
}
+void radeonSetTexOffset(__DRIcontext * pDRICtx, GLint texname,
+ unsigned long long offset, GLint depth, GLuint pitch)
+{
+ r100ContextPtr rmesa = pDRICtx->driverPrivate;
+ struct gl_texture_object *tObj =
+ _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
+ radeonTexObjPtr t = radeon_tex_obj(tObj);
+
+ if (tObj == NULL)
+ return;
+
+ t->image_override = GL_TRUE;
+
+ if (!offset)
+ return;
+
+ t->bo = NULL;
+ t->override_offset = offset;
+ t->pp_txpitch = pitch - 32;
+
+ switch (depth) {
+ case 32:
+ t->pp_txformat = tx_table[MESA_FORMAT_ARGB8888].format;
+ t->pp_txfilter |= tx_table[MESA_FORMAT_ARGB8888].filter;
+ break;
+ case 24:
+ default:
+ t->pp_txformat = tx_table[MESA_FORMAT_RGB888].format;
+ t->pp_txfilter |= tx_table[MESA_FORMAT_RGB888].filter;
+ break;
+ case 16:
+ t->pp_txformat = tx_table[MESA_FORMAT_RGB565].format;
+ t->pp_txfilter |= tx_table[MESA_FORMAT_RGB565].filter;
+ break;
+ }
+}
+
#define TEXOBJ_TXFILTER_MASK (RADEON_MAX_MIP_LEVEL_MASK | \
RADEON_MIN_FILTER_MASK | \
RADEON_MAG_FILTER_MASK | \
RADEON_TXFORMAT_NON_POWER2)
-static void import_tex_obj_state( radeonContextPtr rmesa,
+static void disable_tex_obj_state( r100ContextPtr rmesa,
+ int unit )
+{
+ /* do not use RADEON_DB_STATE to avoid stale texture caches */
+ uint32_t *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
+ GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT];
+ GLuint *txr_cmd = RADEON_DB_STATE( txr[unit] );
+
+ RADEON_STATECHANGE( rmesa, tex[unit] );
+
+ RADEON_STATECHANGE( rmesa, tcl );
+ rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_ST_BIT(unit) |
+ RADEON_Q_BIT(unit));
+
+ if (rmesa->radeon.TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<<unit)) {
+ TCL_FALLBACK( rmesa->radeon.glCtx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
+ rmesa->recheck_texgen[unit] = GL_TRUE;
+ }
+
+ if (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) {
+ /* this seems to be a genuine (r100 only?) hw bug. Need to remove the
+ cubic_map bit on unit 2 when the unit is disabled, otherwise every
+ 2nd (2d) mipmap on unit 0 will be broken (may not be needed for other
+ units, better be safe than sorry though).*/
+ RADEON_STATECHANGE( rmesa, tex[unit] );
+ rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &= ~RADEON_TXFORMAT_CUBIC_MAP_ENABLE;
+ }
+
+ {
+ GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
+ GLuint tmp = rmesa->TexGenEnabled;
+
+ rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
+ rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
+ rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
+ rmesa->TexGenNeedNormals[unit] = 0;
+ rmesa->TexGenEnabled |=
+ (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
+
+ if (tmp != rmesa->TexGenEnabled) {
+ rmesa->recheck_texgen[unit] = GL_TRUE;
+ rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
+ }
+ }
+}
+
+static void import_tex_obj_state( r100ContextPtr rmesa,
int unit,
radeonTexObjPtr texobj )
{
- GLuint *cmd = RADEON_DB_STATE( tex[unit] );
+/* do not use RADEON_DB_STATE to avoid stale texture caches */
+ uint32_t *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
+ GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT];
+
+ RADEON_STATECHANGE( rmesa, tex[unit] );
cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK;
cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK;
cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK;
- cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset;
cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
- RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tex[unit] );
- if (texobj->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
+ if (texobj->base.Target == GL_TEXTURE_RECTANGLE_NV) {
GLuint *txr_cmd = RADEON_DB_STATE( txr[unit] );
txr_cmd[TXR_PP_TEX_SIZE] = texobj->pp_txsize; /* NPOT only! */
txr_cmd[TXR_PP_TEX_PITCH] = texobj->pp_txpitch; /* NPOT only! */
RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.txr[unit] );
+ se_coord_fmt |= RADEON_VTX_ST0_NONPARAMETRIC << unit;
}
+ else {
+ se_coord_fmt &= ~(RADEON_VTX_ST0_NONPARAMETRIC << unit);
- texobj->dirty_state &= ~(1<<unit);
-}
+ if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) {
+ uint32_t *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
+
+ RADEON_STATECHANGE( rmesa, cube[unit] );
+ cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
+ /* state filled out in the cube_emit */
+ }
+ }
+ if (se_coord_fmt != rmesa->hw.set.cmd[SET_SE_COORDFMT]) {
+ RADEON_STATECHANGE( rmesa, set );
+ rmesa->hw.set.cmd[SET_SE_COORDFMT] = se_coord_fmt;
+ }
+ rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
+}
-static void set_texgen_matrix( radeonContextPtr rmesa,
+static void set_texgen_matrix( r100ContextPtr rmesa,
GLuint unit,
const GLfloat *s_plane,
- const GLfloat *t_plane )
+ const GLfloat *t_plane,
+ const GLfloat *r_plane,
+ const GLfloat *q_plane )
{
- static const GLfloat scale_identity[4] = { 1,1,1,1 };
-
- if (!TEST_EQ_4V( s_plane, scale_identity) ||
- !TEST_EQ_4V( t_plane, scale_identity)) {
- rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE<<unit;
- rmesa->TexGenMatrix[unit].m[0] = s_plane[0];
- rmesa->TexGenMatrix[unit].m[4] = s_plane[1];
- rmesa->TexGenMatrix[unit].m[8] = s_plane[2];
- rmesa->TexGenMatrix[unit].m[12] = s_plane[3];
-
- rmesa->TexGenMatrix[unit].m[1] = t_plane[0];
- rmesa->TexGenMatrix[unit].m[5] = t_plane[1];
- rmesa->TexGenMatrix[unit].m[9] = t_plane[2];
- rmesa->TexGenMatrix[unit].m[13] = t_plane[3];
- rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
- }
+ rmesa->TexGenMatrix[unit].m[0] = s_plane[0];
+ rmesa->TexGenMatrix[unit].m[4] = s_plane[1];
+ rmesa->TexGenMatrix[unit].m[8] = s_plane[2];
+ rmesa->TexGenMatrix[unit].m[12] = s_plane[3];
+
+ rmesa->TexGenMatrix[unit].m[1] = t_plane[0];
+ rmesa->TexGenMatrix[unit].m[5] = t_plane[1];
+ rmesa->TexGenMatrix[unit].m[9] = t_plane[2];
+ rmesa->TexGenMatrix[unit].m[13] = t_plane[3];
+
+ rmesa->TexGenMatrix[unit].m[2] = r_plane[0];
+ rmesa->TexGenMatrix[unit].m[6] = r_plane[1];
+ rmesa->TexGenMatrix[unit].m[10] = r_plane[2];
+ rmesa->TexGenMatrix[unit].m[14] = r_plane[3];
+
+ rmesa->TexGenMatrix[unit].m[3] = q_plane[0];
+ rmesa->TexGenMatrix[unit].m[7] = q_plane[1];
+ rmesa->TexGenMatrix[unit].m[11] = q_plane[2];
+ rmesa->TexGenMatrix[unit].m[15] = q_plane[3];
+
+ rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE << unit;
+ rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
}
-/* Ignoring the Q texcoord for now.
- *
- * Returns GL_FALSE if fallback required.
+/* Returns GL_FALSE if fallback required.
*/
static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+{
+ r100ContextPtr rmesa = R100_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
GLuint tmp = rmesa->TexGenEnabled;
-
- rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
- rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
- rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
+ static const GLfloat reflect[16] = {
+ -1, 0, 0, 0,
+ 0, -1, 0, 0,
+ 0, 0, -1, 0,
+ 0, 0, 0, 1 };
+
+ rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE << unit);
+ rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE << unit);
+ rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK << inputshift);
rmesa->TexGenNeedNormals[unit] = 0;
- if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) == 0) {
+ if ((texUnit->TexGenEnabled & (S_BIT|T_BIT|R_BIT|Q_BIT)) == 0) {
/* Disabled, no fallback:
*/
- rmesa->TexGenEnabled |=
- (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
+ rmesa->TexGenEnabled |=
+ (RADEON_TEXGEN_INPUT_TEXCOORD_0 + unit) << inputshift;
return GL_TRUE;
}
- else if (texUnit->TexGenEnabled & Q_BIT) {
- /* Very easy to do this, in fact would remove a fallback case
- * elsewhere, but I haven't done it yet... Fallback:
- */
- fprintf(stderr, "fallback Q_BIT\n");
- return GL_FALSE;
+ /* the r100 cannot do texgen for some coords and not for others
+ * we do not detect such cases (certainly can't do it here) and just
+ * ASSUME that when S and T are texgen enabled we do not need other
+ * non-texgen enabled coords, no matter if the R and Q bits are texgen
+ * enabled. Still check for mixed mode texgen for all coords.
+ */
+ else if ( (texUnit->TexGenEnabled & S_BIT) &&
+ (texUnit->TexGenEnabled & T_BIT) &&
+ (texUnit->GenModeS == texUnit->GenModeT) ) {
+ if ( ((texUnit->TexGenEnabled & R_BIT) &&
+ (texUnit->GenModeS != texUnit->GenModeR)) ||
+ ((texUnit->TexGenEnabled & Q_BIT) &&
+ (texUnit->GenModeS != texUnit->GenModeQ)) ) {
+ /* Mixed modes, fallback:
+ */
+ if (RADEON_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr, "fallback mixed texgen\n");
+ return GL_FALSE;
+ }
+ rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit;
}
- else if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) != (S_BIT|T_BIT) ||
- texUnit->GenModeS != texUnit->GenModeT) {
- /* Mixed modes, fallback:
- */
- /* fprintf(stderr, "fallback mixed texgen\n"); */
+ else {
+ /* some texgen mode not including both S and T bits */
+ if (RADEON_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr, "fallback mixed texgen/nontexgen\n");
return GL_FALSE;
}
- else
- rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit;
+
+ if ((texUnit->TexGenEnabled & (R_BIT | Q_BIT)) != 0) {
+ /* need this here for vtxfmt presumably. Argh we need to set
+ this from way too many places, would be much easier if we could leave
+ tcl q coord always enabled as on r200) */
+ RADEON_STATECHANGE( rmesa, tcl );
+ rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_Q_BIT(unit);
+ }
switch (texUnit->GenModeS) {
case GL_OBJECT_LINEAR:
rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_OBJ << inputshift;
- set_texgen_matrix( rmesa, unit,
+ set_texgen_matrix( rmesa, unit,
texUnit->ObjectPlaneS,
- texUnit->ObjectPlaneT);
+ texUnit->ObjectPlaneT,
+ texUnit->ObjectPlaneR,
+ texUnit->ObjectPlaneQ);
break;
case GL_EYE_LINEAR:
rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE << inputshift;
- set_texgen_matrix( rmesa, unit,
+ set_texgen_matrix( rmesa, unit,
texUnit->EyePlaneS,
- texUnit->EyePlaneT);
+ texUnit->EyePlaneT,
+ texUnit->EyePlaneR,
+ texUnit->EyePlaneQ);
break;
case GL_REFLECTION_MAP_NV:
rmesa->TexGenNeedNormals[unit] = GL_TRUE;
- rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT<<inputshift;
+ rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT << inputshift;
+ /* TODO: unknown if this is needed/correct */
+ set_texgen_matrix( rmesa, unit, reflect, reflect + 4,
+ reflect + 8, reflect + 12 );
break;
case GL_NORMAL_MAP_NV:
rmesa->TexGenNeedNormals[unit] = GL_TRUE;
- rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL<<inputshift;
+ rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL << inputshift;
break;
case GL_SPHERE_MAP:
+ /* the mode which everyone uses :-( */
default:
/* Unsupported mode, fallback:
*/
- /* fprintf(stderr, "fallback unsupported texgen\n"); */
+ if (RADEON_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr, "fallback GL_SPHERE_MAP\n");
return GL_FALSE;
}
if (tmp != rmesa->TexGenEnabled) {
- rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
+ rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
}
return GL_TRUE;
}
-
-static void disable_tex( GLcontext *ctx, int unit )
+/**
+ * Compute the cached hardware register values for the given texture object.
+ *
+ * \param rmesa Context pointer
+ * \param t the r300 texture object
+ */
+static GLboolean setup_hardware_state(r100ContextPtr rmesa, radeonTexObj *t, int unit)
{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ const struct gl_texture_image *firstImage;
+ GLint log2Width, log2Height, log2Depth, texelBytes;
- if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit)) {
- /* Texture unit disabled */
- if ( rmesa->state.texture.unit[unit].texobj != NULL ) {
- /* The old texture is no longer bound to this texture unit.
- * Mark it as such.
- */
-
- rmesa->state.texture.unit[unit].texobj->base.bound &= ~(1UL << unit);
- rmesa->state.texture.unit[unit].texobj = NULL;
- }
+ firstImage = t->base.Image[0][t->mt->firstLevel];
- RADEON_STATECHANGE( rmesa, ctx );
- rmesa->hw.ctx.cmd[CTX_PP_CNTL] &=
- ~((RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit);
-
- RADEON_STATECHANGE( rmesa, tcl );
- switch (unit) {
- case 0:
- rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_TCL_VTX_ST0 |
- RADEON_TCL_VTX_Q0);
- break;
- case 1:
- rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_TCL_VTX_ST1 |
- RADEON_TCL_VTX_Q1);
- break;
- default:
- break;
- }
-
-
- if (rmesa->TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<<unit)) {
- TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
- rmesa->recheck_texgen[unit] = GL_TRUE;
- }
-
-
-
- {
- GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
- GLuint tmp = rmesa->TexGenEnabled;
-
- rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
- rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
- rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
- rmesa->TexGenNeedNormals[unit] = 0;
- rmesa->TexGenEnabled |=
- (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
+ if (firstImage->Border > 0) {
+ fprintf(stderr, "%s: border\n", __FUNCTION__);
+ return GL_FALSE;
+ }
- if (tmp != rmesa->TexGenEnabled) {
- rmesa->recheck_texgen[unit] = GL_TRUE;
- rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
- }
+ log2Width = firstImage->WidthLog2;
+ log2Height = firstImage->HeightLog2;
+ log2Depth = firstImage->DepthLog2;
+ texelBytes = firstImage->TexFormat->TexelBytes;
+
+ if (!t->image_override) {
+ if (VALID_FORMAT(firstImage->TexFormat->MesaFormat)) {
+ const struct tx_table *table = tx_table;
+
+ t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK |
+ RADEON_TXFORMAT_ALPHA_IN_MAP);
+ t->pp_txfilter &= ~RADEON_YUV_TO_RGB;
+
+ t->pp_txformat |= table[ firstImage->TexFormat->MesaFormat ].format;
+ t->pp_txfilter |= table[ firstImage->TexFormat->MesaFormat ].filter;
+ } else {
+ _mesa_problem(NULL, "unexpected texture format in %s",
+ __FUNCTION__);
+ return GL_FALSE;
}
}
-}
-
-static GLboolean enable_tex_2d( GLcontext *ctx, int unit )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- struct gl_texture_object *tObj = texUnit->_Current;
- radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
-
- /* Need to load the 2d images associated with this unit.
- */
- if (t->pp_txformat & RADEON_TXFORMAT_NON_POWER2) {
- t->pp_txformat &= ~RADEON_TXFORMAT_NON_POWER2;
- t->base.dirty_images[0] = ~0;
+
+ t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK;
+ t->pp_txfilter |= (t->mt->lastLevel - t->mt->firstLevel) << RADEON_MAX_MIP_LEVEL_SHIFT;
+
+ t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
+ RADEON_TXFORMAT_HEIGHT_MASK |
+ RADEON_TXFORMAT_CUBIC_MAP_ENABLE |
+ RADEON_TXFORMAT_F5_WIDTH_MASK |
+ RADEON_TXFORMAT_F5_HEIGHT_MASK);
+ t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) |
+ (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT));
+
+ t->tile_bits = 0;
+
+ if (t->base.Target == GL_TEXTURE_CUBE_MAP) {
+ ASSERT(log2Width == log2Height);
+ t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_F5_WIDTH_SHIFT) |
+ (log2Height << RADEON_TXFORMAT_F5_HEIGHT_SHIFT) |
+ /* don't think we need this bit, if it exists at all - fglrx does not set it */
+ (RADEON_TXFORMAT_CUBIC_MAP_ENABLE));
+ t->pp_cubic_faces = ((log2Width << RADEON_FACE_WIDTH_1_SHIFT) |
+ (log2Height << RADEON_FACE_HEIGHT_1_SHIFT) |
+ (log2Width << RADEON_FACE_WIDTH_2_SHIFT) |
+ (log2Height << RADEON_FACE_HEIGHT_2_SHIFT) |
+ (log2Width << RADEON_FACE_WIDTH_3_SHIFT) |
+ (log2Height << RADEON_FACE_HEIGHT_3_SHIFT) |
+ (log2Width << RADEON_FACE_WIDTH_4_SHIFT) |
+ (log2Height << RADEON_FACE_HEIGHT_4_SHIFT));
}
- ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D);
+ t->pp_txsize = (((firstImage->Width - 1) << RADEON_TEX_USIZE_SHIFT)
+ | ((firstImage->Height - 1) << RADEON_TEX_VSIZE_SHIFT));
- if ( t->base.dirty_images[0] ) {
- RADEON_FIREVERTICES( rmesa );
- radeonSetTexImages( rmesa, tObj );
- radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 );
- if ( !t->base.memBlock )
- return GL_FALSE;
+ if ( !t->image_override ) {
+ if (firstImage->IsCompressed)
+ t->pp_txpitch = (firstImage->Width + 63) & ~(63);
+ else
+ t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63);
+ t->pp_txpitch -= 32;
}
- return GL_TRUE;
-}
-
-static GLboolean enable_tex_rect( GLcontext *ctx, int unit )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- struct gl_texture_object *tObj = texUnit->_Current;
- radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
-
- if (!(t->pp_txformat & RADEON_TXFORMAT_NON_POWER2)) {
+ if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2;
- t->base.dirty_images[0] = ~0;
- }
-
- ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);
-
- if ( t->base.dirty_images[0] ) {
- RADEON_FIREVERTICES( rmesa );
- radeonSetTexImages( rmesa, tObj );
- radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 );
- if ( !t->base.memBlock /* && !rmesa->prefer_gart_client_texturing FIXME */ ) {
- fprintf(stderr, "%s: upload failed\n", __FUNCTION__);
- return GL_FALSE;
- }
}
return GL_TRUE;
}
-
-static GLboolean update_tex_common( GLcontext *ctx, int unit )
+static GLboolean radeon_validate_texture(GLcontext *ctx, struct gl_texture_object *texObj, int unit)
{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- struct gl_texture_object *tObj = texUnit->_Current;
- radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
- GLenum format;
+ r100ContextPtr rmesa = R100_CONTEXT(ctx);
+ radeonTexObj *t = radeon_tex_obj(texObj);
+ int ret;
- /* Fallback if there's a texture border */
- if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) {
- fprintf(stderr, "%s: border\n", __FUNCTION__);
+ if (!radeon_validate_texture_miptree(ctx, texObj))
return GL_FALSE;
- }
-
- /* Update state if this is a different texture object to last
- * time.
- */
- if ( rmesa->state.texture.unit[unit].texobj != t ) {
- if ( rmesa->state.texture.unit[unit].texobj != NULL ) {
- /* The old texture is no longer bound to this texture unit.
- * Mark it as such.
- */
-
- rmesa->state.texture.unit[unit].texobj->base.bound &=
- ~(1UL << unit);
- }
-
- rmesa->state.texture.unit[unit].texobj = t;
- t->base.bound |= (1UL << unit);
- t->dirty_state |= 1<<unit;
- driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */
- }
+ ret = setup_hardware_state(rmesa, t, unit);
+ if (ret == GL_FALSE)
+ return GL_FALSE;
- /* Newly enabled?
- */
- if ( !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit))) {
- RADEON_STATECHANGE( rmesa, ctx );
- rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=
- (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit;
+ /* yuv conversion only works in first unit */
+ if (unit != 0 && (t->pp_txfilter & RADEON_YUV_TO_RGB))
+ return GL_FALSE;
- RADEON_STATECHANGE( rmesa, tcl );
+ RADEON_STATECHANGE( rmesa, ctx );
+ rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=
+ (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit;
- if (unit == 0)
- rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST0;
- else
- rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST1;
+ RADEON_STATECHANGE( rmesa, tcl );
+ rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_ST_BIT(unit);
- rmesa->recheck_texgen[unit] = GL_TRUE;
- }
+ rmesa->recheck_texgen[unit] = GL_TRUE;
- if (t->dirty_state & (1<<unit)) {
- import_tex_obj_state( rmesa, unit, t );
- }
+ import_tex_obj_state( rmesa, unit, t );
if (rmesa->recheck_texgen[unit]) {
GLboolean fallback = !radeon_validate_texgen( ctx, unit );
TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
rmesa->recheck_texgen[unit] = 0;
- rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
+ rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
}
- format = tObj->Image[0][tObj->BaseLevel]->Format;
- if ( rmesa->state.texture.unit[unit].format != format ||
- rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode ) {
- rmesa->state.texture.unit[unit].format = format;
- rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode;
- if ( ! radeonUpdateTextureEnv( ctx, unit ) ) {
- return GL_FALSE;
- }
+ if ( ! radeonUpdateTextureEnv( ctx, unit ) ) {
+ return GL_FALSE;
}
-
FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback );
+
+ t->validated = GL_TRUE;
return !t->border_fallback;
}
-
-
static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit )
{
+ r100ContextPtr rmesa = R100_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_TEXRECT_0 << unit, 0 );
-
- if ( texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT) ) {
- TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_TEXRECT_0 << unit, 1 );
- return (enable_tex_rect( ctx, unit ) &&
- update_tex_common( ctx, unit ));
+ if (ctx->Texture.Unit[unit]._ReallyEnabled & TEXTURE_3D_BIT) {
+ return GL_FALSE;
}
- else if ( texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) {
- return (enable_tex_2d( ctx, unit ) &&
- update_tex_common( ctx, unit ));
- }
- else if ( texUnit->_ReallyEnabled ) {
- return GL_FALSE;
+
+ if (!ctx->Texture.Unit[unit]._ReallyEnabled) {
+ /* disable the unit */
+ disable_tex_obj_state(rmesa, unit);
+ return GL_TRUE;
}
- else {
- disable_tex( ctx, unit );
- return GL_TRUE;
+
+ if (!radeon_validate_texture(ctx, ctx->Texture.Unit[unit]._Current, unit)) {
+ _mesa_warning(ctx,
+ "failed to validate texture for unit %d.\n",
+ unit);
+ rmesa->state.texture.unit[unit].texobj = NULL;
+ return GL_FALSE;
}
+ rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
+ return GL_TRUE;
}
void radeonUpdateTextureState( GLcontext *ctx )
{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ r100ContextPtr rmesa = R100_CONTEXT(ctx);
GLboolean ok;
+ /* set the ctx all textures off */
+ RADEON_STATECHANGE( rmesa, ctx );
+ rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~((RADEON_TEX_ENABLE_MASK) | (RADEON_TEX_BLEND_ENABLE_MASK));
+
ok = (radeonUpdateTextureUnit( ctx, 0 ) &&
- radeonUpdateTextureUnit( ctx, 1 ));
+ radeonUpdateTextureUnit( ctx, 1 ) &&
+ radeonUpdateTextureUnit( ctx, 2 ));
FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, !ok );
- if (rmesa->TclFallback)
+ if (rmesa->radeon.TclFallback)
radeonChooseVertexState( ctx );
}