diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 2a55feb61be..d091b58a5ba 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2064,7 +2064,6 @@ static void create_dummy_textures(IWineD3DDeviceImpl *This) { /* Generate a dummy 2d texture (not using 1d because they cause many * DRI drivers fall back to sw) */ - This->stateBlock->textureDimensions[i] = GL_TEXTURE_2D; glBindTexture(GL_TEXTURE_2D, This->dummyTextureName[i]); checkGLcall("glBindTexture"); @@ -4673,14 +4672,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTexture(IWineD3DDevice *iface, DWORD oldTexture = This->updateStateBlock->textures[Stage]; - if(pTexture != NULL) { - /* SetTexture isn't allowed on textures in WINED3DPOOL_SCRATCH; - */ - if(((IWineD3DTextureImpl*)pTexture)->resource.pool == WINED3DPOOL_SCRATCH) { - WARN("(%p) Attempt to set scratch texture rejected\n", pTexture); - return WINED3DERR_INVALIDCALL; - } - This->stateBlock->textureDimensions[Stage] = IWineD3DBaseTexture_GetTextureDimensions(pTexture); + /* SetTexture isn't allowed on textures in WINED3DPOOL_SCRATCH */ + if (pTexture && ((IWineD3DTextureImpl*)pTexture)->resource.pool == WINED3DPOOL_SCRATCH) + { + WARN("(%p) Attempt to set scratch texture rejected\n", pTexture); + return WINED3DERR_INVALIDCALL; } TRACE("GL_LIMITS %d\n",GL_LIMITS(sampler_stages)); diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c index 77f53655211..1b31c746f88 100644 --- a/dlls/wined3d/nvidia_texture_shader.c +++ b/dlls/wined3d/nvidia_texture_shader.c @@ -41,7 +41,7 @@ static void nvts_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateb } if(stateblock->textures[stage]) { - switch(stateblock->textureDimensions[stage]) { + switch(IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) { case GL_TEXTURE_2D: glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_2D); checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)"); diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 66424837708..f76ccacb132 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -470,27 +470,29 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D float ref; BOOL enable_ckey = FALSE; - IWineD3DSurfaceImpl *surf; - /* Find out if the texture on the first stage has a ckey set * The alpha state func reads the texture settings, even though alpha and texture are not grouped * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly * used WINED3DRS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha * in case it finds some texture+colorkeyenable combination which needs extra care. */ - if(stateblock->textures[0] && ( - stateblock->textureDimensions[0] == GL_TEXTURE_2D || - stateblock->textureDimensions[0] == GL_TEXTURE_RECTANGLE_ARB)) { - surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0]; + if (stateblock->textures[0]) + { + UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]); - if(surf->CKeyFlags & WINEDDSD_CKSRCBLT) { - const StaticPixelFormatDesc *fmt = getFormatDescEntry(surf->resource.format, NULL, NULL); - /* The surface conversion does not do color keying conversion for surfaces that have an alpha - * channel on their own. Likewise, the alpha test shouldn't be set up for color keying if the - * surface has alpha bits - */ - if(fmt->alphaMask == 0x00000000) { - enable_ckey = TRUE; + if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) + { + IWineD3DSurfaceImpl *surf; + + surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0]; + + if (surf->CKeyFlags & WINEDDSD_CKSRCBLT) + { + const StaticPixelFormatDesc *fmt = getFormatDescEntry(surf->resource.format, NULL, NULL); + /* The surface conversion does not do color keying conversion for surfaces that have an alpha + * channel on their own. Likewise, the alpha test shouldn't be set up for color keying if the + * surface has alpha bits */ + if (fmt->alphaMask == 0x00000000) enable_ckey = TRUE; } } } @@ -2999,50 +3001,64 @@ void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext arg2 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG2]; arg0 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG0]; - if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && stage == 0 && - stateblock->textures[0] && - (stateblock->textureDimensions[0] == GL_TEXTURE_2D || stateblock->textureDimensions[0] == GL_TEXTURE_RECTANGLE_ARB)) { - IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0]; + if (stateblock->renderState[WINED3DRS_COLORKEYENABLE] && stage == 0 && stateblock->textures[0]) + { + UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]); - if(surf->CKeyFlags & WINEDDSD_CKSRCBLT && - getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000) { + if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) + { + IWineD3DSurfaceImpl *surf; - /* Color keying needs to pass alpha values from the texture through to have the alpha test work properly. - * On the other hand applications can still use texture combiners apparently. This code takes care that apps - * cannot remove the texture's alpha channel entirely. - * - * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires D3DTOP_MODULATE to work - * on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures and alpha component of diffuse color to - * draw things like translucent text and perform other blending effects. - * - * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To provide the - * behavior expected by the game, while emulating the colorkey, diffuse alpha must be modulated with texture alpha. - * OTOH, Moto racer 2 at some points sets alphaop/alphaarg to SELECTARG/CURRENT, yet puts garbage in diffuse alpha - * (zeroes). This works on native, because the game disables alpha test and alpha blending. Alpha test is overwritten by - * wine's for purposes of color-keying though, so this will lead to missing geometry if texture alpha is modulated - * (pixels fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha blending, - * it can be expected to provide meaningful values in diffuse alpha, so it should be modulated with texture alpha; - * otherwise, selecting diffuse alpha is ignored in favour of texture alpha. + surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0]; - * What to do with multitexturing? So far no app has been found that uses color keying with multitexturing - */ - if(op == WINED3DTOP_DISABLE) { - arg1 = WINED3DTA_TEXTURE; - op = WINED3DTOP_SELECTARG1; - } - else if(op == WINED3DTOP_SELECTARG1 && arg1 != WINED3DTA_TEXTURE) { - if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) { - arg2 = WINED3DTA_TEXTURE; - op = WINED3DTOP_MODULATE; - } - else arg1 = WINED3DTA_TEXTURE; - } - else if(op == WINED3DTOP_SELECTARG2 && arg2 != WINED3DTA_TEXTURE) { - if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) { + if (surf->CKeyFlags & WINEDDSD_CKSRCBLT + && getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000) + { + /* Color keying needs to pass alpha values from the texture through to have the alpha test work + * properly. On the other hand applications can still use texture combiners apparently. This code + * takes care that apps cannot remove the texture's alpha channel entirely. + * + * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires + * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures + * and alpha component of diffuse color to draw things like translucent text and perform other + * blending effects. + * + * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To + * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be + * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to + * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the + * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of + * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels + * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha + * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be + * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture + * alpha. + * + * What to do with multitexturing? So far no app has been found that uses color keying with + * multitexturing */ + if (op == WINED3DTOP_DISABLE) + { arg1 = WINED3DTA_TEXTURE; - op = WINED3DTOP_MODULATE; + op = WINED3DTOP_SELECTARG1; + } + else if(op == WINED3DTOP_SELECTARG1 && arg1 != WINED3DTA_TEXTURE) + { + if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) + { + arg2 = WINED3DTA_TEXTURE; + op = WINED3DTOP_MODULATE; + } + else arg1 = WINED3DTA_TEXTURE; + } + else if(op == WINED3DTOP_SELECTARG2 && arg2 != WINED3DTA_TEXTURE) + { + if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) + { + arg1 = WINED3DTA_TEXTURE; + op = WINED3DTOP_MODULATE; + } + else arg2 = WINED3DTA_TEXTURE; } - else arg2 = WINED3DTA_TEXTURE; } } } @@ -3388,13 +3404,17 @@ static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, W * misc pipeline */ if(sampler < MAX_TEXTURES) { - if(stateblock->textureDimensions[sampler] == GL_TEXTURE_2D || - stateblock->textureDimensions[sampler] == GL_TEXTURE_RECTANGLE_ARB) { + UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(texture); + + if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) + { if(((IWineD3DTextureImpl *)texture)->baseTexture.pow2Matrix[0] != 1.0 || ((IWineD3DTextureImpl *)texture)->baseTexture.pow2Matrix[5] != 1.0 ) { texIsPow2 = TRUE; } - } else if(stateblock->textureDimensions[sampler] == GL_TEXTURE_CUBE_MAP_ARB) { + } + else if (texture_dimensions == GL_TEXTURE_CUBE_MAP_ARB) + { if(((IWineD3DCubeTextureImpl *)texture)->baseTexture.pow2Matrix[0] != 1.0) { texIsPow2 = TRUE; } diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 3fe818357ff..1f35e82ba25 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -203,7 +203,6 @@ void stateblock_copy( memcpy(Dest->clipplane, This->clipplane, sizeof(double) * MAX_CLIPPLANES * 4); memcpy(Dest->renderState, This->renderState, sizeof(DWORD) * (WINEHIGHEST_RENDER_STATE + 1)); memcpy(Dest->textures, This->textures, sizeof(IWineD3DBaseTexture*) * MAX_COMBINED_SAMPLERS); - memcpy(Dest->textureDimensions, This->textureDimensions, sizeof(int) * MAX_COMBINED_SAMPLERS); memcpy(Dest->textureState, This->textureState, sizeof(DWORD) * MAX_TEXTURES * (WINED3D_HIGHEST_TEXTURE_STATE + 1)); memcpy(Dest->samplerState, This->samplerState, sizeof(DWORD) * MAX_COMBINED_SAMPLERS * (WINED3D_HIGHEST_SAMPLER_STATE + 1)); @@ -613,7 +612,6 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) memcpy(This->pixelShaderConstantF, targetStateBlock->pixelShaderConstantF, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4); memcpy(This->renderState, targetStateBlock->renderState, sizeof(This->renderState)); memcpy(This->textures, targetStateBlock->textures, sizeof(This->textures)); - memcpy(This->textureDimensions, targetStateBlock->textureDimensions, sizeof(This->textureDimensions)); memcpy(This->textureState, targetStateBlock->textureState, sizeof(This->textureState)); memcpy(This->samplerState, targetStateBlock->samplerState, sizeof(This->samplerState)); This->scissorRect = targetStateBlock->scissorRect; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 4e460139f54..7fc874beacd 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -1931,7 +1931,7 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting if(ignore_textype) { settings->op[i].tex_type = tex_1d; } else { - switch(stateblock->textureDimensions[i]) { + switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) { case GL_TEXTURE_1D: settings->op[i].tex_type = tex_1d; break; @@ -1983,32 +1983,41 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED; } - if(i == 0 && stateblock->textures[0] && - stateblock->renderState[WINED3DRS_COLORKEYENABLE] && - (stateblock->textureDimensions[0] == GL_TEXTURE_2D || - stateblock->textureDimensions[0] == GL_TEXTURE_RECTANGLE_ARB)) { - IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0]; + if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE]) + { + UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]); - if(surf->CKeyFlags & WINEDDSD_CKSRCBLT && - getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000) { + if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) + { + IWineD3DSurfaceImpl *surf; + surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0]; - if(aop == WINED3DTOP_DISABLE) { - aarg1 = WINED3DTA_TEXTURE; - aop = WINED3DTOP_SELECTARG1; - } - else if(aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE) { - if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) { - aarg2 = WINED3DTA_TEXTURE; - aop = WINED3DTOP_MODULATE; + if (surf->CKeyFlags & WINEDDSD_CKSRCBLT + && getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000) + { + if (aop == WINED3DTOP_DISABLE) + { + aarg1 = WINED3DTA_TEXTURE; + aop = WINED3DTOP_SELECTARG1; } - else aarg1 = WINED3DTA_TEXTURE; - } - else if(aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE) { - if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) { - aarg1 = WINED3DTA_TEXTURE; - aop = WINED3DTOP_MODULATE; + else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE) + { + if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) + { + aarg2 = WINED3DTA_TEXTURE; + aop = WINED3DTOP_MODULATE; + } + else aarg1 = WINED3DTA_TEXTURE; + } + else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE) + { + if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) + { + aarg1 = WINED3DTA_TEXTURE; + aop = WINED3DTOP_MODULATE; + } + else aarg2 = WINED3DTA_TEXTURE; } - else aarg2 = WINED3DTA_TEXTURE; } } } @@ -2115,7 +2124,7 @@ void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *des #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { if(stateblock->textures[stage]) { - switch(stateblock->textureDimensions[stage]) { + switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) { case GL_TEXTURE_2D: glDisable(GL_TEXTURE_3D); checkGLcall("glDisable(GL_TEXTURE_3D)"); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 60646c94d2d..e28bb6dc93e 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1835,7 +1835,6 @@ struct IWineD3DStateBlockImpl /* Texture */ IWineD3DBaseTexture *textures[MAX_COMBINED_SAMPLERS]; - int textureDimensions[MAX_COMBINED_SAMPLERS]; /* Texture State Stage */ DWORD textureState[MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];