forked from Mirrors/wine-wine
Only reapply the texture states necessary when a different texture
gets bound to the same texture unit.oldstable
parent
50fbe7330e
commit
d8b2109e61
|
@ -73,6 +73,10 @@ extern int num_lock;
|
||||||
#define HIGHEST_TRANSFORMSTATE 512
|
#define HIGHEST_TRANSFORMSTATE 512
|
||||||
#define D3DSBT_RECORDED 0xfffffffe
|
#define D3DSBT_RECORDED 0xfffffffe
|
||||||
|
|
||||||
|
/* Performance changes - Only reapply what is necessary */
|
||||||
|
#define REAPPLY_ALPHAOP 0x0001
|
||||||
|
#define REAPPLY_ALL 0xFFFF
|
||||||
|
|
||||||
/* CreateVertexShader can return > 0xFFFF */
|
/* CreateVertexShader can return > 0xFFFF */
|
||||||
#define VS_HIGHESTFIXEDFXF 0xF0000000
|
#define VS_HIGHESTFIXEDFXF 0xF0000000
|
||||||
#define VERTEX_SHADER(Handle) \
|
#define VERTEX_SHADER(Handle) \
|
||||||
|
@ -1239,7 +1243,7 @@ extern HRESULT WINAPI IDirect3DDeviceImpl_CreatePixelShader(IDirect3DDevice8Impl
|
||||||
* to see how not defined it here
|
* to see how not defined it here
|
||||||
*/
|
*/
|
||||||
void GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand);
|
void GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand);
|
||||||
void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage);
|
void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage, DWORD Flags);
|
||||||
void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3);
|
void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3);
|
||||||
|
|
||||||
SHORT D3DFmtGetBpp(IDirect3DDevice8Impl* This, D3DFORMAT fmt);
|
SHORT D3DFmtGetBpp(IDirect3DDevice8Impl* This, D3DFORMAT fmt);
|
||||||
|
|
|
@ -66,37 +66,69 @@ do {
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* Apply the current values to the specified texture stage */
|
/* Apply the current values to the specified texture stage */
|
||||||
void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
|
void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage, DWORD Flags) {
|
||||||
ICOM_THIS(IDirect3DDevice8Impl,iface);
|
ICOM_THIS(IDirect3DDevice8Impl,iface);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
float col[4];
|
float col[4];
|
||||||
|
BOOL changeTexture = TRUE;
|
||||||
/* Make appropriate texture active */
|
|
||||||
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
|
|
||||||
#if defined(GL_VERSION_1_3)
|
|
||||||
glActiveTexture(GL_TEXTURE0 + Stage);
|
|
||||||
#else
|
|
||||||
glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
|
|
||||||
#endif
|
|
||||||
checkGLcall("glActiveTextureARB");
|
|
||||||
} else if (Stage > 0) {
|
|
||||||
FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
|
TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
|
||||||
for (i = 1; i < HIGHEST_TEXTURE_STATE; i++) {
|
for (i = 1; i < HIGHEST_TEXTURE_STATE; i++) {
|
||||||
|
|
||||||
|
BOOL skip = FALSE;
|
||||||
|
|
||||||
|
switch (i) {
|
||||||
/* Performance: For texture states where multiples effect the outcome, only bother
|
/* Performance: For texture states where multiples effect the outcome, only bother
|
||||||
applying the last one as it will pick up all the other values */
|
applying the last one as it will pick up all the other values */
|
||||||
switch (i) {
|
|
||||||
case D3DTSS_COLORARG0: /* Will be picked up when setting color op */
|
case D3DTSS_COLORARG0: /* Will be picked up when setting color op */
|
||||||
case D3DTSS_COLORARG1: /* Will be picked up when setting color op */
|
case D3DTSS_COLORARG1: /* Will be picked up when setting color op */
|
||||||
case D3DTSS_COLORARG2: /* Will be picked up when setting color op */
|
case D3DTSS_COLORARG2: /* Will be picked up when setting color op */
|
||||||
case D3DTSS_ALPHAARG0: /* Will be picked up when setting alpha op */
|
case D3DTSS_ALPHAARG0: /* Will be picked up when setting alpha op */
|
||||||
case D3DTSS_ALPHAARG1: /* Will be picked up when setting alpha op */
|
case D3DTSS_ALPHAARG1: /* Will be picked up when setting alpha op */
|
||||||
case D3DTSS_ALPHAARG2: /* Will be picked up when setting alpha op */
|
case D3DTSS_ALPHAARG2: /* Will be picked up when setting alpha op */
|
||||||
|
skip = TRUE;
|
||||||
break;
|
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 D3DTSS_COLOROP:
|
||||||
|
case D3DTSS_TEXCOORDINDEX:
|
||||||
|
if (!(Flags == REAPPLY_ALL)) skip=TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D3DTSS_ALPHAOP:
|
||||||
|
if (!(Flags & REAPPLY_ALPHAOP)) skip=TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
skip = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skip == FALSE) {
|
||||||
|
/* Performance: Only change to this texture if we have to */
|
||||||
|
if (changeTexture) {
|
||||||
|
/* Make appropriate texture active */
|
||||||
|
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
|
||||||
|
#if defined(GL_VERSION_1_3)
|
||||||
|
glActiveTexture(GL_TEXTURE0 + Stage);
|
||||||
|
#else
|
||||||
|
glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
|
||||||
|
#endif
|
||||||
|
checkGLcall("glActiveTextureARB");
|
||||||
|
} else if (Stage > 0) {
|
||||||
|
FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
|
||||||
|
}
|
||||||
|
changeTexture = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now apply the change */
|
||||||
IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock->texture_state[Stage][i]);
|
IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock->texture_state[Stage][i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2671,6 +2703,8 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD
|
||||||
|
|
||||||
IDirect3DBaseTexture8 *oldTxt;
|
IDirect3DBaseTexture8 *oldTxt;
|
||||||
BOOL reapplyStates = TRUE;
|
BOOL reapplyStates = TRUE;
|
||||||
|
DWORD oldTextureDimensions = -1;
|
||||||
|
DWORD reapplyFlags = 0;
|
||||||
|
|
||||||
ICOM_THIS(IDirect3DDevice8Impl,iface);
|
ICOM_THIS(IDirect3DDevice8Impl,iface);
|
||||||
D3DRESOURCETYPE textureType;
|
D3DRESOURCETYPE textureType;
|
||||||
|
@ -2694,6 +2728,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oldTextureDimensions = This->UpdateStateBlock->textureDimensions[Stage];
|
||||||
ENTER_GL();
|
ENTER_GL();
|
||||||
|
|
||||||
/* Make appropriate texture active */
|
/* Make appropriate texture active */
|
||||||
|
@ -2766,10 +2801,30 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD
|
||||||
TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
|
TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Disable the old texture binding and enable the new one (unless operations are disabled) */
|
||||||
|
if (oldTextureDimensions != This->UpdateStateBlock->textureDimensions[Stage]) {
|
||||||
|
glDisable(oldTextureDimensions);
|
||||||
|
checkGLcall("Disable oldTextureDimensions");
|
||||||
|
if (This->StateBlock->texture_state[Stage][D3DTSS_COLOROP] != D3DTOP_DISABLE) {
|
||||||
|
glEnable(This->UpdateStateBlock->textureDimensions[Stage]);
|
||||||
|
checkGLcall("Disable new texture dimensions");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If Alpha arg1 is texture then handle the special case when there changes between a
|
||||||
|
texture and no texture - See comments in set_tex_op */
|
||||||
|
if ((This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG1] == D3DTA_TEXTURE) &&
|
||||||
|
((oldTxt == NULL) && (pTexture != NULL)) ||
|
||||||
|
((pTexture == NULL) && (oldTxt != NULL)))
|
||||||
|
{
|
||||||
|
reapplyFlags |= REAPPLY_ALPHAOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
|
/* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
|
||||||
a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
|
a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
|
||||||
if (reapplyStates) {
|
if (reapplyStates) {
|
||||||
setupTextureStates(iface, Stage);
|
setupTextureStates(iface, Stage, reapplyFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
LEAVE_GL();
|
LEAVE_GL();
|
||||||
|
|
|
@ -234,7 +234,7 @@ HRESULT WINAPI IDirect3DDeviceImpl_InitStartupStateBlock(IDirect3DDevice8Impl* T
|
||||||
checkGLcall("glTexImage1D");
|
checkGLcall("glTexImage1D");
|
||||||
|
|
||||||
/* Reapply all the texture state information to this texture */
|
/* Reapply all the texture state information to this texture */
|
||||||
setupTextureStates(iface, i);
|
setupTextureStates(iface, i, REAPPLY_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
LEAVE_GL();
|
LEAVE_GL();
|
||||||
|
|
Loading…
Reference in New Issue