[PATCH] WineD3D: Make the shader backend call CompileShader=0A=

Stefan Doesinger stefan at codeweavers.com
Mon Nov 24 11:52:12 CST 2008


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

------=_NextPart_000_0002_01C94E6D.BE5D30F0--




More information about the wine-patches mailing list