wined3d: Refuse to create a shader unsupported by the backend.

Matteo Bruni mbruni at codeweavers.com
Wed Oct 12 15:44:46 CDT 2011


---
 dlls/d3d9/tests/shader.c       |   22 ++++++++++++++++++++--
 dlls/wined3d/device.c          |    2 ++
 dlls/wined3d/shader.c          |   19 +++++++++++++++++++
 dlls/wined3d/wined3d_private.h |    1 +
 4 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/dlls/d3d9/tests/shader.c b/dlls/d3d9/tests/shader.c
index f5a2bcb..ab05289 100644
--- a/dlls/d3d9/tests/shader.c
+++ b/dlls/d3d9/tests/shader.c
@@ -233,6 +233,14 @@ static void test_wrong_shader(IDirect3DDevice9 *device_ptr)
         0x0000ffff                                                              /* END                          */
     };
 
+    const DWORD vs_3_0[] = {
+        0xfffe0300,                                                             /* vs_3_0               */
+        0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
+        0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
+        0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
+        0x0000ffff                                                              /* end                  */
+    };
+
 #if 0
 float4 main(const float4 color : COLOR) : SV_TARGET
 {
@@ -263,9 +271,10 @@ float4 main(const float4 color : COLOR) : SV_TARGET
         0x00000000, 0x00000000,
     };
 
-    IDirect3DVertexShader9 *vs;
-    IDirect3DPixelShader9 *ps;
+    IDirect3DVertexShader9 *vs = NULL;
+    IDirect3DPixelShader9 *ps = NULL;
     HRESULT hret;
+    D3DCAPS9 caps;
 
     hret = IDirect3DDevice9_CreateVertexShader(device_ptr, simple_ps, &vs);
     ok(hret == D3DERR_INVALIDCALL, "CreateVertexShader returned: hret 0x%x, shader_ptr %p.\n", hret, vs);
@@ -274,6 +283,15 @@ float4 main(const float4 color : COLOR) : SV_TARGET
 
     hret = IDirect3DDevice9_CreatePixelShader(device_ptr, ps_4_0, &ps);
     ok(hret == D3DERR_INVALIDCALL, "CreatePixelShader returned: hret 0x%x, shader_ptr %p.\n", hret, ps);
+
+    IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
+    if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
+    {
+        hret = IDirect3DDevice9_CreateVertexShader(device_ptr, vs_3_0, &vs);
+        ok(hret == D3DERR_INVALIDCALL, "CreateVertexShader returned: hret 0x%x, shader_ptr %p.\n", hret, vs);
+    }
+    else
+        skip("This GPU supports SM3, skipping unsupported shader test.\n");
 }
 
 START_TEST(shader)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index ec9126f..5537005 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -6046,6 +6046,8 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
     if (device->shader_backend)
     {
         device->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
+        device->vshader_version = shader_caps.VertexShaderVersion;
+        device->pshader_version = shader_caps.PixelShaderVersion;
         device->d3d_vshader_constantF = shader_caps.MaxVertexShaderConst;
         device->d3d_pshader_constantF = shader_caps.MaxPixelShaderConst;
         device->vs_clipping = shader_caps.VSClipping;
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 51dc125..2bd926b 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -1559,6 +1559,7 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, const DWORD *b
     struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
     const struct wined3d_shader_frontend *fe;
     HRESULT hr;
+    unsigned int backend_version;
 
     TRACE("shader %p, byte_code %p, output_signature %p, float_const_count %u.\n",
             shader, byte_code, output_signature, float_const_count);
@@ -1602,6 +1603,24 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, const DWORD *b
         WARN("Shader version %d not supported by this D3D API version.\n", reg_maps->shader_version.major);
         return WINED3DERR_INVALIDCALL;
     }
+    switch (type)
+    {
+        case WINED3D_SHADER_TYPE_VERTEX:
+            backend_version = shader->device->vshader_version & 0xffff;
+            break;
+        case WINED3D_SHADER_TYPE_PIXEL:
+            backend_version = shader->device->pshader_version & 0xffff;
+            break;
+        default:
+            FIXME("No backend version-checking for this shader type\n");
+            backend_version = 0;
+    }
+    if (WINED3D_SHADER_VERSION(reg_maps->shader_version.major, reg_maps->shader_version.minor) > backend_version)
+    {
+        WARN("Shader version %d.%d not supported by your GPU with the current shader backend.\n",
+	        reg_maps->shader_version.major, reg_maps->shader_version.minor);
+        return WINED3DERR_INVALIDCALL;
+    }
 
     shader->function = HeapAlloc(GetProcessHeap(), 0, shader->functionLength);
     if (!shader->function)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e5ed787..d6c880e 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1668,6 +1668,7 @@ struct wined3d_device
     const struct blit_shader *blitter;
 
     unsigned int max_ffp_textures;
+    DWORD vshader_version, pshader_version;
     DWORD d3d_vshader_constantF, d3d_pshader_constantF; /* Advertised d3d caps, not GL ones */
     DWORD vs_clipping;
 
-- 
1.7.3.4




More information about the wine-patches mailing list