wined3d: Select the frontend based on the version token.

Henri Verbeet hverbeet at codeweavers.com
Mon May 4 02:49:27 CDT 2009


---
 dlls/wined3d/baseshader.c      |   17 +++++++++++++++++
 dlls/wined3d/pixelshader.c     |   24 +++++++++++++++++++-----
 dlls/wined3d/vertexshader.c    |   23 +++++++++++++++++++----
 dlls/wined3d/wined3d_private.h |    1 +
 4 files changed, 56 insertions(+), 9 deletions(-)

diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index b519fe5..e3f6311 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -119,6 +119,23 @@ static const char *shader_opcode_names[] =
     /* WINED3DSIH_TEXREG2RGB    */ "texreg2rgb",
 };
 
+#define WINED3D_SM1_VS  0xfffe
+#define WINED3D_SM1_PS  0xffff
+
+const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token)
+{
+    switch (version_token >> 16)
+    {
+        case WINED3D_SM1_VS:
+        case WINED3D_SM1_PS:
+            return &sm1_shader_frontend;
+
+        default:
+            FIXME("Unrecognised version token %#x\n", version_token);
+            return NULL;
+    }
+}
+
 static inline BOOL shader_is_version_token(DWORD token) {
     return shader_is_pshader_version(token) ||
            shader_is_vshader_version(token);
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index 33ac91c..c4693a2 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -301,12 +301,20 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
     IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
     unsigned int i, highest_reg_used = 0, num_regs_used = 0;
     shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
+    const struct wined3d_shader_frontend *fe;
     HRESULT hr;
 
     TRACE("(%p) : pFunction %p\n", iface, pFunction);
 
+    fe = shader_select_frontend(*pFunction);
+    if (!fe)
+    {
+        FIXME("Unable to find frontend for shader.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
+
     /* First pass: trace shader */
-    if (TRACE_ON(d3d_shader)) shader_trace_init(&sm1_shader_frontend, pFunction, This->baseShader.shader_ins);
+    if (TRACE_ON(d3d_shader)) shader_trace_init(fe, pFunction, This->baseShader.shader_ins);
 
     /* Initialize immediate constant lists */
     list_init(&This->baseShader.constantsF);
@@ -314,8 +322,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
     list_init(&This->baseShader.constantsI);
 
     /* Second pass: figure out which registers are used, what the semantics are, etc.. */
-    hr = shader_get_registers_used((IWineD3DBaseShader *)This, &sm1_shader_frontend,
-            reg_maps, This->semantics_in, NULL, pFunction);
+    hr = shader_get_registers_used((IWineD3DBaseShader *)This, fe, reg_maps, This->semantics_in, NULL, pFunction);
     if (FAILED(hr)) return hr;
 
     pshader_set_limits(This);
@@ -422,10 +429,18 @@ static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps
     CONST DWORD *function = This->baseShader.function;
     GLuint retval;
     SHADER_BUFFER buffer;
+    const struct wined3d_shader_frontend *fe;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
 
     TRACE("(%p) : function %p\n", This, function);
 
+    fe = shader_select_frontend(This->baseShader.reg_maps.shader_version);
+    if (!fe)
+    {
+        FIXME("Unable to find frontend for shader.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
+
     pixelshader_update_samplers(&This->baseShader.reg_maps,
             ((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->textures);
 
@@ -433,8 +448,7 @@ static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps
     TRACE("(%p) : Generating hardware program\n", This);
     This->cur_args = args;
     shader_buffer_init(&buffer);
-    retval = device->shader_backend->shader_generate_pshader((IWineD3DPixelShader *)This,
-            &sm1_shader_frontend, &buffer, args);
+    retval = device->shader_backend->shader_generate_pshader((IWineD3DPixelShader *)This, fe, &buffer, args);
     shader_buffer_free(&buffer);
     This->cur_args = NULL;
 
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 9758407..c71b612 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -313,13 +313,21 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
 
     IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
     IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
+    const struct wined3d_shader_frontend *fe;
     HRESULT hr;
     shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
 
     TRACE("(%p) : pFunction %p\n", iface, pFunction);
 
+    fe = shader_select_frontend(*pFunction);
+    if (!fe)
+    {
+        FIXME("Unable to find frontend for shader.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
+
     /* First pass: trace shader */
-    if (TRACE_ON(d3d_shader)) shader_trace_init(&sm1_shader_frontend, pFunction, This->baseShader.shader_ins);
+    if (TRACE_ON(d3d_shader)) shader_trace_init(fe, pFunction, This->baseShader.shader_ins);
 
     /* Initialize immediate constant lists */
     list_init(&This->baseShader.constantsF);
@@ -329,7 +337,7 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
     /* Second pass: figure out registers used, semantics, etc.. */
     This->min_rel_offset = GL_LIMITS(vshader_constantsF);
     This->max_rel_offset = 0;
-    hr = shader_get_registers_used((IWineD3DBaseShader*) This, &sm1_shader_frontend,
+    hr = shader_get_registers_used((IWineD3DBaseShader*) This, fe,
             reg_maps, This->semantics_in, This->semantics_out, pFunction);
     if (hr != WINED3D_OK) return hr;
 
@@ -404,15 +412,22 @@ static HRESULT WINAPI IWIneD3DVertexShaderImpl_SetLocalConstantsF(IWineD3DVertex
 
 static GLuint vertexshader_compile(IWineD3DVertexShaderImpl *This, const struct vs_compile_args *args) {
     IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
+    const struct wined3d_shader_frontend *fe;
     SHADER_BUFFER buffer;
     GLuint ret;
 
+    fe = shader_select_frontend(This->baseShader.reg_maps.shader_version);
+    if (!fe)
+    {
+        FIXME("Unable to find frontend for shader.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
+
     /* Generate the HW shader */
     TRACE("(%p) : Generating hardware program\n", This);
     shader_buffer_init(&buffer);
     This->cur_args = args;
-    ret = deviceImpl->shader_backend->shader_generate_vshader((IWineD3DVertexShader *)This,
-            &sm1_shader_frontend, &buffer, args);
+    ret = deviceImpl->shader_backend->shader_generate_vshader((IWineD3DVertexShader *)This, fe, &buffer, args);
     This->cur_args = NULL;
     shader_buffer_free(&buffer);
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index b22c191..09d8f9d 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2555,6 +2555,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3
         struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code);
 void shader_init(struct IWineD3DBaseShaderClass *shader,
         IWineD3DDevice *device, const SHADER_OPCODE *instruction_table);
+const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token);
 void shader_trace_init(const struct wined3d_shader_frontend *fe,
         const DWORD *pFunction, const SHADER_OPCODE *opcode_table);
 
-- 
1.6.0.6



--------------060307030301000705040802--



More information about the wine-patches mailing list