Rico Schüller : d3d10: Implement ID3DEffectVariable:: GetInputSignatureElementDesc().
Alexandre Julliard
julliard at winehq.org
Thu Apr 8 11:12:44 CDT 2010
Module: wine
Branch: master
Commit: 055a0f0d6c251745164e1730aea28d4fd75737e2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=055a0f0d6c251745164e1730aea28d4fd75737e2
Author: Rico Schüller <kgbricola at web.de>
Date: Wed Apr 7 18:34:24 2010 +0200
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 50fe710..0cad484 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 da4e344..9c98b2c 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(
More information about the wine-cvs
mailing list