diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 12148e6f509..5c6e29f806f 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -1876,6 +1876,7 @@ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) { if (useVS) { TRACE("Using vertex shader\n"); + IWineD3DVertexShaderImpl_CompileShader(This->stateBlock->vertexShader); priv->current_vprogram_id = ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.prgId; @@ -1895,6 +1896,7 @@ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) { if (usePS) { TRACE("Using pixel shader\n"); + pixelshader_compile(This->stateBlock->pixelShader); priv->current_fprogram_id = ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.prgId; @@ -3065,9 +3067,7 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, unsigned int i; if(isStateDirty(context, STATE_RENDER(WINED3DRS_FOGENABLE))) { - if(use_pshader) { - IWineD3DPixelShader_CompileShader(stateblock->pixelShader); - } else if(device->shader_backend == &arb_program_shader_backend && context->last_was_pshader) { + if(!use_pshader && device->shader_backend == &arb_program_shader_backend && context->last_was_pshader) { /* Reload fixed function constants since they collide with the pixel shader constants */ for(i = 0; i < MAX_TEXTURES; i++) { set_bumpmat_arbfp(STATE_TEXTURESTAGE(i, WINED3DTSS_BUMPENVMAT00), stateblock, context); @@ -3078,9 +3078,7 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, return; } - if(use_pshader) { - IWineD3DPixelShader_CompileShader(stateblock->pixelShader); - } else { + if(!use_pshader) { /* Find or create a shader implementing the fixed function pipeline settings, then activate it */ gen_ffp_frag_op(stateblock, &settings, FALSE); desc = (struct arbfp_ffp_desc *) find_ffp_frag_shader(priv->fragment_shaders, &settings); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index be0bdb2217f..aa9fa35b35c 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3854,7 +3854,7 @@ static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) { IWineD3DPixelShaderImpl *pshader = (IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader; /* Make sure the shader's reg_maps are up to date. This is only relevant for 1.x pixelshaders. */ - IWineD3DPixelShader_CompileShader((IWineD3DPixelShader *)pshader); + IWineD3DPixelShader_UpdateSamplers((IWineD3DPixelShader *)pshader); pshader_sampler_tokens = pshader->baseShader.reg_maps.samplers; } diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index bb9a8717cdc..d850ba8139a 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -3225,9 +3225,20 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use GLhandleARB reorder_shader_id = 0; int i; char glsl_name[8]; + GLhandleARB vshader_id, pshader_id; - GLhandleARB vshader_id = use_vs ? ((IWineD3DBaseShaderImpl*)vshader)->baseShader.prgId : 0; - GLhandleARB pshader_id = use_ps ? ((IWineD3DBaseShaderImpl*)pshader)->baseShader.prgId : 0; + if(use_vs) { + IWineD3DVertexShaderImpl_CompileShader(vshader); + vshader_id = ((IWineD3DBaseShaderImpl*)vshader)->baseShader.prgId; + } else { + vshader_id = 0; + } + if(use_ps) { + pixelshader_compile(pshader); + pshader_id = ((IWineD3DBaseShaderImpl*)pshader)->baseShader.prgId; + } else { + pshader_id = 0; + } entry = get_glsl_program_entry(priv, vshader_id, pshader_id); if (entry) { priv->glsl_program = entry; diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index 246b58addf0..cb5d2273f1d 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -384,13 +384,14 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i return WINED3D_OK; } -static HRESULT WINAPI IWineD3DPixelShaderImpl_CompileShader(IWineD3DPixelShader *iface) { +HRESULT pixelshader_compile(IWineD3DPixelShader *iface) { IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface; IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; CONST DWORD *function = This->baseShader.function; UINT i, sampler; IWineD3DBaseTextureImpl *texture; + HRESULT hr; TRACE("(%p) : function %p\n", iface, function); @@ -465,17 +466,8 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_CompileShader(IWineD3DPixelShader return WINED3D_OK; } - if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1) { - shader_reg_maps *reg_maps = &This->baseShader.reg_maps; - HRESULT hr; - - /* Second pass: figure out which registers are used, what the semantics are, etc.. */ - memset(reg_maps, 0, sizeof(shader_reg_maps)); - hr = shader_get_registers_used((IWineD3DBaseShader*)This, reg_maps, - This->semantics_in, NULL, This->baseShader.function, deviceImpl->stateBlock); - if (FAILED(hr)) return hr; - /* FIXME: validate reg_maps against OpenGL */ - } + hr = IWineD3DPixelShader_UpdateSamplers(iface); + if(FAILED(hr)) return hr; /* Reset fields tracking stateblock values being hardcoded in the shader */ This->baseShader.num_sampled_samplers = 0; @@ -489,6 +481,25 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_CompileShader(IWineD3DPixelShader return WINED3D_OK; } +static HRESULT WINAPI IWineD3DPixelShaderImpl_UpdateSamplers(IWineD3DPixelShader *iface) { + IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface; + + if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1) { + IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; + shader_reg_maps *reg_maps = &This->baseShader.reg_maps; + HRESULT hr; + + /* Second pass: figure out which registers are used, what the semantics are, etc.. */ + memset(reg_maps, 0, sizeof(shader_reg_maps)); + hr = shader_get_registers_used((IWineD3DBaseShader*)This, reg_maps, + This->semantics_in, NULL, This->baseShader.function, deviceImpl->stateBlock); + return hr; + /* FIXME: validate reg_maps against OpenGL */ + } else { + return WINED3D_OK; + } +} + const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl = { /*** IUnknown methods ***/ @@ -499,8 +510,8 @@ const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl = IWineD3DPixelShaderImpl_GetParent, /*** IWineD3DBaseShader methods ***/ IWineD3DPixelShaderImpl_SetFunction, - IWineD3DPixelShaderImpl_CompileShader, /*** IWineD3DPixelShader methods ***/ + IWineD3DPixelShaderImpl_UpdateSamplers, IWineD3DPixelShaderImpl_GetDevice, IWineD3DPixelShaderImpl_GetFunction }; diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index b9d28d4720c..f3cdb881e42 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3518,9 +3518,6 @@ void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DC * if a different texture was bound. I don't have to do anything. */ } - - /* Compile and bind the shader */ - IWineD3DPixelShader_CompileShader(stateblock->pixelShader); } else { /* Disabled the pixel shader - color ops weren't applied * while it was enabled, so re-apply them. @@ -4511,11 +4508,6 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context); } } else { - /* We compile the shader here because we need the vertex declaration - * in order to determine if we need to do any swizzling for D3DCOLOR - * registers. If the shader is already compiled this call will do nothing. */ - IWineD3DVertexShader_CompileShader(stateblock->vertexShader); - if(!context->last_was_vshader) { int i; static BOOL warned = FALSE; diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index 05c6d6dec77..10986614e54 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -563,7 +563,7 @@ static inline BOOL swizzled_attribs_differ(IWineD3DVertexShaderImpl *This, IWine return FALSE; } -static HRESULT WINAPI IWineD3DVertexShaderImpl_CompileShader(IWineD3DVertexShader *iface) { +HRESULT IWineD3DVertexShaderImpl_CompileShader(IWineD3DVertexShader *iface) { IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface; IWineD3DVertexDeclarationImpl *vdecl; CONST DWORD *function = This->baseShader.function; @@ -626,7 +626,6 @@ const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl = IWineD3DVertexShaderImpl_GetParent, /*** IWineD3DBaseShader methods ***/ IWineD3DVertexShaderImpl_SetFunction, - IWineD3DVertexShaderImpl_CompileShader, /*** IWineD3DVertexShader methods ***/ IWineD3DVertexShaderImpl_GetDevice, IWineD3DVertexShaderImpl_GetFunction, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index e3d35f248b0..015d7c08e41 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2320,6 +2320,7 @@ typedef struct IWineD3DVertexShaderImpl { } IWineD3DVertexShaderImpl; extern const SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[]; extern const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl; +HRESULT IWineD3DVertexShaderImpl_CompileShader(IWineD3DVertexShader *iface); /***************************************************************************** * IDirect3DPixelShader implementation structure @@ -2368,6 +2369,7 @@ typedef struct IWineD3DPixelShaderImpl { extern const SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[]; extern const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl; +HRESULT pixelshader_compile(IWineD3DPixelShader *iface); /* sRGB correction constants */ static const float srgb_cmp = 0.0031308; diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h index 27797c670f9..6d5f7e57912 100644 --- a/include/wine/wined3d_interface.h +++ b/include/wine/wined3d_interface.h @@ -1458,7 +1458,6 @@ DECLARE_INTERFACE_(IWineD3DBaseShader,IWineD3DBase) STDMETHOD(GetParent)(THIS_ IUnknown **pParent) PURE; /*** IWineD3DBaseShader methods ***/ STDMETHOD(SetFunction)(THIS_ CONST DWORD *pFunction) PURE; - STDMETHOD(CompileShader)(THIS) PURE; }; #undef INTERFACE @@ -1471,7 +1470,6 @@ DECLARE_INTERFACE_(IWineD3DBaseShader,IWineD3DBase) #define IWineD3DBaseShader_GetParent(p,a) (p)->lpVtbl->GetParent(p,a) /*** IWineD3DBaseShader methods ***/ #define IWineD3DBaseShader_SetFunction(p,a) (p)->lpVtbl->SetFunction(p,a) -#define IWineD3DBaseShader_CompileShader(p) (p)->lpVtbl->CompileShader(p) #endif /***************************************************************************** @@ -1488,7 +1486,6 @@ DECLARE_INTERFACE_(IWineD3DVertexShader,IWineD3DBaseShader) STDMETHOD(GetParent)(THIS_ IUnknown **pParent) PURE; /*** IWineD3DBaseShader methods ***/ STDMETHOD(SetFunction)(THIS_ CONST DWORD *pFunction) PURE; - STDMETHOD(CompileShader)(THIS) PURE; /*** IWineD3DVertexShader methods ***/ STDMETHOD(GetDevice)(THIS_ IWineD3DDevice** ppDevice) PURE; STDMETHOD(GetFunction)(THIS_ VOID *pData, UINT *pSizeOfData) PURE; @@ -1506,7 +1503,6 @@ DECLARE_INTERFACE_(IWineD3DVertexShader,IWineD3DBaseShader) #define IWineD3DVertexShader_GetParent(p,a) (p)->lpVtbl->GetParent(p,a) /*** IWineD3DBaseShader methods ***/ #define IWineD3DVertexShader_SetFunction(p,a) (p)->lpVtbl->SetFunction(p,a) -#define IWineD3DVertexShader_CompileShader(p) (p)->lpVtbl->CompileShader(p) /*** IWineD3DVertexShader methods ***/ #define IWineD3DVertexShader_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) #define IWineD3DVertexShader_GetFunction(p,a,b) (p)->lpVtbl->GetFunction(p,a,b) @@ -1528,8 +1524,8 @@ DECLARE_INTERFACE_(IWineD3DPixelShader,IWineD3DBaseShader) STDMETHOD(GetParent)(THIS_ IUnknown **pParent) PURE; /*** IWineD3DBaseShader methods ***/ STDMETHOD(SetFunction)(THIS_ CONST DWORD *pFunction) PURE; - STDMETHOD(CompileShader)(THIS) PURE; /*** IWineD3DPixelShader methods ***/ + STDMETHOD(UpdateSamplers)(THIS) PURE; STDMETHOD(GetDevice)(THIS_ IWineD3DDevice** ppDevice) PURE; STDMETHOD(GetFunction)(THIS_ VOID* pData, UINT* pSizeOfData) PURE; }; @@ -1544,8 +1540,8 @@ DECLARE_INTERFACE_(IWineD3DPixelShader,IWineD3DBaseShader) #define IWineD3DPixelShader_GetParent(p,a) (p)->lpVtbl->GetParent(p,a) /*** IWineD3DBaseShader methods ***/ #define IWineD3DPixelShader_SetFunction(p,a) (p)->lpVtbl->SetFunction(p,a) -#define IWineD3DPixelShader_CompileShader(p) (p)->lpVtbl->CompileShader(p) /*** IWineD3DPixelShader methods ***/ +#define IWineD3DPixelShader_UpdateSamplers(p) (p)->lpVtbl->UpdateSamplers(p) #define IWineD3DPixelShader_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) #define IWineD3DPixelShader_GetFunction(p,a,b) (p)->lpVtbl->GetFunction(p,a,b) #endif