#include "glheader.h"
#include "macros.h"
#include "mtypes.h"
#include "simple_list.h"
#include "enums.h"
#include "mm.h"
#include "i810screen.h"
#include "i810_dri.h"
#include "i810context.h"
#include "i810tex.h"
#include "i810state.h"
#include "i810ioctl.h"
static void i810SetTexImages( i810ContextPtr imesa,
struct gl_texture_object *tObj )
{
GLuint height, width, pitch, i, textureFormat, log_pitch;
i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData;
const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel];
GLint numLevels;
GLint log2Width, log2Height;
switch (baseImage->Format) {
case GL_RGB:
case GL_LUMINANCE:
t->texelBytes = 2;
textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_RGB565;
break;
case GL_ALPHA:
case GL_LUMINANCE_ALPHA:
case GL_INTENSITY:
case GL_RGBA:
t->texelBytes = 2;
textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_ARGB4444;
break;
case GL_COLOR_INDEX:
textureFormat = MI1_FMT_8CI | MI1_PF_8CI_ARGB4444;
t->texelBytes = 1;
break;
case GL_YCBCR_MESA:
t->texelBytes = 2;
textureFormat = MI1_FMT_422 | MI1_PF_422_YCRCB_SWAP_Y
| MI1_COLOR_CONV_ENABLE;
break;
default:
fprintf(stderr, "i810SetTexImages: bad image->Format\n" );
return;
}
driCalculateTextureFirstLastLevel( (driTextureObject *) t );
numLevels = t->base.lastLevel - t->base.firstLevel + 1;
log2Width = tObj->Image[t->base.firstLevel]->WidthLog2;
log2Height = tObj->Image[t->base.firstLevel]->HeightLog2;
width = tObj->Image[t->base.firstLevel]->Width * t->texelBytes;
for (pitch = 32, log_pitch=2 ; pitch < width ; pitch *= 2 )
log_pitch++;
for ( height = i = 0 ; i < numLevels ; i++ ) {
t->image[i].image = tObj->Image[t->base.firstLevel + i];
t->image[i].offset = height * pitch;
t->image[i].internalFormat = baseImage->Format;
height += t->image[i].image->Height;
}
t->Pitch = pitch;
t->base.totalSize = height*pitch;
t->max_level = i-1;
t->dirty = I810_UPLOAD_TEX0 | I810_UPLOAD_TEX1;
t->Setup[I810_TEXREG_MI1] = (MI1_MAP_0 | textureFormat | log_pitch);
t->Setup[I810_TEXREG_MI2] = (MI2_DIMENSIONS_ARE_LOG2 |
(log2Height << 16) | log2Width);
t->Setup[I810_TEXREG_MLL] = (GFX_OP_MAP_LOD_LIMITS |
MLL_MAP_0 |
MLL_UPDATE_MAX_MIP |
MLL_UPDATE_MIN_MIP |
((numLevels - 1) << MLL_MIN_MIP_SHIFT));
LOCK_HARDWARE( imesa );
i810UploadTexImagesLocked( imesa, t );
UNLOCK_HARDWARE( imesa );
}
#define I810_DISABLE 0
#define I810_PASSTHRU 1
#define I810_REPLACE 2
#define I810_MODULATE 3
#define I810_DECAL 4
#define I810_BLEND 5
#define I810_ALPHA_BLEND 6
#define I810_ADD 7
#define I810_MAX_COMBFUNC 8
static GLuint i810_color_combine[][I810_MAX_COMBFUNC] =
{
{
( GFX_OP_MAP_COLOR_STAGES |
MC_STAGE_0 |
MC_UPDATE_DEST |
MC_DEST_CURRENT |
MC_UPDATE_ARG1 |
MC_ARG1_ITERATED_COLOR |
MC_UPDATE_ARG2 |
MC_ARG2_ONE |
MC_UPDATE_OP |
MC_OP_ARG1 ),
( GFX_OP_MAP_COLOR_STAGES |
MC_STAGE_0 |
MC_UPDATE_DEST |
MC_DEST_CURRENT |
MC_UPDATE_ARG1 |
MC_ARG1_ITERATED_COLOR |
MC_UPDATE_ARG2 |
MC_ARG2_ONE |
MC_UPDATE_OP |
MC_OP_ARG1 ),
( GFX_OP_MAP_COLOR_STAGES |
MC_STAGE_0 |
MC_UPDATE_DEST |
MC_DEST_CURRENT |
MC_UPDATE_ARG1 |
MC_ARG1_TEX0_COLOR |
MC_UPDATE_ARG2 |
MC_ARG2_ONE |
MC_UPDATE_OP |
MC_OP_ARG1 ),
( GFX_OP_MAP_COLOR_STAGES |
MC_STAGE_0 |
MC_UPDATE_DEST |
MC_DEST_CURRENT |
MC_UPDATE_ARG1 |
MC_ARG1_TEX0_COLOR |
MC_UPDATE_ARG2 |
MC_ARG2_ITERATED_COLOR |
MC_UPDATE_OP |
MC_OP_MODULATE ),
( GFX_OP_MAP_COLOR_STAGES |
MC_STAGE_0 |
MC_UPDATE_DEST |
MC_DEST_CURRENT |
MC_UPDATE_ARG1 |
MC_ARG1_COLOR_FACTOR |
MC_UPDATE_ARG2 |
MC_ARG2_TEX0_COLOR |
MC_UPDATE_OP |
MC_OP_LIN_BLEND_TEX0_ALPHA ),
( GFX_OP_MAP_COLOR_STAGES |
MC_STAGE_0 |
MC_UPDATE_DEST |
MC_DEST_CURRENT |
MC_UPDATE_ARG1 |
MC_ARG1_COLOR_FACTOR |
MC_UPDATE_ARG2 |
MC_ARG2_ITERATED_COLOR |
MC_UPDATE_OP |
MC_OP_LIN_BLEND_TEX0_COLOR ),
( GFX_OP_MAP_COLOR_STAGES |
MC_STAGE_0 |
MC_UPDATE_DEST |
MC_DEST_CURRENT |
MC_UPDATE_ARG1 |
MC_ARG1_TEX0_COLOR |
MC_UPDATE_ARG2 |
MC_ARG2_ITERATED_COLOR |
MC_UPDATE_OP |
MC_OP_LIN_BLEND_TEX0_ALPHA ),
( GFX_OP_MAP_COLOR_STAGES |
MC_STAGE_0 |
MC_UPDATE_DEST |
MC_DEST_CURRENT |
MC_UPDATE_ARG1 |
MC_ARG1_TEX0_COLOR |
MC_UPDATE_ARG2 |
MC_ARG2_ITERATED_COLOR |
MC_UPDATE_OP |
MC_OP_ADD ),
},
{
( GFX_OP_MAP_COLOR_STAGES |
MC_STAGE_1 |
MC_UPDATE_DEST |
MC_DEST_CURRENT |
MC_UPDATE_ARG1 |
MC_ARG1_ONE |
MC_UPDATE_ARG2 |
MC_ARG2_ONE |
MC_UPDATE_OP |
MC_OP_DISABLE ),
( GFX_OP_MAP_COLOR_STAGES |
MC_STAGE_1 |
MC_UPDATE_DEST |
MC_DEST_CURRENT |
MC_UPDATE_ARG1 |
MC_ARG1_CURRENT_COLOR |
MC_UPDATE_ARG2 |
MC_ARG2_ONE |
MC_UPDATE_OP |
MC_OP_ARG1 ),
( GFX_OP_MAP_COLOR_STAGES |
MC_STAGE_1 |
MC_UPDATE_DEST |
MC_DEST_CURRENT |
MC_UPDATE_ARG1 |
MC_ARG1_TEX1_COLOR |
MC_UPDATE_ARG2 |
MC_ARG2_ONE |
MC_UPDATE_OP |
MC_OP_ARG1 ),
( GFX_OP_MAP_COLOR_STAGES |
MC_STAGE_1 |
MC_UPDATE_DEST |
MC_DEST_CURRENT |
MC_UPDATE_ARG1 |
MC_ARG1_TEX1_COLOR |
MC_UPDATE_ARG2 |
MC_ARG2_CURRENT_COLOR |
MC_UPDATE_OP |
MC_OP_MODULATE ),
( GFX_OP_MAP_COLOR_STAGES |
MC_STAGE_1 |
MC_UPDATE_DEST |
MC_DEST_CURRENT |
MC_UPDATE_ARG1 |
MC_ARG1_COLOR_FACTOR |
MC_UPDATE_ARG2 |
MC_ARG2_TEX1_COLOR |
MC_UPDATE_OP |
MC_OP_LIN_BLEND_TEX1_ALPHA ),
( GFX_OP_MAP_COLOR_STAGES |
MC_STAGE_1 |
MC_UPDATE_DEST |
MC_DEST_CURRENT |
MC_UPDATE_ARG1 |
MC_ARG1_COLOR_FACTOR |
MC_UPDATE_ARG2 |
MC_ARG2_CURRENT_COLOR |
MC_UPDATE_OP |
MC_OP_LIN_BLEND_TEX1_COLOR ),
( GFX_OP_MAP_COLOR_STAGES |
MC_STAGE_1 |
MC_UPDATE_DEST |
MC_DEST_CURRENT |
MC_UPDATE_ARG1 |
MC_ARG1_TEX1_COLOR |
MC_UPDATE_ARG2 |
MC_ARG2_CURRENT_COLOR |
MC_UPDATE_OP |
MC_OP_LIN_BLEND_TEX1_ALPHA ),
( GFX_OP_MAP_COLOR_STAGES |
MC_STAGE_1 |
MC_UPDATE_DEST |
MC_DEST_CURRENT |
MC_UPDATE_ARG1 |
MC_ARG1_TEX1_COLOR |
MC_UPDATE_ARG2 |
MC_ARG2_CURRENT_COLOR |
MC_UPDATE_OP |
MC_OP_ADD ),
}
};
static GLuint i810_alpha_combine[][I810_MAX_COMBFUNC] =
{
{
( GFX_OP_MAP_ALPHA_STAGES |
MA_STAGE_0 |
MA_UPDATE_ARG1 |
MA_ARG1_ITERATED_ALPHA |
MA_UPDATE_ARG2 |
MA_ARG2_TEX0_ALPHA |
MA_UPDATE_OP |
MA_OP_ARG1 ),
( GFX_OP_MAP_ALPHA_STAGES |
MA_STAGE_0 |
MA_UPDATE_ARG1 |
MA_ARG1_ITERATED_ALPHA |
MA_UPDATE_ARG2 |
MA_ARG2_TEX0_ALPHA |
MA_UPDATE_OP |
MA_OP_ARG1 ),
( GFX_OP_MAP_ALPHA_STAGES |
MA_STAGE_0 |
MA_UPDATE_ARG1 |
MA_ARG1_ITERATED_ALPHA |
MA_UPDATE_ARG2 |
MA_ARG2_TEX0_ALPHA |
MA_UPDATE_OP |
MA_OP_ARG2 ),
( GFX_OP_MAP_ALPHA_STAGES |
MA_STAGE_0 |
MA_UPDATE_ARG1 |
MA_ARG1_ITERATED_ALPHA |
MA_UPDATE_ARG2 |
MA_ARG2_TEX0_ALPHA |
MA_UPDATE_OP |
MA_OP_MODULATE ),
( GFX_OP_MAP_ALPHA_STAGES |
MA_STAGE_0 |
MA_UPDATE_ARG1 |
MA_ARG1_ALPHA_FACTOR |
MA_UPDATE_ARG2 |
MA_ARG2_ALPHA_FACTOR |
MA_UPDATE_OP |
MA_OP_ARG1 ),
( GFX_OP_MAP_ALPHA_STAGES |
MA_STAGE_0 |
MA_UPDATE_ARG1 |
MA_ARG1_ALPHA_FACTOR |
MA_UPDATE_ARG2 |
MA_ARG2_ITERATED_ALPHA |
MA_UPDATE_OP |
MA_OP_LIN_BLEND_TEX0_ALPHA ),
( GFX_OP_MAP_ALPHA_STAGES |
MA_STAGE_0 |
MA_UPDATE_ARG1 |
MA_ARG1_ALPHA_FACTOR |
MA_UPDATE_ARG2 |
MA_ARG2_ITERATED_ALPHA |
MA_UPDATE_OP |
MA_OP_LIN_BLEND_TEX0_ALPHA ),
( GFX_OP_MAP_ALPHA_STAGES |
MA_STAGE_0 |
MA_UPDATE_ARG1 |
MA_ARG1_ITERATED_ALPHA |
MA_UPDATE_ARG2 |
MA_ARG2_TEX0_ALPHA |
MA_UPDATE_OP |
MA_OP_ADD ),
},
{
( GFX_OP_MAP_ALPHA_STAGES |
MA_STAGE_1 |
MA_UPDATE_ARG1 |
MA_ARG1_CURRENT_ALPHA |
MA_UPDATE_ARG2 |
MA_ARG2_CURRENT_ALPHA |
MA_UPDATE_OP |
MA_OP_ARG1 ),
( GFX_OP_MAP_ALPHA_STAGES |
MA_STAGE_1 |
MA_UPDATE_ARG1 |
MA_ARG1_CURRENT_ALPHA |
MA_UPDATE_ARG2 |
MA_ARG2_CURRENT_ALPHA |
MA_UPDATE_OP |
MA_OP_ARG1 ),
( GFX_OP_MAP_ALPHA_STAGES |
MA_STAGE_1 |
MA_UPDATE_ARG1 |
MA_ARG1_CURRENT_ALPHA |
MA_UPDATE_ARG2 |
MA_ARG2_TEX1_ALPHA |
MA_UPDATE_OP |
MA_OP_ARG2 ),
( GFX_OP_MAP_ALPHA_STAGES |
MA_STAGE_1 |
MA_UPDATE_ARG1 |
MA_ARG1_CURRENT_ALPHA |
MA_UPDATE_ARG2 |
MA_ARG2_TEX1_ALPHA |
MA_UPDATE_OP |
MA_OP_MODULATE ),
( GFX_OP_MAP_ALPHA_STAGES |
MA_STAGE_1 |
MA_UPDATE_ARG1 |
MA_ARG1_ALPHA_FACTOR |
MA_UPDATE_ARG2 |
MA_ARG2_ALPHA_FACTOR |
MA_UPDATE_OP |
MA_OP_ARG1 ),
( GFX_OP_MAP_ALPHA_STAGES |
MA_STAGE_1 |
MA_UPDATE_ARG1 |
MA_ARG1_ALPHA_FACTOR |
MA_UPDATE_ARG2 |
MA_ARG2_ITERATED_ALPHA |
MA_UPDATE_OP |
MA_OP_LIN_BLEND_TEX1_ALPHA ),
( GFX_OP_MAP_ALPHA_STAGES |
MA_STAGE_1 |
MA_UPDATE_ARG1 |
MA_ARG1_ALPHA_FACTOR |
MA_UPDATE_ARG2 |
MA_ARG2_ITERATED_ALPHA |
MA_UPDATE_OP |
MA_OP_LIN_BLEND_TEX1_ALPHA ),
( GFX_OP_MAP_ALPHA_STAGES |
MA_STAGE_1 |
MA_UPDATE_ARG1 |
MA_ARG1_CURRENT_ALPHA |
MA_UPDATE_ARG2 |
MA_ARG2_TEX1_ALPHA |
MA_UPDATE_OP |
MA_OP_ADD ),
}
};
static void i810UpdateTexEnv( GLcontext *ctx, GLuint unit )
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
const struct gl_texture_object *tObj = texUnit->_Current;
const GLuint format = tObj->Image[tObj->BaseLevel]->Format;
GLuint color_combine, alpha_combine;
switch (texUnit->EnvMode) {
case GL_REPLACE:
if (format == GL_ALPHA) {
color_combine = i810_color_combine[unit][I810_PASSTHRU];
alpha_combine = i810_alpha_combine[unit][I810_REPLACE];
} else if (format == GL_LUMINANCE || format == GL_RGB) {
color_combine = i810_color_combine[unit][I810_REPLACE];
alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU];
} else {
color_combine = i810_color_combine[unit][I810_REPLACE];
alpha_combine = i810_alpha_combine[unit][I810_REPLACE];
}
break;
case GL_MODULATE:
if (format == GL_ALPHA) {
color_combine = i810_color_combine[unit][I810_PASSTHRU];
alpha_combine = i810_alpha_combine[unit][I810_MODULATE];
} else {
color_combine = i810_color_combine[unit][I810_MODULATE];
alpha_combine = i810_alpha_combine[unit][I810_MODULATE];
}
break;
case GL_DECAL:
switch (format) {
case GL_RGBA:
color_combine = i810_color_combine[unit][I810_ALPHA_BLEND];
alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU];
break;
case GL_RGB:
color_combine = i810_color_combine[unit][I810_REPLACE];
alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU];
break;
case GL_ALPHA:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
case GL_INTENSITY:
color_combine = i810_color_combine[unit][I810_PASSTHRU];
alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU];
break;
case GL_COLOR_INDEX:
default:
return;
}
break;
case GL_BLEND:
switch (format) {
case GL_RGB:
case GL_LUMINANCE:
color_combine = i810_color_combine[unit][I810_BLEND];
alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU];
break;
case GL_RGBA:
case GL_LUMINANCE_ALPHA:
color_combine = i810_color_combine[unit][I810_BLEND];
alpha_combine = i810_alpha_combine[unit][I810_MODULATE];
break;
case GL_ALPHA:
color_combine = i810_color_combine[unit][I810_PASSTHRU];
alpha_combine = i810_alpha_combine[unit][I810_MODULATE];
break;
case GL_INTENSITY:
color_combine = i810_color_combine[unit][I810_BLEND];
alpha_combine = i810_alpha_combine[unit][I810_BLEND];
break;
case GL_COLOR_INDEX:
default:
return;
}
break;
case GL_ADD:
switch (format) {
case GL_RGB:
case GL_LUMINANCE:
color_combine = i810_color_combine[unit][I810_ADD];
alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU];
break;
case GL_RGBA:
case GL_LUMINANCE_ALPHA:
color_combine = i810_color_combine[unit][I810_ADD];
alpha_combine = i810_alpha_combine[unit][I810_MODULATE];
break;
case GL_ALPHA:
color_combine = i810_color_combine[unit][I810_PASSTHRU];
alpha_combine = i810_alpha_combine[unit][I810_MODULATE];
break;
case GL_INTENSITY:
color_combine = i810_color_combine[unit][I810_ADD];
alpha_combine = i810_alpha_combine[unit][I810_ADD];
break;
case GL_COLOR_INDEX:
default:
return;
}
break;
default:
return;
}
if (alpha_combine != imesa->Setup[I810_CTXREG_MA0 + unit] ||
color_combine != imesa->Setup[I810_CTXREG_MC0 + unit])
{
I810_STATECHANGE( imesa, I810_UPLOAD_CTX );
imesa->Setup[I810_CTXREG_MA0 + unit] = alpha_combine;
imesa->Setup[I810_CTXREG_MC0 + unit] = color_combine;
}
}
static void i810UpdateTexUnit( GLcontext *ctx, GLuint unit )
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
if (texUnit->_ReallyEnabled == TEXTURE_2D_BIT)
{
struct gl_texture_object *tObj = texUnit->_Current;
i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData;
if (t->base.dirty_images[0]) {
I810_FIREVERTICES(imesa);
i810SetTexImages( imesa, tObj );
if (!t->base.memBlock) {
FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
return;
}
}
if (tObj->Image[tObj->BaseLevel]->Border > 0) {
FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
return;
}
if (imesa->CurrentTexObj[unit] != t) {
I810_STATECHANGE(imesa, (I810_UPLOAD_TEX0<<unit));
imesa->CurrentTexObj[unit] = t;
t->base.bound |= (1U << unit);
driUpdateTextureLRU( (driTextureObject *) t );
}
if (tObj->Image[tObj->BaseLevel]->Format != imesa->TexEnvImageFmt[unit]) {
imesa->TexEnvImageFmt[unit] = tObj->Image[tObj->BaseLevel]->Format;
i810UpdateTexEnv( ctx, unit );
}
}
else if (texUnit->_ReallyEnabled) {
FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
}
else {
imesa->CurrentTexObj[unit] = 0;
imesa->TexEnvImageFmt[unit] = 0;
imesa->dirty &= ~(I810_UPLOAD_TEX0<<unit);
imesa->Setup[I810_CTXREG_MA0 + unit] =
i810_alpha_combine[unit][I810_DISABLE];
imesa->Setup[I810_CTXREG_MC0 + unit] =
i810_color_combine[unit][I810_DISABLE];
I810_STATECHANGE( imesa, I810_UPLOAD_CTX );
}
}
void i810UpdateTextureState( GLcontext *ctx )
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_FALSE );
i810UpdateTexUnit( ctx, 0 );
i810UpdateTexUnit( ctx, 1 );
}