From 055a0f0d6c251745164e1730aea28d4fd75737e2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rico=20Sch=C3=BCller?= Date: Wed, 7 Apr 2010 18:34:24 +0200 Subject: [PATCH] d3d10: Implement ID3DEffectVariable::GetInputSignatureElementDesc(). --- dlls/d3d10/d3d10_private.h | 13 ++++- dlls/d3d10/effect.c | 136 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 143 insertions(+), 6 deletions(-) diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h index 50fe7108c5c..0cad4846dfd 100644 --- a/dlls/d3d10/d3d10_private.h +++ b/dlls/d3d10/d3d10_private.h @@ -29,6 +29,13 @@ #include "d3d10.h" +/* + * This doesn't belong here, but for some functions it is possible to return that value, + * see http://msdn.microsoft.com/en-us/library/bb205278%28v=VS.85%29.aspx + * The original definition is in D3DX10core.h. + */ +#define D3DERR_INVALIDCALL 0x8876086c + /* TRACE helper functions */ const char *debug_d3d10_driver_type(D3D10_DRIVER_TYPE driver_type) DECLSPEC_HIDDEN; const char *debug_d3d10_shader_variable_class(D3D10_SHADER_VARIABLE_CLASS c) DECLSPEC_HIDDEN; @@ -66,6 +73,8 @@ struct d3d10_effect_shader_signature { char *signature; UINT signature_size; + UINT element_count; + D3D10_SIGNATURE_PARAMETER_DESC *elements; }; struct d3d10_effect_shader_variable @@ -188,15 +197,17 @@ struct d3d10_effect DWORD samplerstate_count; DWORD rendertargetview_count; DWORD depthstencilview_count; - DWORD shader_call_count; + DWORD used_shader_count; DWORD anonymous_shader_count; + DWORD used_shader_current; DWORD anonymous_shader_current; struct wine_rb_tree types; struct d3d10_effect_variable *local_buffers; struct d3d10_effect_variable *local_variables; struct d3d10_effect_anonymous_shader *anonymous_shaders; + struct d3d10_effect_variable **used_shaders; struct d3d10_effect_technique *techniques; }; diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index da4e344b4da..9c98b2ce85c 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -223,9 +223,63 @@ static BOOL copy_name(const char *ptr, char **name) return TRUE; } +static HRESULT shader_parse_signature(const char *data, DWORD data_size, struct d3d10_effect_shader_signature *s) +{ + D3D10_SIGNATURE_PARAMETER_DESC *e; + const char *ptr = data; + unsigned int i; + DWORD count; + + read_dword(&ptr, &count); + TRACE("%u elements\n", count); + + skip_dword_unknown(&ptr, 1); + + e = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*e)); + if (!e) + { + ERR("Failed to allocate signature memory.\n"); + return E_OUTOFMEMORY; + } + + for (i = 0; i < count; ++i) + { + UINT name_offset; + UINT mask; + + read_dword(&ptr, &name_offset); + e[i].SemanticName = data + name_offset; + read_dword(&ptr, &e[i].SemanticIndex); + read_dword(&ptr, &e[i].SystemValueType); + read_dword(&ptr, &e[i].ComponentType); + read_dword(&ptr, &e[i].Register); + read_dword(&ptr, &mask); + + e[i].ReadWriteMask = mask >> 8; + e[i].Mask = mask & 0xff; + + TRACE("semantic: %s, semantic idx: %u, sysval_semantic %#x, " + "type %u, register idx: %u, use_mask %#x, input_mask %#x\n", + debugstr_a(e[i].SemanticName), e[i].SemanticIndex, e[i].SystemValueType, + e[i].ComponentType, e[i].Register, e[i].Mask, e[i].ReadWriteMask); + } + + s->elements = e; + s->element_count = count; + + return S_OK; +} + +static void shader_free_signature(struct d3d10_effect_shader_signature *s) +{ + HeapFree(GetProcessHeap(), 0, s->signature); + HeapFree(GetProcessHeap(), 0, s->elements); +} + static HRESULT shader_chunk_handler(const char *data, DWORD data_size, DWORD tag, void *ctx) { struct d3d10_effect_shader_variable *s = ctx; + HRESULT hr; TRACE("tag: %s.\n", debugstr_an((const char *)&tag, 4)); @@ -274,6 +328,14 @@ static HRESULT shader_chunk_handler(const char *data, DWORD data_size, DWORD tag write_dword(&ptr, TAG_ISGN); write_dword(&ptr, data_size); memcpy(ptr, data, data_size); + + hr = shader_parse_signature(ptr, data_size, sig); + if (FAILED(hr)) + { + ERR("Failed to parse shader, hr %#x\n", hr); + shader_free_signature(sig); + } + break; } @@ -302,6 +364,15 @@ static HRESULT parse_shader(struct d3d10_effect_variable *v, const char *data) v->data = s; + if (v->effect->used_shader_current >= v->effect->used_shader_count) + { + WARN("Invalid shader? Used shader current(%u) >= used shader count(%u)\n", v->effect->used_shader_current, v->effect->used_shader_count); + return E_FAIL; + } + + v->effect->used_shaders[v->effect->used_shader_current] = v; + ++v->effect->used_shader_current; + if (!ptr) return S_OK; read_dword(&ptr, &dxbc_size); @@ -1581,6 +1652,13 @@ static HRESULT parse_fx10_body(struct d3d10_effect *e, const char *data, DWORD d return E_OUTOFMEMORY; } + e->used_shaders = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, e->used_shader_count * sizeof(*e->used_shaders)); + if (!e->used_shaders) + { + ERR("Failed to allocate used shaders memory\n"); + return E_OUTOFMEMORY; + } + e->techniques = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, e->technique_count * sizeof(*e->techniques)); if (!e->techniques) { @@ -1683,8 +1761,8 @@ static HRESULT parse_fx10(struct d3d10_effect *e, const char *data, DWORD data_s read_dword(&ptr, &e->depthstencilview_count); TRACE("Depthstencilview count: %u\n", e->depthstencilview_count); - read_dword(&ptr, &e->shader_call_count); - TRACE("Shader call count: %u\n", e->shader_call_count); + read_dword(&ptr, &e->used_shader_count); + TRACE("Used shader count: %u\n", e->used_shader_count); read_dword(&ptr, &e->anonymous_shader_count); TRACE("Anonymous shader count: %u\n", e->anonymous_shader_count); @@ -1785,7 +1863,7 @@ static void d3d10_effect_variable_destroy(struct d3d10_effect_variable *v) case D3D10_SVT_VERTEXSHADER: case D3D10_SVT_PIXELSHADER: case D3D10_SVT_GEOMETRYSHADER: - HeapFree(GetProcessHeap(), 0, ((struct d3d10_effect_shader_variable *)v->data)->input_signature.signature); + shader_free_signature(&((struct d3d10_effect_shader_variable *)v->data)->input_signature); break; default: @@ -1957,6 +2035,8 @@ static ULONG STDMETHODCALLTYPE d3d10_effect_Release(ID3D10Effect *iface) HeapFree(GetProcessHeap(), 0, This->anonymous_shaders); } + HeapFree(GetProcessHeap(), 0, This->used_shaders); + wine_rb_destroy(&This->types, d3d10_effect_type_destroy, NULL); ID3D10Device_Release(This->device); @@ -5160,10 +5240,56 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetInputSignatureE ID3D10EffectShaderVariable *iface, UINT shader_index, UINT element_index, D3D10_SIGNATURE_PARAMETER_DESC *desc) { - FIXME("iface %p, shader_index %u, element_index %u, desc %p stub!\n", + struct d3d10_effect_variable *This = (struct d3d10_effect_variable *)iface; + struct d3d10_effect_shader_variable *s; + D3D10_SIGNATURE_PARAMETER_DESC *d; + + TRACE("iface %p, shader_index %u, element_index %u, desc %p\n", iface, shader_index, element_index, desc); - return E_NOTIMPL; + if (!iface->lpVtbl->IsValid(iface)) + { + WARN("Null variable specified\n"); + return E_FAIL; + } + + /* Check shader_index, this crashes on W7/DX10 */ + if (shader_index >= This->effect->used_shader_count) + { + WARN("This should crash on W7/DX10!\n"); + return E_FAIL; + } + + s = This->effect->used_shaders[shader_index]->data; + if (!s->input_signature.signature) + { + WARN("No shader signature\n"); + return D3DERR_INVALIDCALL; + } + + /* Check desc for NULL, this crashes on W7/DX10 */ + if (!desc) + { + WARN("This should crash on W7/DX10!\n"); + return E_FAIL; + } + + if (element_index >= s->input_signature.element_count) + { + WARN("Invalid element index specified\n"); + return E_INVALIDARG; + } + + d = &s->input_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; } static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetOutputSignatureElementDesc( -- 2.11.4.GIT