Commit bb6f9b02 authored by Oliver Stieber's avatar Oliver Stieber Committed by Alexandre Julliard

Move the setting of states from device to basetexture, states that

relate to the opengl texture object will only be updated when they are out of sync, this reduces the number of texture object state changes during game play in Axis and allies from several hundreds to 0 or 1.
parent 3b5c2221
......@@ -23,9 +23,38 @@
#include "config.h"
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
#define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->resource.wineD3DDevice)->wineD3D))->gl_info
static const Wined3dTextureStateMap textureObjectSamplerStates[] = {
{WINED3DSAMP_ADDRESSU, WINED3DSAMP_ADDRESSU},
{WINED3DSAMP_ADDRESSV, WINED3DSAMP_ADDRESSV},
{WINED3DSAMP_ADDRESSW, WINED3DSAMP_ADDRESSW},
/* NOTE: Sometimes it's a good idea to disable the setting of border colour, e.g. Axis and Allies */
{WINED3DSAMP_BORDERCOLOR, WINED3DFUNC_NOTSUPPORTED/* 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
******************************************* */
......@@ -223,7 +252,23 @@ HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface) {
GLclampf tmp;
tmp = 0.9f;
glPrioritizeTextures(1, &This->baseTexture.textureName, &tmp);
}
/* Initilise the state of the texture object
to the openGL defaults, not the directx defaults */
This->baseTexture.states[WINED3DTEXSTA_ADDRESSU] = D3DTADDRESS_WRAP;
This->baseTexture.states[WINED3DTEXSTA_ADDRESSV] = D3DTADDRESS_WRAP;
This->baseTexture.states[WINED3DTEXSTA_ADDRESSW] = D3DTADDRESS_WRAP;
This->baseTexture.states[WINED3DTEXSTA_BORDERCOLOR] = 0;
This->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = D3DTEXF_POINT;
This->baseTexture.states[WINED3DTEXSTA_MINFILTER] = D3DTEXF_POINT;
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] = D3DTEXF_NONE;
This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] = 0;
This->baseTexture.states[WINED3DTEXSTA_MAXANISOTROPY] = 0;
This->baseTexture.states[WINED3DTEXSTA_SRGBTEXTURE] = 0;
This->baseTexture.states[WINED3DTEXSTA_ELEMENTINDEX] = 0;
This->baseTexture.states[WINED3DTEXSTA_DMAPOFFSET] = 0;
This->baseTexture.states[WINED3DTEXSTA_TSSADDRESSW] = D3DTADDRESS_WRAP;
IWineD3DBaseTexture_SetDirty(iface, TRUE);
isNewTexture = TRUE;
}
......@@ -242,14 +287,19 @@ HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface) {
}
glBindTexture(textureDimensions, This->baseTexture.textureName);
checkGLcall("glBindTexture");
if (isNewTexture) {
if (isNewTexture || (TRUE && This->baseTexture.levels >1)) {
/* For a new texture we have to set the textures levels after binding the texture,
* in theory this is all we should ever have to dom, but because ATI's drivers are broken we
* also need to set the texture dimensins before the texture is is set */
TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", This->baseTexture.levels - 1);
glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels - 1);
checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels)");
} else {
TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", This->baseTexture.levels - 1);
glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels - 1);
checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels)");
}
} else { /* this only happened if we've run out of openGL textures */
WARN("This texture doesn't have an openGL texture assigned to it\n");
hr = D3DERR_INVALIDCALL;
......@@ -285,6 +335,152 @@ UINT WINAPI IWineD3DBaseTextureImpl_GetTextureDimensions(IWineD3DBaseTexture *if
return D3D_OK;
}
static inline GLenum warpLookupType(WINED3DSAMPLERSTATETYPE Type) {
switch(Type) {
case WINED3DSAMP_ADDRESSU:
return GL_TEXTURE_WRAP_S;
case WINED3DSAMP_ADDRESSV:
return GL_TEXTURE_WRAP_T;
case WINED3DSAMP_ADDRESSW:
return GL_TEXTURE_WRAP_R;
default:
FIXME("Unexpected warp type %d\n", Type);
return 0;
}
}
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;
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 %ld to %ld \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 D3DTADDRESS_* value %ld, state %d\n", *state, textureObjectSamplerStates[i].function);
} else {
GLint 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 %lx\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 %ld, state %d\n", *state, textureObjectSamplerStates[i].function);
}
glValue = stateLookup[WINELOOKUP_MAGFILTER][*state - minLookup[WINELOOKUP_MAGFILTER]];
TRACE("ValueMAG=%ld 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 D3DTEXF_ANISOTROPIC (this seems a bit weird, check the documentataion to see how it should be switched off. */
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && D3DTEXF_ANISOTROPIC == *state) {
glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]);
}
}
break;
case WINED3DSAMP_MINFILTER:
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] = samplerStates[WINED3DSAMP_MIPFILTER];
case WINED3DSAMP_MIPFILTER: /* fall through */
{
GLint glValue;
*state = samplerStates[textureObjectSamplerStates[i].state];
if (This->baseTexture.states[WINED3DTEXSTA_MINFILTER] < D3DTEXF_NONE ||
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] < D3DTEXF_NONE ||
This->baseTexture.states[WINED3DTEXSTA_MINFILTER] > D3DTEXF_ANISOTROPIC ||
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] > D3DTEXF_LINEAR)
{
FIXME("Unrecognized or unsupported D3DSAMP_MINFILTER value %ld, state %d D3DSAMP_MIPFILTER value %ld, 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],D3DTEXF_NONE), D3DTEXF_ANISOTROPIC)]
[min(max(This->baseTexture.states[WINED3DTEXSTA_MIPFILTER],D3DTEXF_NONE), D3DTEXF_LINEAR)];
TRACE("ValueMIN=%ld, ValueMIP=%ld, 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, ...");
}
break;
case WINED3DSAMP_MAXMIPLEVEL:
*state = samplerStates[textureObjectSamplerStates[i].state];
/**
* Not really the same, but the more apprioprate than nothing
*/
glTexParameteri(textureDimensions, GL_TEXTURE_BASE_LEVEL, *state);
break;
case WINED3DSAMP_MAXANISOTROPY:
*state = samplerStates[textureObjectSamplerStates[i].state];
glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, *state);
checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ...");
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;
}
}
state++;
}
for(i = 0 ;textureObjectTextureStates[i].state != - 1; i++) {
if(*state != textureStates[textureObjectTextureStates[i].state] ) {
/* apply the state */
*state = textureStates[textureObjectTextureStates[i].state];
switch (textureObjectTextureStates[i].function) {
case WINED3DTSS_ADDRESSW:
/* I'm not sure what to do if this is set as well as ADDRESSW on the sampler, how do they interact together? */
break;
case WINED3DFUNC_UNIMPLEMENTED: /* unimplemented */
TRACE("(%p) : stub\n", This);
break;
case WINED3DFUNC_NOTSUPPORTED: /* nop */
TRACE("(%p) : function no supported by this opengl implementation\n", This);
break;
}
}
state++;
}
}
static const IWineD3DBaseTextureVtbl IWineD3DBaseTexture_Vtbl =
{
/* IUnknown */
......@@ -313,6 +509,7 @@ static const IWineD3DBaseTextureVtbl IWineD3DBaseTexture_Vtbl =
/* internal */
IWineD3DBaseTextureImpl_BindTexture,
IWineD3DBaseTextureImpl_UnBindTexture,
IWineD3DBaseTextureImpl_GetTextureDimensions
IWineD3DBaseTextureImpl_GetTextureDimensions,
IWineD3DBaseTextureImpl_ApplyStateChanges
};
......@@ -217,6 +217,13 @@ UINT WINAPI IWineD3DCubeTextureImpl_GetTextureDimensions(IWineD3DCubeTexture *if
return GL_TEXTURE_CUBE_MAP_ARB;
}
void WINAPI IWineD3DCubeTextureImpl_ApplyStateChanges(IWineD3DCubeTexture *iface,
const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
IWineD3DBaseTextureImpl_ApplyStateChanges((IWineD3DBaseTexture *)iface, textureStates, samplerStates);
}
/* *******************************************
IWineD3DCubeTexture IWineD3DCubeTexture parts follow
******************************************* */
......@@ -319,6 +326,7 @@ const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl =
IWineD3DCubeTextureImpl_BindTexture,
IWineD3DCubeTextureImpl_UnBindTexture,
IWineD3DCubeTextureImpl_GetTextureDimensions,
IWineD3DCubeTextureImpl_ApplyStateChanges,
/* IWineD3DCubeTexture */
IWineD3DCubeTextureImpl_GetLevelDesc,
IWineD3DCubeTextureImpl_GetCubeMapSurface,
......
......@@ -55,16 +55,14 @@ static unsigned int emulated_textureram = 64*1024*1024;
/* TODO: setup some flags in the regestry to enable, disable pbuffer support */
/* enable pbuffer support for offscreen textures */
BOOL pbuffer_support = TRUE;
BOOL pbuffer_support = FALSE;
/* allocate one pbuffer per surface */
BOOL pbuffer_per_surface = FALSE;
/* static function declarations */
static void WINAPI IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3DResource *resource);
static void WINAPI IWineD3DDeviceImpl_ApplyTextureStageState(IWineD3DDevice *iface, DWORD Stage, WINED3DTEXTURESTAGESTATETYPE Type);
static void WINAPI IWineD3DDeviceImpl_ApplySamplerState(IWineD3DDevice *iface, DWORD Sampler, WINED3DSAMPLERSTATETYPE Type);
static void WINAPI IWineD3DDeviceImpl_ApplyTextureUnitState(IWineD3DDevice *iface, DWORD Stage, WINED3DTEXTURESTAGESTATETYPE Type);
/* helper macros */
#define D3DMEMCHECK(object, ppResult) if(NULL == object) { *ppResult = NULL; WARN("Out of memory\n"); return D3DERR_OUTOFVIDEOMEMORY;}
......@@ -95,7 +93,7 @@ static void WINAPI IWineD3DDeviceImpl_ApplySamplerState(IWineD3DDevice *iface, D
if (Pool == D3DPOOL_DEFAULT) { \
if (IWineD3DDevice_GetAvailableTextureMem(iface) <= _size) { \
WARN("Out of 'bogus' video memory\n"); \
HeapFree(GetProcessHeap(),0,object); \
HeapFree(GetProcessHeap(), 0, object); \
*pp##type = NULL; \
return D3DERR_OUTOFVIDEOMEMORY; \
} \
......@@ -138,7 +136,7 @@ static void setup_light(IWineD3DDevice *iface, LONG Index, PLIGHTINFOEL *lightIn
/* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadMatrixf((float *) &This->stateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
glLoadMatrixf((float *)&This->stateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
/* Diffuse: */
colRGBA[0] = lightInfo->OriginalParms.Diffuse.r;
......@@ -170,8 +168,8 @@ static void setup_light(IWineD3DDevice *iface, LONG Index, PLIGHTINFOEL *lightIn
glLightf(GL_LIGHT0+Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
checkGLcall("glLightf");
if ((lightInfo->OriginalParms.Range * lightInfo->OriginalParms.Range) != 0 ) {
quad_att = 1.4/(lightInfo->OriginalParms.Range*lightInfo->OriginalParms.Range);
if ((lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range) != 0) {
quad_att = 1.4/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
} else {
quad_att = 0; /* 0 or MAX? (0 seems to be ok) */
}
......@@ -223,69 +221,85 @@ static void setup_light(IWineD3DDevice *iface, LONG Index, PLIGHTINFOEL *lightIn
}
/* Apply the current values to the specified texture stage */
void WINAPI IWineD3DDeviceImpl_SetupTextureStates(IWineD3DDevice *iface, DWORD Stage, DWORD Flags) {
void WINAPI IWineD3DDeviceImpl_SetupTextureStates(IWineD3DDevice *iface, DWORD Sampler, DWORD Flags) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
int i = 0;
float col[4];
TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
for (i = 1; i < WINED3D_HIGHEST_TEXTURE_STATE; i++) {
BOOL skip = FALSE;
switch (i) {
/* Performance: For texture states where multiples effect the outcome, only bother
applying the last one as it will pick up all the other values */
case WINED3DTSS_COLORARG0: /* Will be picked up when setting color op */
case WINED3DTSS_COLORARG1: /* Will be picked up when setting color op */
case WINED3DTSS_COLORARG2: /* Will be picked up when setting color op */
case WINED3DTSS_ALPHAARG0: /* Will be picked up when setting alpha op */
case WINED3DTSS_ALPHAARG1: /* Will be picked up when setting alpha op */
case WINED3DTSS_ALPHAARG2: /* Will be picked up when setting alpha op */
skip = TRUE;
break;
/* Performance: If the texture states only impact settings for the texture unit
(compared to the texture object) then there is no need to reapply them. The
only time they need applying is the first time, since we cheat and put the
values into the stateblock without applying.
Per-texture unit: texture function (eg. combine), ops and args
texture env color
texture generation settings
Note: Due to some special conditions there may be a need to do particular ones
of these, which is what the Flags allows */
case WINED3DTSS_COLOROP:
case WINED3DTSS_TEXCOORDINDEX:
if (!(Flags == REAPPLY_ALL)) skip = TRUE;
break;
union {
float f;
DWORD d;
} tmpvalue;
case WINED3DTSS_ALPHAOP:
if (!(Flags & REAPPLY_ALPHAOP)) skip = TRUE;
break;
/* In addition, IDirect3DDevice9::SetSamplerState will now be used for filtering, tiling,
clamping, MIPLOD, etc. This will work for up to 16 samplers.
*/
default:
skip = FALSE;
if (Sampler >= GL_LIMITS(samplers)) {
FIXME("Trying to set the state of more samplers %ld than are supported %d by this openGL implementation\n", Sampler, GL_LIMITS(samplers));
return;
}
if (skip == FALSE) {
/* Now apply the change */
IWineD3DDeviceImpl_ApplyTextureStageState(iface, Stage, i);
VTRACE(("Activating appropriate texture state %ld\n", Sampler));
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
ENTER_GL();
GLACTIVETEXTURE(Sampler);
LEAVE_GL();
/* Could we use bindTexture and then apply the states instead of GLACTIVETEXTURE */
} else if (Sampler > 0) {
FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
return;
}
/* TODO: change this to a lookup table
LOOKUP_TEXTURE_STATES lists all texture states that should be applied.
LOOKUP_CONTEXT_SATES list all context applicable states that can be applied
etc.... it's a lot cleaner, quicker and possibly easier to maintain than running a switch and setting a skip flag...
especially when there are a number of groups of states. */
TRACE("-----------------------> Updating the texture at Sampler %ld to have new texture state information\n", Sampler);
/* The list of states not to apply is a big as the list of states to apply, so it makes sense to produce an inclusive list */
#define APPLY_STATE(_state) IWineD3DDeviceImpl_ApplyTextureUnitState(iface, Sampler, _state)
/* these are the only two supported states that need to be applied */
APPLY_STATE(WINED3DTSS_TEXCOORDINDEX);
APPLY_STATE(WINED3DTSS_TEXTURETRANSFORMFLAGS);
#if 0 /* not supported at the moment */
APPLY_STATE(WINED3DTSS_BUMPENVMAT00);
APPLY_STATE(WINED3DTSS_BUMPENVMAT01);
APPLY_STATE(WINED3DTSS_BUMPENVMAT10);
APPLY_STATE(WINED3DTSS_BUMPENVMAT11);
APPLY_STATE(WINED3DTSS_BUMPENVLSCALE);
APPLY_STATE(WINED3DTSS_BUMPENVLOFFSET);
APPLY_STATE(WINED3DTSS_RESULTARG);
APPLY_STATE(WINED3DTSS_CONSTANT);
#endif
/* a quick sanity check incase someone forgot to update this function */
if (WINED3D_HIGHEST_TEXTURE_STATE > WINED3DTSS_CONSTANT) {
FIXME("(%p) : There are more texture states than expected, update device.c to match\n", This);
}
#undef APPLY_STATE
/* apply the sampler states to the texture */
for (i = 1; i <= WINED3D_HIGHEST_SAMPLER_STATE; i++) {
IWineD3DDeviceImpl_ApplySamplerState(iface, Stage, i);
/* apply any sampler states that always need applying */
if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
tmpvalue.d = This->stateBlock->samplerState[Sampler][WINED3DSAMP_MIPMAPLODBIAS];
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
GL_TEXTURE_LOD_BIAS_EXT,
tmpvalue.f);
checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
}
/* Note the D3DRS value applies to all textures, but GL has one
* per texture, so apply it now ready to be used!
*/
D3DCOLORTOGLFLOAT4(This->stateBlock->renderState[WINED3DRS_TEXTUREFACTOR], col);
/* Set the default alpha blend color */
glBlendColor(col[0], col[1], col[2], col[3]);
checkGLcall("glBlendColor");
D3DCOLORTOGLFLOAT4(This->stateBlock->renderState[WINED3DRS_TEXTUREFACTOR], col);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage);
TRACE("-----------------------> Updated the texture at Sampler %ld to have new texture state information\n", Sampler);
}
/**********************************************************
......@@ -3272,286 +3286,10 @@ HRESULT WINAPI IWineD3DDeviceImpl_GetRenderState(IWineD3DDevice *iface, D3DRENDE
}
/*****
* Apply / Get / Set Sampler States
* Get / Set Sampler States
* TODO: Verify against dx9 definitions
*****/
/* NOTE: It is expected that this function is called a number of times in a row for the same texture unit, so it is more efficient if the caller sets the active texture unit before calling this function. set the correct Texture unit active before calling ApplySamplerState */
static void WINAPI IWineD3DDeviceImpl_ApplySamplerState(IWineD3DDevice *iface, DWORD Sampler, WINED3DSAMPLERSTATETYPE Type) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
DWORD Value = This->stateBlock->samplerState[Sampler][Type];
/**
* SetSampler is designed to allow for more than the standard up to 8 textures
* and Geforce has stopped supporting more than 6 standard textures in openGL.
* So I have to use ARB for Gforce. (maybe if the sampler > 4 then use ARB?)
*
* http://developer.nvidia.com/object/General_FAQ.html#t6
*
* There are two new settings for GForce
* the sampler one:
* GL_MAX_TEXTURE_IMAGE_UNITS_ARB
* and the texture one:
* GL_MAX_TEXTURE_COORDS_ARB.
* Ok GForce say it's ok to use glTexParameter/glGetTexParameter(...).
******************/
union {
float f;
DWORD d;
} tmpvalue;
TRACE("(%p) Sampler(%ld), Type(%d) Value(%ld)\n",This, Sampler ,Type, Value);
if(Sampler > GL_LIMITS(samplers) || Sampler < 0 || Type > WINED3D_HIGHEST_SAMPLER_STATE || Type < 0) {
return;
}
TRACE("Setting sampler %ld %d to %ld \n", Sampler, Type, Value);
/* In addition, IDirect3DDevice9::SetSamplerState will now be used for filtering, tiling,
clamping, MIPLOD, etc. This will work for up to 16 samplers.
is this just GL_TEXTURE_2D or is it GL_TEXTURE_1D and GL_TEXTURE_3D as well?
*/
ENTER_GL();
switch (Type) {
case WINED3DSAMP_ADDRESSU : /* 1 */
case WINED3DSAMP_ADDRESSV : /* 2 */
case WINED3DSAMP_ADDRESSW : /* 3 */
{
GLint wrapParm = GL_REPEAT;
switch (Value) {
case D3DTADDRESS_WRAP: wrapParm = GL_REPEAT; break;
case D3DTADDRESS_CLAMP: wrapParm = GL_CLAMP_TO_EDGE; break;
case D3DTADDRESS_BORDER:
{
if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
wrapParm = GL_CLAMP_TO_BORDER_ARB;
} else {
/* FIXME: Not right, but better */
TRACE("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value, Type);
wrapParm = GL_REPEAT;
}
}
break;
case D3DTADDRESS_MIRROR:
{
if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
wrapParm = GL_MIRRORED_REPEAT_ARB;
} else {
/* Unsupported in OpenGL pre-1.4 */
TRACE("Unsupported D3DTADDRESS_MIRROR (needs GL_ARB_texture_mirrored_repeat) state %d\n", Type);
wrapParm = GL_REPEAT;
}
}
break;
case D3DTADDRESS_MIRRORONCE:
{
if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
wrapParm = GL_MIRROR_CLAMP_TO_EDGE_ATI;
} else {
TRACE("Unsupported D3DTADDRESS_MIRRORONCE (needs GL_ATI_texture_mirror_once) state %d\n", Type);
wrapParm = GL_REPEAT;
}
}
break;
default:
/* This is for the whole context, not just the sampler,
so we should warn if two states are baing set for any given scene */
if (Type!=0)
TRACE("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value, Type);
wrapParm = GL_REPEAT;
}
switch (Type) {
case WINED3DSAMP_ADDRESSU:
TRACE("Setting WRAP_S for %ld to %d \n", Sampler, wrapParm);
glTexParameteri(This->stateBlock->textureDimensions[Sampler], GL_TEXTURE_WRAP_S, wrapParm);
checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_S, wrapParm)");
break;
case WINED3DSAMP_ADDRESSV:
TRACE("Setting WRAP_T for %ld to %d\n", Sampler, wrapParm);
glTexParameteri(This->stateBlock->textureDimensions[Sampler], GL_TEXTURE_WRAP_T, wrapParm);
checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_T, wrapParm)");
break;
case WINED3DSAMP_ADDRESSW:
TRACE("Setting WRAP_R for %ld to %d\n", Sampler, wrapParm);
glTexParameteri(This->stateBlock->textureDimensions[Sampler], GL_TEXTURE_WRAP_R, wrapParm);
checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
break;
default: /* nop */
break; /** stupic compilator */
}
}
break;
case WINED3DSAMP_BORDERCOLOR : /* 4 */
{
float col[4];
D3DCOLORTOGLFLOAT4(Value, col);
TRACE("Setting border color for %ld to %lx\n", Sampler, Value);
glTexParameterfv(This->stateBlock->textureDimensions[Sampler], GL_TEXTURE_BORDER_COLOR, &col[0]);
checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
}
break;
case WINED3DSAMP_MAGFILTER : /* 5 */
{
DWORD ValueMAG = This->stateBlock->samplerState[Sampler][WINED3DSAMP_MAGFILTER];
GLint realVal = GL_NEAREST;
if (ValueMAG == D3DTEXF_POINT) {
realVal = GL_NEAREST;
} else if (ValueMAG == D3DTEXF_LINEAR) {
realVal = GL_LINEAR;
} else if (ValueMAG == D3DTEXF_ANISOTROPIC) {
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
realVal = GL_LINEAR;
} else {
FIXME("Trying to use ANISOTROPIC_FILTERING for WINED3DTSS_MAGFILTER. But not supported by current OpenGL driver\n");
realVal = GL_NEAREST;
}
} else {
FIXME("Unhandled WINED3DTSS_MAGFILTER value of %ld\n", ValueMAG);
realVal = GL_NEAREST;
}
TRACE("ValueMAG=%ld setting MAGFILTER to %x\n", ValueMAG, realVal);
glTexParameteri(This->stateBlock->textureDimensions[Sampler], GL_TEXTURE_MAG_FILTER, realVal);
checkGLcall("glTexParameter GL_TEXTURE_MAG_FILTER, ...");
/**
* if we juste choose to use ANISOTROPIC filtering, refresh openGL state
*/
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && D3DTEXF_ANISOTROPIC == ValueMAG) {
glTexParameteri(This->stateBlock->textureDimensions[Sampler],
GL_TEXTURE_MAX_ANISOTROPY_EXT,
This->stateBlock->samplerState[Sampler][WINED3DSAMP_MAXANISOTROPY]);
checkGLcall("glTexParameter GL_TEXTURE_MAX_ANISOTROPY_EXT, ...");
}
}
break;
case WINED3DSAMP_MINFILTER: /* 6 */
case WINED3DSAMP_MIPFILTER: /* 7 */
{
DWORD ValueMIN = This->stateBlock->samplerState[Sampler][WINED3DSAMP_MINFILTER];
DWORD ValueMIP = This->stateBlock->samplerState[Sampler][WINED3DSAMP_MIPFILTER];
GLint realVal = GL_LINEAR;
if (ValueMIN == D3DTEXF_NONE) {
/* Doesn't really make sense - Windows just seems to disable
mipmapping when this occurs */
FIXME("Odd - minfilter of none, just disabling mipmaps\n");
realVal = GL_LINEAR;
} else if (ValueMIN == D3DTEXF_POINT) {
/* GL_NEAREST_* */
if (ValueMIP == D3DTEXF_NONE) {
realVal = GL_NEAREST;
} else if (ValueMIP == D3DTEXF_POINT) {
realVal = GL_NEAREST_MIPMAP_NEAREST;
} else if (ValueMIP == D3DTEXF_LINEAR) {
realVal = GL_NEAREST_MIPMAP_LINEAR;
} else {
FIXME("Unhandled WINED3DTSS_MIPFILTER value of %ld\n", ValueMIP);
realVal = GL_NEAREST;
}
} else if (ValueMIN == D3DTEXF_LINEAR) {
/* GL_LINEAR_* */
if (ValueMIP == D3DTEXF_NONE) {
realVal = GL_LINEAR;
} else if (ValueMIP == D3DTEXF_POINT) {
realVal = GL_LINEAR_MIPMAP_NEAREST;
} else if (ValueMIP == D3DTEXF_LINEAR) {
realVal = GL_LINEAR_MIPMAP_LINEAR;
} else {
FIXME("Unhandled WINED3DTSS_MIPFILTER value of %ld\n", ValueMIP);
realVal = GL_LINEAR;
}
} else if (ValueMIN == D3DTEXF_ANISOTROPIC) {
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
if (ValueMIP == D3DTEXF_NONE) {
realVal = GL_LINEAR_MIPMAP_LINEAR;
} else if (ValueMIP == D3DTEXF_POINT) {
realVal = GL_LINEAR_MIPMAP_NEAREST;
} else if (ValueMIP == D3DTEXF_LINEAR) {
realVal = GL_LINEAR_MIPMAP_LINEAR;
} else {
FIXME("Unhandled WINED3DTSS_MIPFILTER value of %ld\n", ValueMIP);
realVal = GL_LINEAR;
}
} else {
WARN("Trying to use ANISOTROPIC_FILTERING for WINED3DTSS_MINFILTER. But not supported by OpenGL driver\n");
realVal = GL_LINEAR;
}
} else {
FIXME("Unhandled WINED3DTSS_MINFILTER value of %ld\n", ValueMIN);
realVal = GL_LINEAR_MIPMAP_LINEAR;
}
TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", ValueMIN, ValueMIP, realVal);
glTexParameteri(This->stateBlock->textureDimensions[Sampler], GL_TEXTURE_MIN_FILTER, realVal);
checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");
/**
* if we just choose to use ANISOTROPIC filtering, refresh openGL state
*/
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && D3DTEXF_ANISOTROPIC == ValueMIN) {
glTexParameteri(This->stateBlock->textureDimensions[Sampler], GL_TEXTURE_MAX_ANISOTROPY_EXT,
This->stateBlock->samplerState[Sampler][WINED3DSAMP_MAXANISOTROPY]);
checkGLcall("glTexParameter GL_TEXTURE_MAX_ANISOTROPY_EXT, ...");
}
}
break;
case WINED3DSAMP_MIPMAPLODBIAS : /* 8 */
{
if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
tmpvalue.d = Value;
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
GL_TEXTURE_LOD_BIAS_EXT,
tmpvalue.f);
checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
}
}
break;
case WINED3DSAMP_MAXMIPLEVEL : /* 9 */
{
/**
* Not really the same, but the more apprioprate than nothing
*/
glTexParameteri(This->stateBlock->textureDimensions[Sampler],
GL_TEXTURE_BASE_LEVEL,
This->stateBlock->samplerState[Sampler][WINED3DSAMP_MAXMIPLEVEL]);
checkGLcall("glTexParameteri GL_TEXTURE_BASE_LEVEL ...");
}
break;
case WINED3DSAMP_MAXANISOTROPY : /* 10 */
{
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
glTexParameteri(This->stateBlock->textureDimensions[Sampler],
GL_TEXTURE_MAX_ANISOTROPY_EXT,
This->stateBlock->samplerState[Sampler][WINED3DSAMP_MAXANISOTROPY]);
checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ...");
}
}
break;
case WINED3DSAMP_SRGBTEXTURE : /* 11 */
/* Per texture gamma correction, default 0 */
case WINED3DSAMP_ELEMENTINDEX : /* 12 */
/* When a multi-element textures is used this indicates the element, (what's a multielement texture?) */
case WINED3DSAMP_DMAPOFFSET : /* 13 */
/* Value of a precompiled displacement map used by the tesselator, default 0 */
TRACE("Unsupported sampler setting, Sampler=%ld, Type=%d, Value =%ld\n", Sampler, Type, Value);
break;
default:
TRACE("invalid sampler setting, Sampler=%ld, Type=%d, Value =%ld\n", Sampler, Type, Value);
};
LEAVE_GL();
return;
}
HRESULT WINAPI IWineD3DDeviceImpl_SetSamplerState(IWineD3DDevice *iface, DWORD Sampler, WINED3DSAMPLERSTATETYPE Type, DWORD Value) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
/**
......@@ -3568,6 +3306,7 @@ HRESULT WINAPI IWineD3DDeviceImpl_SetSamplerState(IWineD3DDevice *iface, DWORD S
* GL_MAX_TEXTURE_COORDS_ARB.
* Ok GForce say it's ok to use glTexParameter/glGetTexParameter(...).
******************/
/** NOTE: States are appled in IWineD3DBaseTextre ApplyStateChanges and IWineD3DDevice SetupTextureStates**/
TRACE("(%p) Sampler(%ld), Type(%d) Value(%ld)\n",This, Sampler ,Type, Value);
if(Sampler > GL_LIMITS(samplers) || Sampler < 0 || Type > WINED3D_HIGHEST_SAMPLER_STATE || Type < 0) {
......@@ -3803,7 +3542,7 @@ HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, UINT Sr
*****/
/* NOTE: It's expected that this function is going to be called lots of times with the same stage active, so make it the callers responsibility to GLACTIVETEXTURE(Stage) for better state management. Set the correct Texture unit active before callnig ApplyTextureStageState */
static void WINAPI IWineD3DDeviceImpl_ApplyTextureStageState(IWineD3DDevice *iface, DWORD Stage, WINED3DTEXTURESTAGESTATETYPE Type) {
static void WINAPI IWineD3DDeviceImpl_ApplyTextureUnitState(IWineD3DDevice *iface, DWORD Stage, WINED3DTEXTURESTAGESTATETYPE Type) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
DWORD Value = This->updateStateBlock->textureState[Stage][Type];
/* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
......@@ -5504,10 +5243,10 @@ HRESULT WINAPI IWineD3DDeviceImpl_ActiveRender(IWineD3DDevice* iface,
}
}
#if 0 /* Apply the stateblock to the new context
#if 1 /* Apply the stateblock to the new context
FIXME: This is a bit of a hack, each context should know it's own state,
the directX current directX state should then be applied to the context */
{
BOOL oldRecording;
IWineD3DStateBlockImpl *oldUpdateStateBlock;
oldUpdateStateBlock = This->updateStateBlock;
......@@ -5518,6 +5257,7 @@ the directX current directX state should then be applied to the context */
This->isRecordingState = oldRecording;
This->updateStateBlock = oldUpdateStateBlock;
}
#endif
......
......@@ -58,6 +58,15 @@ inline static Display *get_display( HDC hdc )
return display;
}
/* lookup tables */
int minLookup[MAX_LOOKUPS];
int maxLookup[MAX_LOOKUPS];
DWORD *stateLookup[MAX_LOOKUPS];
DWORD minMipLookup[D3DTEXF_ANISOTROPIC + 1][D3DTEXF_LINEAR + 1];
/**
* Note: GL seems to trap if GetDeviceCaps is called before any HWND's created
* ie there is no GL Context - Get a default rendering context to enable the
......@@ -205,6 +214,7 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info, Display* display)
int major, minor;
WineD3D_Context *fake_ctx = NULL;
BOOL gotContext = FALSE;
int i;
/* Make sure that we've got a context */
if (glXGetCurrentContext() == NULL) {
......@@ -562,6 +572,55 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info, Display* display)
}
}
/* Load all the lookup tables
TODO: It may be a good idea to make minLookup and maxLookup const and populate them in wined3d_private.h where they are declared */
minLookup[WINELOOKUP_WARPPARAM] = D3DTADDRESS_WRAP;
maxLookup[WINELOOKUP_WARPPARAM] = D3DTADDRESS_MIRRORONCE;
minLookup[WINELOOKUP_MAGFILTER] = D3DTEXF_NONE;
maxLookup[WINELOOKUP_MAGFILTER] = D3DTEXF_ANISOTROPIC;
for (i = 0; i < MAX_LOOKUPS; i++) {
stateLookup[i] = HeapAlloc(GetProcessHeap(), 0, sizeof(*stateLookup[i]) * (1 + maxLookup[i] - minLookup[MAX_LOOKUPS]) );
}
stateLookup[WINELOOKUP_WARPPARAM][D3DTADDRESS_WRAP - minLookup[WINELOOKUP_WARPPARAM]] = GL_REPEAT;
stateLookup[WINELOOKUP_WARPPARAM][D3DTADDRESS_CLAMP - minLookup[WINELOOKUP_WARPPARAM]] = GL_CLAMP_TO_EDGE;
stateLookup[WINELOOKUP_WARPPARAM][D3DTADDRESS_BORDER - minLookup[WINELOOKUP_WARPPARAM]] =
gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
stateLookup[WINELOOKUP_WARPPARAM][D3DTADDRESS_BORDER - minLookup[WINELOOKUP_WARPPARAM]] =
gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
stateLookup[WINELOOKUP_WARPPARAM][D3DTADDRESS_MIRROR - minLookup[WINELOOKUP_WARPPARAM]] =
gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT;
stateLookup[WINELOOKUP_WARPPARAM][D3DTADDRESS_MIRRORONCE - minLookup[WINELOOKUP_WARPPARAM]] =
gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT;
stateLookup[WINELOOKUP_MAGFILTER][D3DTEXF_NONE - minLookup[WINELOOKUP_MAGFILTER]] = GL_NEAREST;
stateLookup[WINELOOKUP_MAGFILTER][D3DTEXF_POINT - minLookup[WINELOOKUP_MAGFILTER]] = GL_NEAREST;
stateLookup[WINELOOKUP_MAGFILTER][D3DTEXF_LINEAR - minLookup[WINELOOKUP_MAGFILTER]] = GL_LINEAR;
stateLookup[WINELOOKUP_MAGFILTER][D3DTEXF_ANISOTROPIC - minLookup[WINELOOKUP_MAGFILTER]] =
gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR : GL_NEAREST;
minMipLookup[D3DTEXF_NONE][D3DTEXF_NONE] = GL_LINEAR;
minMipLookup[D3DTEXF_NONE][D3DTEXF_POINT] = GL_LINEAR;
minMipLookup[D3DTEXF_NONE][D3DTEXF_LINEAR] = GL_LINEAR;
minMipLookup[D3DTEXF_POINT][D3DTEXF_NONE] = GL_NEAREST;
minMipLookup[D3DTEXF_POINT][D3DTEXF_POINT] = GL_NEAREST_MIPMAP_NEAREST;
minMipLookup[D3DTEXF_POINT][D3DTEXF_LINEAR] = GL_NEAREST_MIPMAP_LINEAR;
minMipLookup[D3DTEXF_LINEAR][D3DTEXF_NONE] = GL_LINEAR;
minMipLookup[D3DTEXF_LINEAR][D3DTEXF_POINT] = GL_LINEAR_MIPMAP_NEAREST;
minMipLookup[D3DTEXF_LINEAR][D3DTEXF_LINEAR] = GL_LINEAR_MIPMAP_LINEAR;
minMipLookup[D3DTEXF_ANISOTROPIC][D3DTEXF_NONE] = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ?
GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
minMipLookup[D3DTEXF_ANISOTROPIC][D3DTEXF_POINT] = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR;
minMipLookup[D3DTEXF_ANISOTROPIC][D3DTEXF_LINEAR] = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
/* TODO: config lookups */
#define USE_GL_FUNC(type, pfn) gl_info->pfn = (type) glXGetProcAddressARB( (const GLubyte *) #pfn);
GL_EXT_FUNCS_GEN;
#undef USE_GL_FUNC
......
......@@ -199,6 +199,11 @@ UINT WINAPI IWineD3DTextureImpl_GetTextureDimensions(IWineD3DTexture *iface) {
return GL_TEXTURE_2D;
}
void WINAPI IWineD3DTextureImpl_ApplyStateChanges(IWineD3DTexture *iface,
const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
IWineD3DBaseTextureImpl_ApplyStateChanges((IWineD3DBaseTexture *)iface, textureStates, samplerStates);
}
/* *******************************************
IWineD3DTexture IWineD3DTexture parts follow
......@@ -298,6 +303,7 @@ const IWineD3DTextureVtbl IWineD3DTexture_Vtbl =
IWineD3DTextureImpl_BindTexture,
IWineD3DTextureImpl_UnBindTexture,
IWineD3DTextureImpl_GetTextureDimensions,
IWineD3DTextureImpl_ApplyStateChanges,
/* IWineD3DTexture */
IWineD3DTextureImpl_GetLevelDesc,
IWineD3DTextureImpl_GetSurfaceLevel,
......
......@@ -182,6 +182,15 @@ UINT WINAPI IWineD3DVolumeTextureImpl_GetTextureDimensions(IWineD3DVolumeTexture
return GL_TEXTURE_3D;
}
void WINAPI IWineD3DVolumeTextureImpl_ApplyStateChanges(IWineD3DVolumeTexture *iface,
const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
TRACE("(%p) : nothing to do, passing to base texture\n", This);
IWineD3DBaseTextureImpl_ApplyStateChanges((IWineD3DBaseTexture *)iface, textureStates, samplerStates);
}
/* *******************************************
IWineD3DVolumeTexture IWineD3DVolumeTexture parts follow
******************************************* */
......@@ -274,6 +283,7 @@ const IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl =
IWineD3DVolumeTextureImpl_BindTexture,
IWineD3DVolumeTextureImpl_UnBindTexture,
IWineD3DVolumeTextureImpl_GetTextureDimensions,
IWineD3DVolumeTextureImpl_ApplyStateChanges,
/* volume texture */
IWineD3DVolumeTextureImpl_GetLevelDesc,
IWineD3DVolumeTextureImpl_GetVolumeLevel,
......
......@@ -66,6 +66,46 @@ extern const DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R];
extern const DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T];
extern const DWORD SavedVertexStates_S[NUM_SAVEDVERTEXSTATES_S];
typedef enum _WINELOOKUP {
WINELOOKUP_WARPPARAM = 0,
WINELOOKUP_MAGFILTER = 1,
MAX_LOOKUPS = 2
} WINELOOKUP;
extern int minLookup[MAX_LOOKUPS];
extern int maxLookup[MAX_LOOKUPS];
extern DWORD *stateLookup[MAX_LOOKUPS];
extern DWORD minMipLookup[D3DTEXF_ANISOTROPIC + 1][D3DTEXF_LINEAR + 1];
#if 0
/* NOTE: Make sure these are in the correct numerical order. (see /include/d3d9types.h typedef enum _D3DDECLTYPE) */
UINT static const glTypeLookup[D3DDECLTYPE_UNUSED][5] = {
{D3DDECLTYPE_FLOAT1, 1, GL_FLOAT , GL_FALSE ,sizeof(float)},
{D3DDECLTYPE_FLOAT2, 2, GL_FLOAT , GL_FALSE ,sizeof(float)},
{D3DDECLTYPE_FLOAT3, 3, GL_FLOAT , GL_FALSE ,sizeof(float)},
{D3DDECLTYPE_FLOAT4, 4, GL_FLOAT , GL_FALSE ,sizeof(float)},
{D3DDECLTYPE_D3DCOLOR, 4, GL_UNSIGNED_BYTE , GL_TRUE ,sizeof(BYTE)},
{D3DDECLTYPE_UBYTE4, 4, GL_UNSIGNED_BYTE , GL_FALSE ,sizeof(BYTE)},
{D3DDECLTYPE_SHORT2, 2, GL_SHORT , GL_FALSE ,sizeof(short int)},
{D3DDECLTYPE_SHORT4, 4, GL_SHORT , GL_FALSE ,sizeof(short int)},
{D3DDECLTYPE_UBYTE4N, 4, GL_UNSIGNED_BYTE , GL_FALSE ,sizeof(BYTE)},
{D3DDECLTYPE_SHORT2N, 2, GL_SHORT , GL_FALSE ,sizeof(short int)},
{D3DDECLTYPE_SHORT4N, 4, GL_SHORT , GL_FALSE ,sizeof(short int)},
{D3DDECLTYPE_USHORT2N, 2, GL_UNSIGNED_SHORT , GL_FALSE ,sizeof(short int)},
{D3DDECLTYPE_USHORT4N, 4, GL_UNSIGNED_SHORT , GL_FALSE ,sizeof(short int)},
{D3DDECLTYPE_UDEC3, 3, GL_UNSIGNED_SHORT , GL_FALSE ,sizeof(short int)},
{D3DDECLTYPE_DEC3N, 3, GL_SHORT , GL_FALSE ,sizeof(short int)},
{D3DDECLTYPE_FLOAT16_2, 2, GL_FLOAT , GL_FALSE ,sizeof(short int)},
{D3DDECLTYPE_FLOAT16_4, 4, GL_FLOAT , GL_FALSE ,sizeof(short int)}};
#define WINED3D_ATR_TYPE(_attribute) glTypeLookup[sd->u.s._attribute.dwType][0]
#define WINED3D_ATR_SIZE(_attribute) glTypeLookup[sd->u.s._attribute.dwType][1]
#define WINED3D_ATR_GLTYPE(_attribute) glTypeLookup[sd->u.s._attribute.dwType][2]
#define WINED3D_ATR_GLSOMETHING(_attribute) glTypeLookup[sd->u.s._attribute.dwType][3]
#define WINED3D_ATR_TYPESIZE(_attribute) glTypeLookup[sd->u.s._attribute.dwType][4]
#endif
/**
* Settings
*/
......@@ -583,6 +623,34 @@ typedef struct IWineD3DIndexBufferImpl
extern const IWineD3DIndexBufferVtbl IWineD3DIndexBuffer_Vtbl;
/*****************************************************************************
* IWineD3DBaseTexture D3D- > openGL state map lookups
*/
#define WINED3DFUNC_NOTSUPPORTED -2
#define WINED3DFUNC_UNIMPLEMENTED -1
typedef enum winetexturestates {
WINED3DTEXSTA_ADDRESSU = 0,
WINED3DTEXSTA_ADDRESSV = 1,
WINED3DTEXSTA_ADDRESSW = 2,
WINED3DTEXSTA_BORDERCOLOR = 3,
WINED3DTEXSTA_MAGFILTER = 4,
WINED3DTEXSTA_MINFILTER = 5,
WINED3DTEXSTA_MIPFILTER = 6,
WINED3DTEXSTA_MAXMIPLEVEL = 7,
WINED3DTEXSTA_MAXANISOTROPY = 8,
WINED3DTEXSTA_SRGBTEXTURE = 9,
WINED3DTEXSTA_ELEMENTINDEX = 10,
WINED3DTEXSTA_DMAPOFFSET = 11,
WINED3DTEXSTA_TSSADDRESSW = 12,
MAX_WINETEXTURESTATES = 13,
} winetexturestates;
typedef struct Wined3dTextureStateMap {
CONST int state;
int function;
} Wined3dTextureStateMap;
/*****************************************************************************
* IWineD3DBaseTexture implementation structure (extends IWineD3DResourceImpl)
*/
typedef struct IWineD3DBaseTextureClass
......@@ -594,6 +662,7 @@ typedef struct IWineD3DBaseTextureClass
UINT textureName;
UINT LOD;
D3DTEXTUREFILTERTYPE filterType;
DWORD states[MAX_WINETEXTURESTATES];
} IWineD3DBaseTextureClass;
......@@ -1007,6 +1076,7 @@ int D3DFmtMakeGlCfg(D3DFORMAT BackBufferFormat, D3DFORMAT StencilBufferFormat, i
extern HRESULT WINAPI IWineD3DVertexBufferImpl_ReleaseMemory(IWineD3DVertexBuffer* iface);
extern HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface);
extern HRESULT WINAPI IWineD3DBaseTextureImpl_UnBindTexture(IWineD3DBaseTexture *iface);
extern void WINAPI IWineD3DBaseTextureImpl_ApplyStateChanges(IWineD3DBaseTexture *iface, const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]);
/*** class static members ***/
void IWineD3DBaseTextureImpl_CleanUp(IWineD3DBaseTexture *iface);
......
......@@ -691,6 +691,7 @@ DECLARE_INTERFACE_(IWineD3DBaseTexture,IWineD3DResource)
STDMETHOD(BindTexture)(THIS) PURE;
STDMETHOD(UnBindTexture)(THIS) PURE;
STDMETHOD_(UINT, GetTextureDimensions)(THIS) PURE;
STDMETHOD_(void, ApplyStateChanges)(THIS_ const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) PURE;
};
#undef INTERFACE
......@@ -723,6 +724,7 @@ DECLARE_INTERFACE_(IWineD3DBaseTexture,IWineD3DResource)
#define IWineD3DBaseTexture_BindTexture(p) (p)->lpVtbl->BindTexture(p)
#define IWineD3DBaseTexture_UnBindTexture(p) (p)->lpVtbl->UnBindTexture(p)
#define IWineD3DBaseTexture_GetTextureDimensions(p) (p)->lpVtbl->GetTextureDimensions(p)
#define IWineD3DBaseTexture_ApplyStateChanges(p,a,b) (p)->lpVtbl->ApplyStateChanges(p,a,b)
#endif
/*****************************************************************************
......@@ -757,6 +759,7 @@ DECLARE_INTERFACE_(IWineD3DTexture,IWineD3DBaseTexture)
STDMETHOD(BindTexture)(THIS) PURE;
STDMETHOD(UnBindTexture)(THIS) PURE;
STDMETHOD_(UINT, GetTextureDimensions)(THIS) PURE;
STDMETHOD_(void, ApplyStateChanges)(THIS_ const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) PURE;
/*** IWineD3DTexture methods ***/
STDMETHOD(GetLevelDesc)(THIS_ UINT Level, WINED3DSURFACE_DESC* pDesc) PURE;
STDMETHOD(GetSurfaceLevel)(THIS_ UINT Level, struct IWineD3DSurface** ppSurfaceLevel) PURE;
......@@ -793,6 +796,7 @@ DECLARE_INTERFACE_(IWineD3DTexture,IWineD3DBaseTexture)
#define IWineD3DTexture_BindTexture(p) (p)->lpVtbl->BindTexture(p)
#define IWineD3DTexture_UnBindTexture(p) (p)->lpVtbl->UnBindTexture(p)
#define IWineD3DTexture_GetTextureDimensions(p) (p)->lpVtbl->GetTextureDimensions(p)
#define IWineD3DTexture_ApplyStateChanges(p,a,b) (p)->lpVtbl->ApplyStateChanges(p,a,b)
/*** IWineD3DTexture methods ***/
#define IWineD3DTexture_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b)
#define IWineD3DTexture_GetSurfaceLevel(p,a,b) (p)->lpVtbl->GetSurfaceLevel(p,a,b)
......@@ -833,6 +837,7 @@ DECLARE_INTERFACE_(IWineD3DCubeTexture,IWineD3DBaseTexture)
STDMETHOD(BindTexture)(THIS) PURE;
STDMETHOD(UnBindTexture)(THIS) PURE;
STDMETHOD_(UINT, GetTextureDimensions)(THIS) PURE;
STDMETHOD_(void, ApplyStateChanges)(THIS_ DWORD const textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) PURE;
/*** IWineD3DCubeTexture methods ***/
STDMETHOD(GetLevelDesc)(THIS_ UINT Level,WINED3DSURFACE_DESC* pDesc) PURE;
STDMETHOD(GetCubeMapSurface)(THIS_ D3DCUBEMAP_FACES FaceType, UINT Level, struct IWineD3DSurface** ppCubeMapSurface) PURE;
......@@ -869,6 +874,7 @@ DECLARE_INTERFACE_(IWineD3DCubeTexture,IWineD3DBaseTexture)
#define IWineD3DCubeTexture_BindTexture(p) (p)->lpVtbl->BindTexture(p)
#define IWineD3DCubeTexture_UnBindTexture(p) (p)->lpVtbl->UnBindTexture(p)
#define IWineD3DCubeTexture_GetTextureDimensions(p) (p)->lpVtbl->GetTextureDimensions(p)
#define IWineD3DCubeTexture_ApplyStateChanges(p,a,b) (p)->lpVtbl->ApplyStateChanges(p,a,b)
/*** IWineD3DCubeTexture methods ***/
#define IWineD3DCubeTexture_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b)
#define IWineD3DCubeTexture_GetCubeMapSurface(p,a,b,c) (p)->lpVtbl->GetCubeMapSurface(p,a,b,c)
......@@ -910,6 +916,7 @@ DECLARE_INTERFACE_(IWineD3DVolumeTexture,IWineD3DBaseTexture)
STDMETHOD(BindTexture)(THIS) PURE;
STDMETHOD(UnBindTexture)(THIS) PURE;
STDMETHOD_(UINT, GetTextureDimensions)(THIS) PURE;
STDMETHOD_(void, ApplyStateChanges)(THIS_ const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) PURE;
/*** IWineD3DVolumeTexture methods ***/
STDMETHOD(GetLevelDesc)(THIS_ UINT Level, WINED3DVOLUME_DESC *pDesc) PURE;
STDMETHOD(GetVolumeLevel)(THIS_ UINT Level, struct IWineD3DVolume** ppVolumeLevel) PURE;
......@@ -946,6 +953,7 @@ DECLARE_INTERFACE_(IWineD3DVolumeTexture,IWineD3DBaseTexture)
#define IWineD3DVolumeTexture_BindTexture(p) (p)->lpVtbl->BindTexture(p)
#define IWineD3DVolumeTexture_UnBindTexture(p) (p)->lpVtbl->UnBindTexture(p)
#define IWineD3DVolumeTexture_GetTextureDimensions(p) (p)->lpVtbl->GetTextureDimensions(p)
#define IWineD3DVolumeTexture_ApplyStateChanges(p,a,b) (p)->lpVtbl->ApplyStateChanges(p,a,b)
/*** IWineD3DVolumeTexture methods ***/
#define IWineD3DVolumeTexture_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b)
#define IWineD3DVolumeTexture_GetVolumeLevel(p,a,b) (p)->lpVtbl->GetVolumeLevel(p,a,b)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment