From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v3 (Matteo): Flatten an else, tiny formatting fixes.
dlls/d3d10/effect.c | 84 ++++++++++++++++-------- dlls/d3d10/tests/effect.c | 134 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 184 insertions(+), 34 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index acc7199138b..025ed60d97b 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -6780,12 +6780,64 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetRawValue(
/* ID3D10EffectShaderVariable methods */
+static HRESULT d3d10_get_shader_variable(struct d3d10_effect_variable *v, UINT shader_index, + struct d3d10_effect_shader_variable **s) +{ + unsigned int i; + + if (v->type->element_count) + v = &v->elements[0]; + + if (!shader_index) + { + *s = &v->u.shader; + return S_OK; + } + + /* Index is used as an offset from this variable. */ + + for (i = 0; i < v->effect->used_shader_count; ++i) + { + if (v == v->effect->used_shaders[i]) break; + } + + if (i + shader_index >= v->effect->used_shader_count) + { + WARN("Invalid shader index %u.\n", shader_index); + return E_FAIL; + } + + *s = &v->effect->used_shaders[i + shader_index]->u.shader; + return S_OK; +} + static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetShaderDesc( ID3D10EffectShaderVariable *iface, UINT index, D3D10_EFFECT_SHADER_DESC *desc) { - FIXME("iface %p, index %u, desc %p stub!\n", iface, index, desc); + struct d3d10_effect_variable *v = impl_from_ID3D10EffectShaderVariable(iface); + struct d3d10_effect_shader_variable *s; + D3D10_SHADER_DESC shader_desc; + HRESULT hr;
- return E_NOTIMPL; + FIXME("iface %p, index %u, desc %p semi-stub.\n", iface, index, desc); + + if (FAILED(hr = d3d10_get_shader_variable(v, index, &s))) + return hr; + + memset(desc, 0, sizeof(*desc)); + if (s->input_signature) + desc->pInputSignature = ID3D10Blob_GetBufferPointer(s->input_signature); + desc->SODecl = s->stream_output_declaration; + if (s->reflection) + { + if (SUCCEEDED(hr = s->reflection->lpVtbl->GetDesc(s->reflection, &shader_desc))) + { + desc->NumInputSignatureEntries = shader_desc.InputParameters; + desc->NumOutputSignatureEntries = shader_desc.OutputParameters; + } + } + + return hr; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetVertexShader( @@ -6858,32 +6910,10 @@ static HRESULT d3d10_get_shader_variable_signature(struct d3d10_effect_variable UINT shader_index, UINT element_index, BOOL output, D3D10_SIGNATURE_PARAMETER_DESC *desc) { struct d3d10_effect_shader_variable *s; - unsigned int i; - - if (v->type->element_count) - v = &v->elements[0]; - - if (shader_index == 0) - { - s = &v->u.shader; - } - else - { - /* Index is used as an offset from this variable. */ - - for (i = 0; i < v->effect->used_shader_count; ++i) - { - if (v == v->effect->used_shaders[i]) break; - } - - if (i + shader_index >= v->effect->used_shader_count) - { - WARN("This should crash!\n"); - return E_FAIL; - } + HRESULT hr;
- s = &v->effect->used_shaders[i + shader_index]->u.shader; - } + if (FAILED(hr = d3d10_get_shader_variable(v, shader_index, &s))) + return hr;
if (!s->reflection) return D3DERR_INVALIDCALL; diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index 5fcece4695b..7645b6c45ab 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -3642,14 +3642,10 @@ if (0) v = effect->lpVtbl->GetVariableByName(effect, "g_so"); gs = v->lpVtbl->AsShader(v); hr = gs->lpVtbl->GetShaderDesc(gs, 0, &shaderdesc); -todo_wine ok(hr == S_OK, "Failed to get shader description, hr %#x.\n", hr); - if (hr == S_OK) - { - ok(!shaderdesc.IsInline, "Unexpected inline flag.\n"); - ok(!strcmp(shaderdesc.SODecl, "SV_POSITION.x"), "Unexpected stream output declaration %s.\n", - shaderdesc.SODecl); - } + ok(!shaderdesc.IsInline, "Unexpected inline flag.\n"); + ok(!strcmp(shaderdesc.SODecl, "SV_POSITION.x"), "Unexpected stream output declaration %s.\n", + shaderdesc.SODecl);
/* Signature description */ v = effect->lpVtbl->GetVariableByName(effect, "p"); @@ -5865,6 +5861,128 @@ static void test_effect_resource_variable(void) ok(!refcount, "Device has %u references left.\n", refcount); }
+static void test_effect_optimize(void) +{ + D3D10_EFFECT_SHADER_DESC shaderdesc; + ID3D10EffectShaderVariable *gs; + ID3D10EffectVariable *v; + ID3D10Effect *effect; + ID3D10Device *device; + ULONG refcount; + HRESULT hr; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + + hr = create_effect(fx_local_shader, 0, device, NULL, &effect); + ok(SUCCEEDED(hr), "Failed to create an effect.\n"); + + v = effect->lpVtbl->GetVariableByName(effect, "g_so"); + + gs = v->lpVtbl->AsShader(v); + hr = gs->lpVtbl->GetShaderDesc(gs, 0, &shaderdesc); + ok(hr == S_OK, "Failed to get shader description, hr %#x.\n", hr); + ok(!!shaderdesc.pInputSignature, "Expected input signature.\n"); + ok(!shaderdesc.IsInline, "Unexpected inline flag.\n"); +todo_wine { + ok(!!shaderdesc.pBytecode, "Expected bytecode.\n"); + ok(!!shaderdesc.BytecodeLength, "Unexpected bytecode length.\n"); +} + ok(!strcmp(shaderdesc.SODecl, "SV_POSITION.x"), "Unexpected stream output declaration %s.\n", shaderdesc.SODecl); + ok(!!shaderdesc.NumInputSignatureEntries, "Unexpected input signature count.\n"); + ok(!!shaderdesc.NumOutputSignatureEntries, "Unexpected output signature count.\n"); + + hr = effect->lpVtbl->Optimize(effect); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = gs->lpVtbl->GetShaderDesc(gs, 0, &shaderdesc); + ok(hr == S_OK, "Failed to get shader description, hr %#x.\n", hr); + ok(!!shaderdesc.pInputSignature, "Expected input signature.\n"); + ok(!shaderdesc.IsInline, "Unexpected inline flag.\n"); + ok(!shaderdesc.pBytecode, "Unexpected bytecode.\n"); + ok(!shaderdesc.BytecodeLength, "Unexpected bytecode length.\n"); +todo_wine { + ok(!shaderdesc.SODecl, "Unexpected stream output declaration %p.\n", shaderdesc.SODecl); + ok(!shaderdesc.NumInputSignatureEntries, "Unexpected input signature count.\n"); + ok(!shaderdesc.NumOutputSignatureEntries, "Unexpected output signature count.\n"); +} + effect->lpVtbl->Release(effect); + + refcount = ID3D10Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +} + +static void test_effect_shader_description(void) +{ + D3D10_EFFECT_SHADER_DESC shaderdesc; + ID3D10EffectShaderVariable *s; + ID3D10EffectVariable *v; + ID3D10Effect *effect; + ID3D10Device *device; + ULONG refcount; + HRESULT hr; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + + hr = create_effect(fx_local_shader, 0, device, NULL, &effect); + ok(SUCCEEDED(hr), "Failed to create an effect.\n"); + + v = effect->lpVtbl->GetVariableByName(effect, "v0"); + + /* GetShaderDesc() is indexing through all shaders in the effect.*/ + s = v->lpVtbl->AsShader(v); + hr = s->lpVtbl->GetShaderDesc(s, 0, &shaderdesc); + ok(hr == S_OK, "Failed to get shader description, hr %#x.\n", hr); + ok(!shaderdesc.BytecodeLength, "Unexpected bytecode length %u.\n", shaderdesc.BytecodeLength); + hr = s->lpVtbl->GetShaderDesc(s, 1, &shaderdesc); + ok(hr == S_OK, "Failed to get shader description, hr %#x.\n", hr); + ok(!shaderdesc.BytecodeLength, "Unexpected bytecode length %u.\n", shaderdesc.BytecodeLength); + hr = s->lpVtbl->GetShaderDesc(s, 2, &shaderdesc); + ok(hr == S_OK, "Failed to get shader description, hr %#x.\n", hr); + ok(!shaderdesc.BytecodeLength, "Unexpected bytecode length %u.\n", shaderdesc.BytecodeLength); + hr = s->lpVtbl->GetShaderDesc(s, 3, &shaderdesc); + ok(hr == S_OK, "Failed to get shader description, hr %#x.\n", hr); +todo_wine + ok(shaderdesc.BytecodeLength == 424, "Unexpected bytecode length %u.\n", + shaderdesc.BytecodeLength); + hr = s->lpVtbl->GetShaderDesc(s, 4, &shaderdesc); + ok(hr == S_OK, "Failed to get shader description, hr %#x.\n", hr); +todo_wine + ok(shaderdesc.BytecodeLength == 424, "Unexpected bytecode length %u.\n", + shaderdesc.BytecodeLength); + hr = s->lpVtbl->GetShaderDesc(s, 5, &shaderdesc); + ok(hr == S_OK, "Failed to get shader description, hr %#x.\n", hr); +todo_wine + ok(shaderdesc.BytecodeLength == 420, "Unexpected bytecode length %u.\n", + shaderdesc.BytecodeLength); + hr = s->lpVtbl->GetShaderDesc(s, 6, &shaderdesc); + ok(hr == S_OK, "Failed to get shader description, hr %#x.\n", hr); +todo_wine + ok(shaderdesc.BytecodeLength == 516, "Unexpected bytecode length %u.\n", + shaderdesc.BytecodeLength); + ok(!shaderdesc.SODecl, "Unexpected SO declaration %p.\n", shaderdesc.SODecl); + hr = s->lpVtbl->GetShaderDesc(s, 7, &shaderdesc); + ok(hr == S_OK, "Failed to get shader description, hr %#x.\n", hr); +todo_wine + ok(shaderdesc.BytecodeLength == 516, "Unexpected bytecode length %u.\n", + shaderdesc.BytecodeLength); + ok(!strcmp(shaderdesc.SODecl, "SV_POSITION.x"), "Unexpected SO declaration %s.\n", + wine_dbgstr_a(shaderdesc.SODecl)); + + effect->lpVtbl->Release(effect); + + refcount = ID3D10Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +} + START_TEST(effect) { test_effect_constant_buffer_type(); @@ -5881,4 +5999,6 @@ START_TEST(effect) test_effect_vector_variable(); test_effect_matrix_variable(); test_effect_resource_variable(); + test_effect_optimize(); + test_effect_shader_description(); }