From 095a9a68937a04949a04d707f81fe7b3d75840b0 Mon Sep 17 00:00:00 2001 From: Matteo Bruni Date: Tue, 25 Oct 2011 16:58:47 +0200 Subject: [PATCH] wined3d: Refuse to create a shader unsupported by the backend. --- 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 f5a2bcb978d..ab052893b7a 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 5aace82a374..05a0ad86b0e 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -5938,6 +5938,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 69bd69d6aed..50ecc2cf5fe 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; + break; + case WINED3D_SHADER_TYPE_PIXEL: + backend_version = shader->device->pshader_version; + break; + default: + FIXME("No backend version-checking for this shader type\n"); + backend_version = 0; + } + if (reg_maps->shader_version.major > 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 3b865807cb5..9b510c45bab 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; -- 2.11.4.GIT