diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c index 50719b2ccaf..5a0f1db77c6 100644 --- a/dlls/d3dx9_36/shader.c +++ b/dlls/d3dx9_36/shader.c @@ -1273,50 +1273,40 @@ HRESULT WINAPI D3DXGetShaderConstantTable(CONST DWORD* byte_code, HRESULT WINAPI D3DXGetShaderSamplers(CONST DWORD *byte_code, LPCSTR *samplers, UINT *count) { HRESULT hr; - LPD3DXCONSTANTTABLE constant_table = NULL; - D3DXCONSTANTTABLE_DESC constant_table_desc; UINT i, sampler_count = 0; + UINT size; + LPCSTR data; + const D3DXSHADER_CONSTANTTABLE *ctab_header; + const D3DXSHADER_CONSTANTINFO *constant_info; TRACE("byte_code %p, samplers %p, count %p\n", byte_code, samplers, count); if (count) *count = 0; - hr = D3DXGetShaderConstantTable(byte_code, &constant_table); - if (hr != D3D_OK) + hr = D3DXFindShaderComment(byte_code, MAKEFOURCC('C','T','A','B'), (LPCVOID *)&data, &size); + if (hr != D3D_OK) return D3D_OK; + + if (size < sizeof(D3DXSHADER_CONSTANTTABLE)) return D3D_OK; + + ctab_header = (const D3DXSHADER_CONSTANTTABLE *)data; + if (ctab_header->Size != sizeof(*ctab_header)) return D3D_OK; + + constant_info = (D3DXSHADER_CONSTANTINFO *)(data + ctab_header->ConstantInfo); + for (i = 0; i < ctab_header->Constants; i++) { - WARN("Failed to get constant table\n"); + const D3DXSHADER_TYPEINFO *type; - /* no samplers found, all is fine */ - return D3D_OK; - } + TRACE("name = %s\n", data + constant_info[i].Name); - hr = ID3DXConstantTable_GetDesc(constant_table, &constant_table_desc); - if (hr != D3D_OK) - { - WARN("Failed to get constant table desc\n"); - goto err_out; - } + type = (D3DXSHADER_TYPEINFO *)(data + constant_info[i].TypeInfo); - for (i = 0; i < constant_table_desc.Constants; ++i) - { - D3DXHANDLE handle = ID3DXConstantTable_GetConstant(constant_table, NULL, i); - D3DXCONSTANT_DESC constant_desc; - UINT size; - - hr = ID3DXConstantTable_GetConstantDesc(constant_table, handle, &constant_desc, &size); - if (hr != D3D_OK) + if (type->Type == D3DXPT_SAMPLER + || type->Type == D3DXPT_SAMPLER1D + || type->Type == D3DXPT_SAMPLER2D + || type->Type == D3DXPT_SAMPLER3D + || type->Type == D3DXPT_SAMPLERCUBE) { - WARN("Failed to get constant desc\n"); - goto err_out; - } - - if (constant_desc.Type == D3DXPT_SAMPLER - || constant_desc.Type == D3DXPT_SAMPLER1D - || constant_desc.Type == D3DXPT_SAMPLER2D - || constant_desc.Type == D3DXPT_SAMPLER3D - || constant_desc.Type == D3DXPT_SAMPLERCUBE) - { - if (samplers) samplers[sampler_count] = constant_desc.Name; + if (samplers) samplers[sampler_count] = data + constant_info[i].Name; ++sampler_count; } @@ -1324,10 +1314,7 @@ HRESULT WINAPI D3DXGetShaderSamplers(CONST DWORD *byte_code, LPCSTR *samplers, U TRACE("Found %u samplers\n", sampler_count); -err_out: - if (count) *count = sampler_count; - if (constant_table) ID3DXConstantTable_Release(constant_table); - return hr; + return D3D_OK; } diff --git a/dlls/d3dx9_36/tests/shader.c b/dlls/d3dx9_36/tests/shader.c index 0a1b8bf223e..9220e28fb70 100644 --- a/dlls/d3dx9_36/tests/shader.c +++ b/dlls/d3dx9_36/tests/shader.c @@ -768,6 +768,7 @@ static const DWORD get_shader_samplers_blob[] = static void test_get_shader_samplers(void) { LPCSTR samplers[16] = {NULL}; /* maximum number of sampler registers v/ps 3.0 = 16 */ + LPCSTR sampler_orig; UINT count = 2; HRESULT hr; @@ -785,11 +786,22 @@ static void test_get_shader_samplers(void) hr = D3DXGetShaderSamplers(get_shader_samplers_blob, samplers, NULL); ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK); - ok(!strcmp(samplers[0], "s"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[0], "s"); - ok(!strcmp(samplers[1], "s1D"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[1], "s1D"); - ok(!strcmp(samplers[2], "s2D"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[2], "s2D"); - ok(!strcmp(samplers[3], "s3D"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[3], "s3D"); - ok(!strcmp(samplers[4], "scube"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[4], "scube"); + /* check that sampler points to shader blob */ + sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x2E]; + ok(sampler_orig == samplers[0], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[0], sampler_orig); + + sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x33]; + ok(sampler_orig == samplers[1], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[1], sampler_orig); + + sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x38]; + ok(sampler_orig == samplers[2], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[2], sampler_orig); + + sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x3D]; + ok(sampler_orig == samplers[3], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[3], sampler_orig); + + sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x42]; + ok(sampler_orig == samplers[4], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[4], sampler_orig); + ok(!strcmp(samplers[5], "dummy"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[5], "dummy"); /* reset samplers */ @@ -804,12 +816,33 @@ static void test_get_shader_samplers(void) ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK); ok(count == 5, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 5); - ok(!strcmp(samplers[0], "s"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[0], "s"); - ok(!strcmp(samplers[1], "s1D"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[1], "s1D"); - ok(!strcmp(samplers[2], "s2D"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[2], "s2D"); - ok(!strcmp(samplers[3], "s3D"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[3], "s3D"); - ok(!strcmp(samplers[4], "scube"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[4], "scube"); + /* check that sampler points to shader blob */ + sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x2E]; + ok(sampler_orig == samplers[0], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[0], sampler_orig); + + sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x33]; + ok(sampler_orig == samplers[1], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[1], sampler_orig); + + sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x38]; + ok(sampler_orig == samplers[2], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[2], sampler_orig); + + sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x3D]; + ok(sampler_orig == samplers[3], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[3], sampler_orig); + + sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x42]; + ok(sampler_orig == samplers[4], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[4], sampler_orig); + ok(!strcmp(samplers[5], "dummy"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[5], "dummy"); + + /* check without ctab */ + hr = D3DXGetShaderSamplers(simple_vs, samplers, &count); + ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK); + ok(count == 0, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 0); + + /* check invalid ctab */ + hr = D3DXGetShaderSamplers(shader_with_invalid_ctab, samplers, &count); + ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK); + ok(count == 0, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 0); } START_TEST(shader)