[PATCH] WineD3D: Pass some stateblock values around directly=0A=

Stefan Doesinger stefan at codeweavers.com
Thu Nov 20 02:55:17 CST 2008


=0A=
This was suggested by Ivan quite a while ago, and we need it to=0A=
better handle conflicting texture format corrections and similar=0A=
stateblock value changes which until now required a recompilation=0A=
of the entire shader=0A=
=0A=
This only passes the structure to the CompileShader function,=0A=
which currently does the compatibility tests. More work is=0A=
needed, but this fixes the main problems.=0A=
=0A=
Later on this structure will be used as part of a key in a=0A=
hashmap, so I'll optimize the packing later on. For now this code=0A=
is less error-prone and works as well=0A=
---=0A=
 dlls/wined3d/arb_program_shader.c |    4 ++-=0A=
 dlls/wined3d/glsl_shader.c        |    4 ++-=0A=
 dlls/wined3d/pixelshader.c        |   53 =
++++++++++++++++++++++++------------=0A=
 dlls/wined3d/wined3d_private.h    |   12 +++++++-=0A=
 4 files changed, 52 insertions(+), 21 deletions(-)=0A=
=0A=
diff --git a/dlls/wined3d/arb_program_shader.c =
b/dlls/wined3d/arb_program_shader.c=0A=
index 5c6e29f..20e731b 100644=0A=
--- a/dlls/wined3d/arb_program_shader.c=0A=
+++ b/dlls/wined3d/arb_program_shader.c=0A=
@@ -1895,8 +1895,10 @@ static void shader_arb_select(IWineD3DDevice =
*iface, BOOL usePS, BOOL useVS) {=0A=
     }=0A=
 =0A=
     if (usePS) {=0A=
+        struct ps_compile_args compile_args;=0A=
         TRACE("Using pixel shader\n");=0A=
-        pixelshader_compile(This->stateBlock->pixelShader);=0A=
+        find_ps_compile_args((IWineD3DPixelShaderImpl *) =
This->stateBlock->pixelShader, This->stateBlock, &compile_args);=0A=
+        pixelshader_compile(This->stateBlock->pixelShader, =
&compile_args);=0A=
 =0A=
         priv->current_fprogram_id =3D ((IWineD3DPixelShaderImpl =
*)This->stateBlock->pixelShader)->baseShader.prgId;=0A=
 =0A=
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c=0A=
index d850ba8..92a6a36 100644=0A=
--- a/dlls/wined3d/glsl_shader.c=0A=
+++ b/dlls/wined3d/glsl_shader.c=0A=
@@ -3234,7 +3234,9 @@ static void set_glsl_shader_program(IWineD3DDevice =
*iface, BOOL use_ps, BOOL use=0A=
         vshader_id =3D 0;=0A=
     }=0A=
     if(use_ps) {=0A=
-        pixelshader_compile(pshader);=0A=
+        struct ps_compile_args compile_args;=0A=
+        =
find_ps_compile_args((IWineD3DPixelShaderImpl*)This->stateBlock->pixelSha=
der, This->stateBlock, &compile_args);=0A=
+        pixelshader_compile(pshader, &compile_args);=0A=
         pshader_id =3D =
((IWineD3DBaseShaderImpl*)pshader)->baseShader.prgId;=0A=
     } else {=0A=
         pshader_id =3D 0;=0A=
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c=0A=
index cb5d227..1ce2849 100644=0A=
--- a/dlls/wined3d/pixelshader.c=0A=
+++ b/dlls/wined3d/pixelshader.c=0A=
@@ -384,13 +384,12 @@ static HRESULT WINAPI =
IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i=0A=
     return WINED3D_OK;=0A=
 }=0A=
 =0A=
-HRESULT pixelshader_compile(IWineD3DPixelShader *iface) {=0A=
+HRESULT pixelshader_compile(IWineD3DPixelShader *iface, struct =
ps_compile_args *args) {=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=
@@ -399,15 +398,13 @@ HRESULT pixelshader_compile(IWineD3DPixelShader =
*iface) {=0A=
      * changed.=0A=
      */=0A=
     if (This->baseShader.is_compiled) {=0A=
-        char srgbenabled =3D =
deviceImpl->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE] ? 1 : 0;=0A=
         for(i =3D 0; i < This->baseShader.num_sampled_samplers; i++) {=0A=
             sampler =3D This->baseShader.sampled_samplers[i];=0A=
-            texture =3D (IWineD3DBaseTextureImpl *) =
deviceImpl->stateBlock->textures[sampler];=0A=
-            if(texture && texture->baseTexture.shader_conversion_group =
!=3D This->baseShader.sampled_format[sampler]) {=0A=
+            if(args->format_conversion[sampler] !=3D =
This->baseShader.sampled_format[sampler]) {=0A=
                 WARN("Recompiling shader %p due to format change on =
sampler %d\n", This, sampler);=0A=
                 WARN("Old format group %s, new is %s\n",=0A=
                      =
debug_d3dformat(This->baseShader.sampled_format[sampler]),=0A=
-                     =
debug_d3dformat(texture->baseTexture.shader_conversion_group));=0A=
+                     debug_d3dformat(args->format_conversion[sampler]));=0A=
                 goto recompile;=0A=
             }=0A=
         }=0A=
@@ -415,7 +412,7 @@ HRESULT pixelshader_compile(IWineD3DPixelShader =
*iface) {=0A=
         /* TODO: Check projected textures */=0A=
         /* TODO: Check texture types(2D, Cube, 3D) */=0A=
 =0A=
-        if(srgbenabled !=3D This->srgb_enabled && =
This->srgb_mode_hardcoded) {=0A=
+        if(args->srgb_correction !=3D This->srgb_enabled && =
This->srgb_mode_hardcoded) {=0A=
             WARN("Recompiling shader because srgb correction is =
different and hardcoded\n");=0A=
             goto recompile;=0A=
         }=0A=
@@ -433,17 +430,8 @@ HRESULT pixelshader_compile(IWineD3DPixelShader =
*iface) {=0A=
             }=0A=
         }=0A=
         if(This->baseShader.hex_version >=3D WINED3DPS_VERSION(3,0)) {=0A=
-            if(((IWineD3DDeviceImpl *) =
This->baseShader.device)->strided_streams.u.s.position_transformed) {=0A=
-                if(This->vertexprocessing !=3D pretransformed) {=0A=
-                    WARN("Recompiling shader because pretransformed =
vertices are provided, which wasn't the case before\n");=0A=
-                    goto recompile;=0A=
-                }=0A=
-            } else if(!use_vs((IWineD3DDeviceImpl *) =
This->baseShader.device) &&=0A=
-                       This->vertexprocessing !=3D fixedfunction) {=0A=
-                WARN("Recompiling shader because fixed function vp is =
in use, which wasn't the case before\n");=0A=
-                goto recompile;=0A=
-            } else if(This->vertexprocessing !=3D vertexshader) {=0A=
-                WARN("Recompiling shader because vertex shaders are in =
use, which wasn't the case before\n");=0A=
+            if(args->vp_mode !=3D This->vertexprocessing) {=0A=
+                WARN("Recompiling shader because the vertex processing =
mode changed\n");=0A=
                 goto recompile;=0A=
             }=0A=
         }=0A=
@@ -515,3 +503,32 @@ const IWineD3DPixelShaderVtbl =
IWineD3DPixelShader_Vtbl =3D=0A=
     IWineD3DPixelShaderImpl_GetDevice,=0A=
     IWineD3DPixelShaderImpl_GetFunction=0A=
 };=0A=
+=0A=
+void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, =
IWineD3DStateBlockImpl *stateblock, struct ps_compile_args *args) {=0A=
+    UINT i, sampler;=0A=
+    IWineD3DBaseTextureImpl *tex;=0A=
+=0A=
+    args->srgb_correction =3D =
stateblock->renderState[WINED3DRS_SRGBWRITEENABLE] ? 1 : 0;=0A=
+=0A=
+    memset(args->format_conversion, 0, sizeof(args->format_conversion));=0A=
+    for(i =3D 0; i < shader->baseShader.num_sampled_samplers; i++) {=0A=
+        sampler =3D shader->baseShader.sampled_samplers[i];=0A=
+        tex =3D (IWineD3DBaseTextureImpl *) =
stateblock->textures[sampler];=0A=
+        if(!tex) {=0A=
+            args->format_conversion[sampler] =3D WINED3DFMT_UNKNOWN;=0A=
+            continue;=0A=
+        }=0A=
+        args->format_conversion[sampler] =3D =
tex->baseTexture.shader_conversion_group;=0A=
+    }=0A=
+    if(shader->baseShader.hex_version >=3D WINED3DPS_VERSION(3,0)) {=0A=
+        if(((IWineD3DDeviceImpl *) =
shader->baseShader.device)->strided_streams.u.s.position_transformed) {=0A=
+            args->vp_mode =3D pretransformed;=0A=
+        } else if(use_vs((IWineD3DDeviceImpl *) =
shader->baseShader.device)) {=0A=
+            args->vp_mode =3D vertexshader;=0A=
+        } else {=0A=
+            args->vp_mode =3D fixedfunction;=0A=
+        }=0A=
+    } else {=0A=
+        args->vp_mode =3D vertexshader;=0A=
+    }=0A=
+}=0A=
diff --git a/dlls/wined3d/wined3d_private.h =
b/dlls/wined3d/wined3d_private.h=0A=
index 015d7c0..847d11d 100644=0A=
--- a/dlls/wined3d/wined3d_private.h=0A=
+++ b/dlls/wined3d/wined3d_private.h=0A=
@@ -2337,6 +2337,15 @@ struct stb_const_desc {=0A=
     UINT                    const_num;=0A=
 };=0A=
 =0A=
+/* Stateblock dependent parameters which have to be hardcoded=0A=
+ * into the shader code=0A=
+ */=0A=
+struct ps_compile_args {=0A=
+    BOOL                        srgb_correction;=0A=
+    WINED3DFORMAT               =
format_conversion[MAX_FRAGMENT_SAMPLERS];=0A=
+    enum vertexprocessing_mode  vp_mode;=0A=
+};=0A=
+=0A=
 typedef struct IWineD3DPixelShaderImpl {=0A=
     /* IUnknown parts */=0A=
     const IWineD3DPixelShaderVtbl *lpVtbl;=0A=
@@ -2369,7 +2378,8 @@ 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=
+HRESULT pixelshader_compile(IWineD3DPixelShader *iface, struct =
ps_compile_args *args);=0A=
+void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, =
IWineD3DStateBlockImpl *stateblock, struct ps_compile_args *args);=0A=
 =0A=
 /* sRGB correction constants */=0A=
 static const float srgb_cmp =3D 0.0031308;=0A=
-- =0A=
1.5.6.4=0A=
=0A=

------=_NextPart_000_0006_01C94E6D.D0329EF0--




More information about the wine-patches mailing list