wined3d: Don't reparse the entire shader just to update the sampler types.

Henri Verbeet hverbeet at codeweavers.com
Fri Dec 12 02:33:51 CST 2008


---
 dlls/wined3d/baseshader.c      |   32 ++---------------
 dlls/wined3d/device.c          |    3 +-
 dlls/wined3d/pixelshader.c     |   76 +++++++++++++++++++++++++---------------
 dlls/wined3d/vertexshader.c    |    2 +-
 dlls/wined3d/wined3d_private.h |   12 ++----
 include/wine/wined3d.idl       |    2 -
 6 files changed, 58 insertions(+), 69 deletions(-)

diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index 8d6c28c..9bac931 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -207,8 +207,7 @@ static void shader_delete_constant_list(struct list* clist) {
  * as an address register. */
 
 HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_maps *reg_maps,
-        struct semantic *semantics_in, struct semantic *semantics_out, const DWORD *byte_code,
-        IWineD3DStateBlockImpl *stateBlock)
+        struct semantic *semantics_in, struct semantic *semantics_out, const DWORD *byte_code)
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     const SHADER_OPCODE *shader_ins = This->baseShader.shader_ins;
@@ -384,33 +383,8 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m
                 /* Fake sampler usage, only set reserved bit and ttype */
                 DWORD sampler_code = *pToken & WINED3DSP_REGNUM_MASK;
 
-                if(!stateBlock->textures[sampler_code]) {
-                    ERR("No texture bound to sampler %d\n", sampler_code);
-                    reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D;
-                } else {
-                    int texType = IWineD3DBaseTexture_GetTextureDimensions(stateBlock->textures[sampler_code]);
-                    switch(texType) {
-                        /* We have to select between texture rectangles and 2D textures later because 2.0 and
-                         * 3.0 shaders only have WINED3DSTT_2D as well
-                         */
-                        case GL_TEXTURE_RECTANGLE_ARB:
-                        case GL_TEXTURE_2D:
-                            reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D;
-                            break;
-
-                        case GL_TEXTURE_3D:
-                            reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_VOLUME;
-                            break;
-
-                        case GL_TEXTURE_CUBE_MAP_ARB:
-                            reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_CUBE;
-                            break;
-
-                        default:
-                            ERR("Unexpected gl texture type found: %d\n", texType);
-                            reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D;
-                    }
-                }
+                TRACE("Setting fake 2D sampler for 1.x pixelshader\n");
+                reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D;
 
                 /* texbem is only valid with < 1.4 pixel shaders */
                 if(WINED3DSIO_TEXBEM  == curOpcode->opcode ||
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 836ad3b..0541c59 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3862,7 +3862,8 @@ 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_UpdateSamplers((IWineD3DPixelShader *)pshader);
+        pixelshader_update_samplers(&pshader->baseShader.reg_maps, This->stateBlock->textures,
+                pshader->baseShader.hex_version);
         pshader_sampler_tokens = pshader->baseShader.reg_maps.samplers;
     }
 
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index c5f3c3e..200a2bc 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -332,8 +332,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
 
     /* 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, pFunction, deviceImpl->stateBlock);
+    hr = shader_get_registers_used((IWineD3DBaseShader *)This, reg_maps, This->semantics_in, NULL, pFunction);
     if (FAILED(hr)) return hr;
 
     pshader_set_limits(This);
@@ -396,19 +395,60 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
     return WINED3D_OK;
 }
 
+void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures,
+        DWORD shader_version)
+{
+    DWORD *samplers = reg_maps->samplers;
+    unsigned int i;
+
+    if (WINED3DSHADER_VERSION_MAJOR(shader_version) != 1) return;
+
+    for (i = 0; i < max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS); ++i)
+    {
+        /* We don't sample from this sampler */
+        if (!samplers[i]) continue;
+
+        if (!textures[i])
+        {
+            ERR("No texture bound to sampler %u, using 2D\n", i);
+            samplers[i] = (0x1 << 31) | WINED3DSTT_2D;
+            continue;
+        }
+
+        switch (IWineD3DBaseTexture_GetTextureDimensions(textures[i]))
+        {
+            case GL_TEXTURE_RECTANGLE_ARB:
+            case GL_TEXTURE_2D:
+                /* We have to select between texture rectangles and 2D textures later because 2.0 and
+                 * 3.0 shaders only have WINED3DSTT_2D as well */
+                samplers[i] = (1 << 31) | WINED3DSTT_2D;
+                break;
+
+            case GL_TEXTURE_3D:
+                samplers[i] = (1 << 31) | WINED3DSTT_VOLUME;
+                break;
+
+            case GL_TEXTURE_CUBE_MAP_ARB:
+                samplers[i] = (1 << 31) | WINED3DSTT_CUBE;
+                break;
+
+            default:
+                FIXME("Unrecognized texture type %#x, using 2D\n",
+                        IWineD3DBaseTexture_GetTextureDimensions(textures[i]));
+                samplers[i] = (0x1 << 31) | WINED3DSTT_2D;
+        }
+    }
+}
+
 static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps_compile_args *args)
 {
     CONST DWORD *function = This->baseShader.function;
-    HRESULT hr;
     GLuint retval;
 
     TRACE("(%p) : function %p\n", This, function);
 
-    hr = IWineD3DPixelShader_UpdateSamplers((IWineD3DPixelShader *) This);
-    if(FAILED(hr)) {
-        ERR("Failed to update sampler information\n");
-        return 0;
-    }
+    pixelshader_update_samplers(&This->baseShader.reg_maps,
+            ((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->textures, This->baseShader.hex_version);
 
     /* Reset fields tracking stateblock values being hardcoded in the shader */
     This->baseShader.num_sampled_samplers = 0;
@@ -422,25 +462,6 @@ static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps
     return retval;
 }
 
-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 ***/
@@ -452,7 +473,6 @@ const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl =
     /*** IWineD3DBaseShader methods ***/
     IWineD3DPixelShaderImpl_SetFunction,
     /*** IWineD3DPixelShader methods ***/
-    IWineD3DPixelShaderImpl_UpdateSamplers,
     IWineD3DPixelShaderImpl_GetDevice,
     IWineD3DPixelShaderImpl_GetFunction
 };
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 529fe7a..ea8781f 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -447,7 +447,7 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
     This->max_rel_offset = 0;
     memset(reg_maps, 0, sizeof(shader_reg_maps));
     hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps,
-       This->semantics_in, This->semantics_out, pFunction, NULL);
+            This->semantics_in, This->semantics_out, pFunction);
     if (hr != WINED3D_OK) return hr;
 
     vshader_set_limits(This);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index fe5569a..8cb8cea 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2230,16 +2230,10 @@ typedef struct IWineD3DBaseShaderImpl {
 void shader_buffer_init(struct SHADER_BUFFER *buffer);
 void shader_buffer_free(struct SHADER_BUFFER *buffer);
 void shader_cleanup(IWineD3DBaseShader *iface);
+HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_maps *reg_maps,
+        struct semantic *semantics_in, struct semantic *semantics_out, const DWORD *byte_code);
 void shader_trace_init(const DWORD *byte_code, const SHADER_OPCODE *opcode_table);
 
-extern HRESULT shader_get_registers_used(
-    IWineD3DBaseShader *iface,
-    shader_reg_maps* reg_maps,
-    semantic* semantics_in,
-    semantic* semantics_out,
-    CONST DWORD* pToken,
-    IWineD3DStateBlockImpl *stateBlock);
-
 extern void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
         const shader_reg_maps *reg_maps, const DWORD *pFunction);
 
@@ -2407,6 +2401,8 @@ extern const SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[];
 extern const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl;
 GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args);
 void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct ps_compile_args *args);
+void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures,
+        DWORD shader_version);
 
 /* sRGB correction constants */
 static const float srgb_cmp = 0.0031308;
diff --git a/include/wine/wined3d.idl b/include/wine/wined3d.idl
index abb0d3b..39ba598 100644
--- a/include/wine/wined3d.idl
+++ b/include/wine/wined3d.idl
@@ -2825,8 +2825,6 @@ interface IWineD3DVertexShader : IWineD3DBaseShader
 ]
 interface IWineD3DPixelShader : IWineD3DBaseShader
 {
-    HRESULT UpdateSamplers(
-    );
     HRESULT GetDevice(
         [out] IWineD3DDevice **device
     );
-- 
1.5.6.4



--------------030900030602010403050708--



More information about the wine-patches mailing list