wined3d: Simplify IWineD3DBaseTextureImpl_ApplyStateChanges.

This commit is contained in:
Stefan Dösinger 2007-08-12 13:37:17 +02:00 committed by Alexandre Julliard
parent 6746554099
commit b728ff0f55
2 changed files with 105 additions and 147 deletions

View File

@ -26,34 +26,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
static const Wined3dTextureStateMap textureObjectSamplerStates[] = {
{WINED3DSAMP_ADDRESSU, WINED3DSAMP_ADDRESSU},
{WINED3DSAMP_ADDRESSV, WINED3DSAMP_ADDRESSV},
{WINED3DSAMP_ADDRESSW, WINED3DSAMP_ADDRESSW},
{WINED3DSAMP_BORDERCOLOR, WINED3DSAMP_BORDERCOLOR},
{WINED3DSAMP_MAGFILTER, WINED3DSAMP_MAGFILTER},
{WINED3DSAMP_MINFILTER, WINED3DSAMP_MINFILTER},
{WINED3DSAMP_MIPFILTER, WINED3DSAMP_MIPFILTER},
/* applies to the texture unit
WINED3DSAMP_MIPMAPLODBIAS, WINED3DSAMP_MIPMAPLODBIAS,
*/
{WINED3DSAMP_MAXMIPLEVEL, WINED3DSAMP_MAXMIPLEVEL},
#if 0
{WINED3DSAMP_MAXANISOTROPY, GL_SUPPORTED(EXT_TEXTURE_FILTER_ANISOTROPIC) ? WINED3DSAMP_MAXANISOTROPY : WINED3DFUNC_NOTSUPPORTED},
#else
{WINED3DSAMP_MAXANISOTROPY, WINED3DSAMP_MAXANISOTROPY},
#endif
{WINED3DSAMP_SRGBTEXTURE, WINED3DFUNC_UNIMPLEMENTED},
{WINED3DSAMP_ELEMENTINDEX, WINED3DFUNC_UNIMPLEMENTED},
{WINED3DSAMP_DMAPOFFSET, WINED3DFUNC_UNIMPLEMENTED},
{-1, 0}
};
static const Wined3dTextureStateMap textureObjectTextureStates[] = {
{WINED3DTSS_ADDRESSW , WINED3DTSS_ADDRESSW},
{-1, 0}
};
/* *******************************************
IWineD3DBaseTexture IUnknown parts follow
******************************************* */
@ -337,133 +309,124 @@ static inline GLenum warpLookupType(WINED3DSAMPLERSTATETYPE Type) {
}
}
static inline void apply_wrap(const GLint textureDimensions, const DWORD state, const GLint type) {
GLint wrapParm;
if (state < minLookup[WINELOOKUP_WARPPARAM] || state > maxLookup[WINELOOKUP_WARPPARAM]) {
FIXME("Unrecognized or unsupported WINED3DTADDRESS_U value %d\n", state);
} else {
if(textureDimensions==GL_TEXTURE_CUBE_MAP_ARB) {
/* Cubemaps are always set to clamp, regardeless of the sampler state. */
wrapParm = GL_CLAMP_TO_EDGE;
} else {
wrapParm = stateLookup[WINELOOKUP_WARPPARAM][state - minLookup[WINELOOKUP_WARPPARAM]];
}
TRACE("Setting WRAP_S to %d for %x\n", wrapParm, textureDimensions);
glTexParameteri(textureDimensions, type, wrapParm);
checkGLcall("glTexParameteri(..., type, wrapParm)");
}
}
void WINAPI IWineD3DBaseTextureImpl_ApplyStateChanges(IWineD3DBaseTexture *iface,
const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
int i;
DWORD *state = This->baseTexture.states;
DWORD state;
GLint textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
IWineD3DBaseTexture_PreLoad(iface);
/* run through a couple of loops and apply and states that are different */
/* this will reduce the number of texture state changes to an absolute minimum
for multi-parameter states we pickup the first one that changes, work out the correct values for the other states
and set all the states that we've just applied to their new values */
for (i = 0 ;textureObjectSamplerStates[i].state != -1; i++) {
if (*state != samplerStates[textureObjectSamplerStates[i].state]) {
/* apply the state */
TRACE("(%p) : Changing state %u from %d to %d\n", This, i, *state , samplerStates[textureObjectSamplerStates[i].state]);
switch (textureObjectSamplerStates[i].function) {
case WINED3DSAMP_ADDRESSU:
case WINED3DSAMP_ADDRESSV: /* fall through */
case WINED3DSAMP_ADDRESSW: /* fall through */
*state = samplerStates[textureObjectSamplerStates[i].state];
if (*state < minLookup[WINELOOKUP_WARPPARAM] || *state > maxLookup[WINELOOKUP_WARPPARAM]) {
FIXME("Unrecognized or unsupported WINED3DTADDRESS_* value %d, state %d\n", *state, textureObjectSamplerStates[i].function);
} else {
GLint wrapParm;
if(textureDimensions==GL_TEXTURE_CUBE_MAP_ARB) {
/* Cubemaps are always set to clamp, regardeless of the sampler state. */
wrapParm = GL_CLAMP_TO_EDGE;
} else {
wrapParm = stateLookup[WINELOOKUP_WARPPARAM][*state - minLookup[WINELOOKUP_WARPPARAM]];
}
TRACE("Setting WRAP_R to %d for %x\n", wrapParm, textureDimensions);
glTexParameteri(textureDimensions, warpLookupType(textureObjectSamplerStates[i].function), wrapParm);
checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
}
break;
case WINED3DSAMP_BORDERCOLOR:
{
float col[4];
*state = samplerStates[textureObjectSamplerStates[i].state];
D3DCOLORTOGLFLOAT4(*state, col);
TRACE("Setting border color for %u to %x\n", textureDimensions, *state);
glTexParameterfv(textureDimensions, GL_TEXTURE_BORDER_COLOR, &col[0]);
checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
}
break;
case WINED3DSAMP_MAGFILTER:
{
GLint glValue;
*state = samplerStates[textureObjectSamplerStates[i].state];
if (*state < minLookup[WINELOOKUP_MAGFILTER] || *state > maxLookup[WINELOOKUP_MAGFILTER]) {
FIXME("Unrecognized or unsupported MAGFILTER* value %d, state %d\n", *state, textureObjectSamplerStates[i].function);
}
glValue = stateLookup[WINELOOKUP_MAGFILTER][*state - minLookup[WINELOOKUP_MAGFILTER]];
TRACE("ValueMAG=%d setting MAGFILTER to %x\n", *state, glValue);
glTexParameteri(textureDimensions, GL_TEXTURE_MAG_FILTER, glValue);
/* We need to reset the Aniotropic filtering state when we change the mag filter to WINED3DTEXF_ANISOTROPIC (this seems a bit weird, check the documentataion to see how it should be switched off. */
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && WINED3DTEXF_ANISOTROPIC == *state) {
glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]);
}
}
break;
if(samplerStates[WINED3DSAMP_ADDRESSU] != This->baseTexture.states[WINED3DTEXSTA_ADDRESSU]) {
state = samplerStates[WINED3DSAMP_ADDRESSU];
apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_S);
This->baseTexture.states[WINED3DTEXSTA_ADDRESSU] = state;
}
case WINED3DSAMP_MINFILTER:
case WINED3DSAMP_MAXMIPLEVEL:
case WINED3DSAMP_MIPFILTER: /* fall through */
{
GLint glValue;
if(samplerStates[WINED3DSAMP_ADDRESSV] != This->baseTexture.states[WINED3DTEXSTA_ADDRESSV]) {
state = samplerStates[WINED3DSAMP_ADDRESSV];
apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_T);
This->baseTexture.states[WINED3DTEXSTA_ADDRESSV] = state;
}
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] = samplerStates[WINED3DSAMP_MIPFILTER];
This->baseTexture.states[WINED3DTEXSTA_MINFILTER] = samplerStates[WINED3DSAMP_MINFILTER];
This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] = samplerStates[WINED3DSAMP_MAXMIPLEVEL];
if(samplerStates[WINED3DSAMP_ADDRESSW] != This->baseTexture.states[WINED3DTEXSTA_ADDRESSW]) {
state = samplerStates[WINED3DSAMP_ADDRESSW];
apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_R);
This->baseTexture.states[WINED3DTEXSTA_ADDRESSW] = state;
}
*state = samplerStates[textureObjectSamplerStates[i].state];
if (This->baseTexture.states[WINED3DTEXSTA_MINFILTER] < WINED3DTEXF_NONE ||
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] < WINED3DTEXF_NONE ||
This->baseTexture.states[WINED3DTEXSTA_MINFILTER] > WINED3DTEXF_ANISOTROPIC ||
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] > WINED3DTEXF_LINEAR)
{
if(samplerStates[WINED3DSAMP_BORDERCOLOR] != This->baseTexture.states[WINED3DTEXSTA_BORDERCOLOR]) {
float col[4];
FIXME("Unrecognized or unsupported D3DSAMP_MINFILTER value %d, state %d D3DSAMP_MIPFILTER value %d, state %d\n",
This->baseTexture.states[WINED3DTEXSTA_MINFILTER],
textureObjectSamplerStates[WINED3DTEXSTA_MINFILTER].function,
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER],
textureObjectSamplerStates[WINED3DTEXSTA_MIPFILTER].function);
}
glValue = minMipLookup[min(max(This->baseTexture.states[WINED3DTEXSTA_MINFILTER],WINED3DTEXF_NONE), WINED3DTEXF_ANISOTROPIC)]
[min(max(This->baseTexture.states[WINED3DTEXSTA_MIPFILTER],WINED3DTEXF_NONE), WINED3DTEXF_LINEAR)];
state = samplerStates[WINED3DSAMP_BORDERCOLOR];
D3DCOLORTOGLFLOAT4(state, col);
TRACE("Setting border color for %u to %x\n", textureDimensions, state);
glTexParameterfv(textureDimensions, GL_TEXTURE_BORDER_COLOR, &col[0]);
checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
This->baseTexture.states[WINED3DTEXSTA_BORDERCOLOR] = state;
}
TRACE("ValueMIN=%d, ValueMIP=%d, setting MINFILTER to %x\n",
This->baseTexture.states[WINED3DTEXSTA_MINFILTER],
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER], glValue);
glTexParameteri(textureDimensions, GL_TEXTURE_MIN_FILTER, glValue);
checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");
if(This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE) {
glValue = 0;
} else if(This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.levels) {
glValue = This->baseTexture.levels - 1;
} else {
glValue = This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL];
}
glTexParameteri(textureDimensions, GL_TEXTURE_BASE_LEVEL, glValue);
}
break;
break;
case WINED3DSAMP_MAXANISOTROPY:
*state = samplerStates[textureObjectSamplerStates[i].state];
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, *state);
checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ...");
} else {
WARN("Unsupported in local OpenGL implementation: glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT\n");
}
break;
case WINED3DFUNC_UNIMPLEMENTED: /* unimplemented */
TRACE("(%p) : stub\n", This);
*state = samplerStates[textureObjectSamplerStates[i].state];
break;
case WINED3DFUNC_NOTSUPPORTED: /* nop */
TRACE("(%p) : %s function is not supported by this opengl implementation\n", This, "unknown" /* TODO: replace with debug_blah... */);
*state = samplerStates[textureObjectSamplerStates[i].state];
break;
}
if(samplerStates[WINED3DSAMP_MAGFILTER] != This->baseTexture.states[WINED3DTEXSTA_MAGFILTER]) {
GLint glValue;
state = samplerStates[WINED3DSAMP_MAGFILTER];
if (state < minLookup[WINELOOKUP_MAGFILTER] || state > maxLookup[WINELOOKUP_MAGFILTER]) {
FIXME("Unrecognized or unsupported MAGFILTER* value %d\n", state);
}
state++;
glValue = stateLookup[WINELOOKUP_MAGFILTER][state - minLookup[WINELOOKUP_MAGFILTER]];
TRACE("ValueMAG=%d setting MAGFILTER to %x\n", state, glValue);
glTexParameteri(textureDimensions, GL_TEXTURE_MAG_FILTER, glValue);
/* We need to reset the Aniotropic filtering state when we change the mag filter to WINED3DTEXF_ANISOTROPIC (this seems a bit weird, check the documentataion to see how it should be switched off. */
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && WINED3DTEXF_ANISOTROPIC == state) {
glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]);
}
This->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = state;
}
if(samplerStates[WINED3DSAMP_MINFILTER] != This->baseTexture.states[WINED3DTEXSTA_MINFILTER] ||
samplerStates[WINED3DSAMP_MIPFILTER] != This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] ||
samplerStates[WINED3DSAMP_MAXMIPLEVEL] != This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL]) {
GLint glValue;
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] = samplerStates[WINED3DSAMP_MIPFILTER];
This->baseTexture.states[WINED3DTEXSTA_MINFILTER] = samplerStates[WINED3DSAMP_MINFILTER];
This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] = samplerStates[WINED3DSAMP_MAXMIPLEVEL];
if (This->baseTexture.states[WINED3DTEXSTA_MINFILTER] < WINED3DTEXF_NONE ||
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] < WINED3DTEXF_NONE ||
This->baseTexture.states[WINED3DTEXSTA_MINFILTER] > WINED3DTEXF_ANISOTROPIC ||
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] > WINED3DTEXF_LINEAR)
{
FIXME("Unrecognized or unsupported D3DSAMP_MINFILTER value %d D3DSAMP_MIPFILTER value %d\n",
This->baseTexture.states[WINED3DTEXSTA_MINFILTER],
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER]);
}
glValue = minMipLookup[min(max(samplerStates[WINED3DSAMP_MINFILTER],WINED3DTEXF_NONE), WINED3DTEXF_ANISOTROPIC)]
[min(max(samplerStates[WINED3DSAMP_MIPFILTER],WINED3DTEXF_NONE), WINED3DTEXF_LINEAR)];
TRACE("ValueMIN=%d, ValueMIP=%d, setting MINFILTER to %x\n",
samplerStates[WINED3DSAMP_MINFILTER],
samplerStates[WINED3DSAMP_MIPFILTER], glValue);
glTexParameteri(textureDimensions, GL_TEXTURE_MIN_FILTER, glValue);
checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");
if(This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE) {
glValue = 0;
} else if(This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.levels) {
glValue = This->baseTexture.levels - 1;
} else {
glValue = This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL];
}
glTexParameteri(textureDimensions, GL_TEXTURE_BASE_LEVEL, glValue);
}
if(samplerStates[WINED3DSAMP_MAXANISOTROPY] != This->baseTexture.states[WINED3DTEXSTA_MAXANISOTROPY]) {
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]);
checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ...");
} else {
WARN("Unsupported in local OpenGL implementation: glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT\n");
}
This->baseTexture.states[WINED3DTEXSTA_MAXANISOTROPY] = samplerStates[WINED3DSAMP_MAXANISOTROPY];
}
}

View File

@ -910,11 +910,6 @@ typedef enum winetexturestates {
MAX_WINETEXTURESTATES = 13,
} winetexturestates;
typedef struct Wined3dTextureStateMap {
CONST int state;
int function;
} Wined3dTextureStateMap;
/*****************************************************************************
* IWineD3DBaseTexture implementation structure (extends IWineD3DResourceImpl)
*/