Stefan Dösinger : wined3d: Pass some stateblock values around directly.

Alexandre Julliard julliard at winehq.org
Tue Nov 25 07:21:44 CST 2008


Module: wine
Branch: master
Commit: dd8905543ba0052adc7d26a0b14595aea5bad4f5
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=dd8905543ba0052adc7d26a0b14595aea5bad4f5

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Thu Nov 20 02:55:17 2008 +0100

wined3d: Pass some stateblock values around directly.

This was suggested by Ivan quite a while ago, and we need it to better
handle conflicting texture format corrections and similar stateblock
value changes which until now required a recompilation of the entire
shader

---

 dlls/wined3d/arb_program_shader.c |    4 ++-
 dlls/wined3d/glsl_shader.c        |    4 ++-
 dlls/wined3d/pixelshader.c        |   53 ++++++++++++++++++++++++------------
 dlls/wined3d/wined3d_private.h    |   12 +++++++-
 4 files changed, 52 insertions(+), 21 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 5c6e29f..20e731b 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -1895,8 +1895,10 @@ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
     }
 
     if (usePS) {
+        struct ps_compile_args compile_args;
         TRACE("Using pixel shader\n");
-        pixelshader_compile(This->stateBlock->pixelShader);
+        find_ps_compile_args((IWineD3DPixelShaderImpl *) This->stateBlock->pixelShader, This->stateBlock, &compile_args);
+        pixelshader_compile(This->stateBlock->pixelShader, &compile_args);
 
         priv->current_fprogram_id = ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.prgId;
 
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index d850ba8..92a6a36 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -3234,7 +3234,9 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
         vshader_id = 0;
     }
     if(use_ps) {
-        pixelshader_compile(pshader);
+        struct ps_compile_args compile_args;
+        find_ps_compile_args((IWineD3DPixelShaderImpl*)This->stateBlock->pixelShader, This->stateBlock, &compile_args);
+        pixelshader_compile(pshader, &compile_args);
         pshader_id = ((IWineD3DBaseShaderImpl*)pshader)->baseShader.prgId;
     } else {
         pshader_id = 0;
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index cb5d227..1ce2849 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -384,13 +384,12 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
     return WINED3D_OK;
 }
 
-HRESULT pixelshader_compile(IWineD3DPixelShader *iface) {
+HRESULT pixelshader_compile(IWineD3DPixelShader *iface, struct ps_compile_args *args) {
 
     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);
@@ -399,15 +398,13 @@ HRESULT pixelshader_compile(IWineD3DPixelShader *iface) {
      * changed.
      */
     if (This->baseShader.is_compiled) {
-        char srgbenabled = deviceImpl->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE] ? 1 : 0;
         for(i = 0; i < This->baseShader.num_sampled_samplers; i++) {
             sampler = This->baseShader.sampled_samplers[i];
-            texture = (IWineD3DBaseTextureImpl *) deviceImpl->stateBlock->textures[sampler];
-            if(texture && texture->baseTexture.shader_conversion_group != This->baseShader.sampled_format[sampler]) {
+            if(args->format_conversion[sampler] != This->baseShader.sampled_format[sampler]) {
                 WARN("Recompiling shader %p due to format change on sampler %d\n", This, sampler);
                 WARN("Old format group %s, new is %s\n",
                      debug_d3dformat(This->baseShader.sampled_format[sampler]),
-                     debug_d3dformat(texture->baseTexture.shader_conversion_group));
+                     debug_d3dformat(args->format_conversion[sampler]));
                 goto recompile;
             }
         }
@@ -415,7 +412,7 @@ HRESULT pixelshader_compile(IWineD3DPixelShader *iface) {
         /* TODO: Check projected textures */
         /* TODO: Check texture types(2D, Cube, 3D) */
 
-        if(srgbenabled != This->srgb_enabled && This->srgb_mode_hardcoded) {
+        if(args->srgb_correction != This->srgb_enabled && This->srgb_mode_hardcoded) {
             WARN("Recompiling shader because srgb correction is different and hardcoded\n");
             goto recompile;
         }
@@ -433,17 +430,8 @@ HRESULT pixelshader_compile(IWineD3DPixelShader *iface) {
             }
         }
         if(This->baseShader.hex_version >= WINED3DPS_VERSION(3,0)) {
-            if(((IWineD3DDeviceImpl *) This->baseShader.device)->strided_streams.u.s.position_transformed) {
-                if(This->vertexprocessing != pretransformed) {
-                    WARN("Recompiling shader because pretransformed vertices are provided, which wasn't the case before\n");
-                    goto recompile;
-                }
-            } else if(!use_vs((IWineD3DDeviceImpl *) This->baseShader.device) &&
-                       This->vertexprocessing != fixedfunction) {
-                WARN("Recompiling shader because fixed function vp is in use, which wasn't the case before\n");
-                goto recompile;
-            } else if(This->vertexprocessing != vertexshader) {
-                WARN("Recompiling shader because vertex shaders are in use, which wasn't the case before\n");
+            if(args->vp_mode != This->vertexprocessing) {
+                WARN("Recompiling shader because the vertex processing mode changed\n");
                 goto recompile;
             }
         }
@@ -515,3 +503,32 @@ const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl =
     IWineD3DPixelShaderImpl_GetDevice,
     IWineD3DPixelShaderImpl_GetFunction
 };
+
+void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct ps_compile_args *args) {
+    UINT i, sampler;
+    IWineD3DBaseTextureImpl *tex;
+
+    args->srgb_correction = stateblock->renderState[WINED3DRS_SRGBWRITEENABLE] ? 1 : 0;
+
+    memset(args->format_conversion, 0, sizeof(args->format_conversion));
+    for(i = 0; i < shader->baseShader.num_sampled_samplers; i++) {
+        sampler = shader->baseShader.sampled_samplers[i];
+        tex = (IWineD3DBaseTextureImpl *) stateblock->textures[sampler];
+        if(!tex) {
+            args->format_conversion[sampler] = WINED3DFMT_UNKNOWN;
+            continue;
+        }
+        args->format_conversion[sampler] = tex->baseTexture.shader_conversion_group;
+    }
+    if(shader->baseShader.hex_version >= WINED3DPS_VERSION(3,0)) {
+        if(((IWineD3DDeviceImpl *) shader->baseShader.device)->strided_streams.u.s.position_transformed) {
+            args->vp_mode = pretransformed;
+        } else if(use_vs((IWineD3DDeviceImpl *) shader->baseShader.device)) {
+            args->vp_mode = vertexshader;
+        } else {
+            args->vp_mode = fixedfunction;
+        }
+    } else {
+        args->vp_mode = vertexshader;
+    }
+}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 015d7c0..847d11d 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2337,6 +2337,15 @@ struct stb_const_desc {
     UINT                    const_num;
 };
 
+/* Stateblock dependent parameters which have to be hardcoded
+ * into the shader code
+ */
+struct ps_compile_args {
+    BOOL                        srgb_correction;
+    WINED3DFORMAT               format_conversion[MAX_FRAGMENT_SAMPLERS];
+    enum vertexprocessing_mode  vp_mode;
+};
+
 typedef struct IWineD3DPixelShaderImpl {
     /* IUnknown parts */
     const IWineD3DPixelShaderVtbl *lpVtbl;
@@ -2369,7 +2378,8 @@ typedef struct IWineD3DPixelShaderImpl {
 
 extern const SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[];
 extern const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl;
-HRESULT pixelshader_compile(IWineD3DPixelShader *iface);
+HRESULT pixelshader_compile(IWineD3DPixelShader *iface, struct ps_compile_args *args);
+void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct ps_compile_args *args);
 
 /* sRGB correction constants */
 static const float srgb_cmp = 0.0031308;




More information about the wine-cvs mailing list