d3d10/effect: Use shader reflection to return output signature description.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2021-08-23 11:23:03 +03:00 committed by Alexandre Julliard
parent 4eef68eb8d
commit 4d135986a3
3 changed files with 48 additions and 45 deletions

View File

@ -106,7 +106,7 @@ struct d3d10_effect_shader_signature
struct d3d10_effect_shader_variable struct d3d10_effect_shader_variable
{ {
struct d3d10_effect_shader_signature input_signature; struct d3d10_effect_shader_signature input_signature;
struct d3d10_effect_shader_signature output_signature; ID3D10ShaderReflection *reflection;
union union
{ {
ID3D10VertexShader *vs; ID3D10VertexShader *vs;

View File

@ -599,16 +599,12 @@ static HRESULT shader_chunk_handler(const char *data, DWORD data_size, DWORD tag
switch(tag) switch(tag)
{ {
case TAG_ISGN: case TAG_ISGN:
case TAG_OSGN:
{ {
/* 32 (DXBC header) + 1 * 4 (chunk index) + 2 * 4 (chunk header) + data_size (chunk data) */ /* 32 (DXBC header) + 1 * 4 (chunk index) + 2 * 4 (chunk header) + data_size (chunk data) */
UINT size = 44 + data_size; UINT size = 44 + data_size;
struct d3d10_effect_shader_signature *sig; struct d3d10_effect_shader_signature *sig = &s->input_signature;
char *ptr; char *ptr;
if (tag == TAG_ISGN) sig = &s->input_signature;
else sig = &s->output_signature;
if (!(sig->signature = heap_alloc_zero(size))) if (!(sig->signature = heap_alloc_zero(size)))
{ {
ERR("Failed to allocate input signature data\n"); ERR("Failed to allocate input signature data\n");
@ -666,28 +662,22 @@ static HRESULT get_fx10_shader_resources(struct d3d10_effect_variable *v, const
struct d3d10_effect_shader_variable *sv = &v->u.shader; struct d3d10_effect_shader_variable *sv = &v->u.shader;
struct d3d10_effect_shader_resource *sr; struct d3d10_effect_shader_resource *sr;
D3D10_SHADER_INPUT_BIND_DESC bind_desc; D3D10_SHADER_INPUT_BIND_DESC bind_desc;
ID3D10ShaderReflection *reflection;
struct d3d10_effect_variable *var; struct d3d10_effect_variable *var;
D3D10_SHADER_DESC desc; D3D10_SHADER_DESC desc;
unsigned int i, y; unsigned int i, y;
HRESULT hr;
if (FAILED(hr = D3D10ReflectShader(data, data_size, &reflection))) sv->reflection->lpVtbl->GetDesc(sv->reflection, &desc);
return hr;
reflection->lpVtbl->GetDesc(reflection, &desc);
sv->resource_count = desc.BoundResources; sv->resource_count = desc.BoundResources;
if (!(sv->resources = heap_calloc(sv->resource_count, sizeof(*sv->resources)))) if (!(sv->resources = heap_calloc(sv->resource_count, sizeof(*sv->resources))))
{ {
ERR("Failed to allocate shader resource binding information memory.\n"); ERR("Failed to allocate shader resource binding information memory.\n");
reflection->lpVtbl->Release(reflection);
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
for (i = 0; i < desc.BoundResources; ++i) for (i = 0; i < desc.BoundResources; ++i)
{ {
reflection->lpVtbl->GetResourceBindingDesc(reflection, i, &bind_desc); sv->reflection->lpVtbl->GetResourceBindingDesc(sv->reflection, i, &bind_desc);
sr = &sv->resources[i]; sr = &sv->resources[i];
sr->in_type = bind_desc.Type; sr->in_type = bind_desc.Type;
@ -731,7 +721,6 @@ static HRESULT get_fx10_shader_resources(struct d3d10_effect_variable *v, const
if (!sr->variable) if (!sr->variable)
{ {
WARN("Failed to find shader resource.\n"); WARN("Failed to find shader resource.\n");
reflection->lpVtbl->Release(reflection);
return E_FAIL; return E_FAIL;
} }
} }
@ -774,6 +763,9 @@ static HRESULT parse_fx10_shader(const char *data, size_t data_size, DWORD offse
/* We got a shader VertexShader vs = NULL, so it is fine to skip this. */ /* We got a shader VertexShader vs = NULL, so it is fine to skip this. */
if (!dxbc_size) return S_OK; if (!dxbc_size) return S_OK;
if (FAILED(hr = D3D10ReflectShader(ptr, dxbc_size, &v->u.shader.reflection)))
return hr;
if (FAILED(hr = get_fx10_shader_resources(v, ptr, dxbc_size))) if (FAILED(hr = get_fx10_shader_resources(v, ptr, dxbc_size)))
return hr; return hr;
@ -2747,8 +2739,9 @@ static HRESULT d3d10_effect_object_apply(struct d3d10_effect_object *o)
static void d3d10_effect_shader_variable_destroy(struct d3d10_effect_shader_variable *s, static void d3d10_effect_shader_variable_destroy(struct d3d10_effect_shader_variable *s,
D3D10_SHADER_VARIABLE_TYPE type) D3D10_SHADER_VARIABLE_TYPE type)
{ {
if (s->reflection)
s->reflection->lpVtbl->Release(s->reflection);
shader_free_signature(&s->input_signature); shader_free_signature(&s->input_signature);
shader_free_signature(&s->output_signature);
switch (type) switch (type)
{ {
@ -7068,7 +7061,6 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetOutputSignature
{ {
struct d3d10_effect_variable *v = impl_from_ID3D10EffectShaderVariable(iface); struct d3d10_effect_variable *v = impl_from_ID3D10EffectShaderVariable(iface);
struct d3d10_effect_shader_variable *s; struct d3d10_effect_shader_variable *s;
D3D10_SIGNATURE_PARAMETER_DESC *d;
TRACE("iface %p, shader_index %u, element_index %u, desc %p\n", TRACE("iface %p, shader_index %u, element_index %u, desc %p\n",
iface, shader_index, element_index, desc); iface, shader_index, element_index, desc);
@ -7087,35 +7079,11 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetOutputSignature
} }
s = &v->effect->used_shaders[shader_index]->u.shader; s = &v->effect->used_shaders[shader_index]->u.shader;
if (!s->output_signature.signature)
{ if (!s->reflection)
WARN("No shader signature\n");
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
}
/* Check desc for NULL, this crashes on W7/DX10 */ return s->reflection->lpVtbl->GetOutputParameterDesc(s->reflection, element_index, desc);
if (!desc)
{
WARN("This should crash on W7/DX10!\n");
return E_FAIL;
}
if (element_index >= s->output_signature.element_count)
{
WARN("Invalid element index specified\n");
return E_INVALIDARG;
}
d = &s->output_signature.elements[element_index];
desc->SemanticName = d->SemanticName;
desc->SemanticIndex = d->SemanticIndex;
desc->SystemValueType = d->SystemValueType;
desc->ComponentType = d->ComponentType;
desc->Register = d->Register;
desc->ReadWriteMask = d->ReadWriteMask;
desc->Mask = d->Mask;
return S_OK;
} }

View File

@ -23,6 +23,8 @@
#include <float.h> #include <float.h>
#define D3DERR_INVALIDCALL 0x8876086c
static ID3D10Device *create_device(void) static ID3D10Device *create_device(void)
{ {
ID3D10Device *device; ID3D10Device *device;
@ -2796,8 +2798,9 @@ static void test_effect_local_shader(void)
D3D10_EFFECT_TYPE_DESC typedesc; D3D10_EFFECT_TYPE_DESC typedesc;
D3D10_EFFECT_DESC effect_desc; D3D10_EFFECT_DESC effect_desc;
ID3D10EffectShaderVariable *null_shader, *null_anon_vs, *null_anon_ps, *null_anon_gs, ID3D10EffectShaderVariable *null_shader, *null_anon_vs, *null_anon_ps, *null_anon_gs,
*p3_anon_vs, *p3_anon_ps, *p3_anon_gs, *p6_vs, *p6_ps, *p6_gs, *gs; *p3_anon_vs, *p3_anon_ps, *p3_anon_gs, *p6_vs, *p6_ps, *p6_gs, *gs, *ps, *vs;
D3D10_EFFECT_SHADER_DESC shaderdesc; D3D10_EFFECT_SHADER_DESC shaderdesc;
D3D10_SIGNATURE_PARAMETER_DESC sign;
ID3D10Device *device; ID3D10Device *device;
ULONG refcount; ULONG refcount;
@ -3648,6 +3651,38 @@ todo_wine
shaderdesc.SODecl); shaderdesc.SODecl);
} }
/* Output signature description */
v = effect->lpVtbl->GetVariableByName(effect, "p");
ps = v->lpVtbl->AsShader(v);
hr = ps->lpVtbl->GetOutputSignatureElementDesc(ps, 0, 0, &sign);
todo_wine
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
if (SUCCEEDED(hr))
ok(!strcmp(sign.SemanticName, "SV_Target"), "Unexpected semantic %s.\n", sign.SemanticName);
v = effect->lpVtbl->GetVariableByName(effect, "v");
vs = v->lpVtbl->AsShader(v);
hr = vs->lpVtbl->GetOutputSignatureElementDesc(vs, 0, 0, &sign);
todo_wine
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
if (SUCCEEDED(hr))
ok(!strcmp(sign.SemanticName, "SV_POSITION"), "Unexpected semantic %s.\n", sign.SemanticName);
hr = vs->lpVtbl->GetOutputSignatureElementDesc(vs, 1, 0, &sign);
todo_wine
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
if (SUCCEEDED(hr))
ok(!strcmp(sign.SemanticName, "SV_POSITION"), "Unexpected semantic %s.\n", sign.SemanticName);
/* NULL shader variable */
v = effect->lpVtbl->GetVariableByName(effect, "v0");
vs = v->lpVtbl->AsShader(v);
hr = vs->lpVtbl->GetOutputSignatureElementDesc(vs, 0, 0, &sign);
ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr);
effect->lpVtbl->Release(effect); effect->lpVtbl->Release(effect);
refcount = ID3D10Device_Release(device); refcount = ID3D10Device_Release(device);