d3d10core: Create a vertex declaration from the input layout.

Henri Verbeet hverbeet at codeweavers.com
Mon Mar 30 04:24:55 CDT 2009


---
 dlls/d3d10core/d3d10core_private.h |    9 ++-
 dlls/d3d10core/device.c            |   23 +++++-
 dlls/d3d10core/inputlayout.c       |  139 ++++++++++++++++++++++++++++++++++++
 3 files changed, 167 insertions(+), 4 deletions(-)

diff --git a/dlls/d3d10core/d3d10core_private.h b/dlls/d3d10core/d3d10core_private.h
index ff723ba..df9794f 100644
--- a/dlls/d3d10core/d3d10core_private.h
+++ b/dlls/d3d10core/d3d10core_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Henri Verbeet for CodeWeavers
+ * Copyright 2008-2009 Henri Verbeet for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -38,6 +38,7 @@
     ((DWORD)(ch0) | ((DWORD)(ch1) << 8) | \
     ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 ))
 #define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C')
+#define TAG_ISGN MAKE_TAG('I', 'S', 'G', 'N')
 
 /* TRACE helper functions */
 const char *debug_d3d10_primitive_topology(D3D10_PRIMITIVE_TOPOLOGY topology);
@@ -118,8 +119,14 @@ struct d3d10_input_layout
 {
     const struct ID3D10InputLayoutVtbl *vtbl;
     LONG refcount;
+
+    IWineD3DVertexDeclaration *wined3d_decl;
 };
 
+HRESULT d3d10_input_layout_to_wined3d_declaration(const D3D10_INPUT_ELEMENT_DESC *element_descs,
+        UINT element_count, const void *shader_byte_code, SIZE_T shader_byte_code_length,
+        WINED3DVERTEXELEMENT **wined3d_elements, UINT *wined3d_element_count);
+
 /* ID3D10VertexShader */
 extern const struct ID3D10VertexShaderVtbl d3d10_vertex_shader_vtbl;
 struct d3d10_vertex_shader
diff --git a/dlls/d3d10core/device.c b/dlls/d3d10core/device.c
index 7320f92..ff31b53 100644
--- a/dlls/d3d10core/device.c
+++ b/dlls/d3d10core/device.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Henri Verbeet for CodeWeavers
+ * Copyright 2008-2009 Henri Verbeet for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -909,10 +909,14 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateInputLayout(ID3D10Device *if
         const D3D10_INPUT_ELEMENT_DESC *element_descs, UINT element_count, const void *shader_byte_code,
         SIZE_T shader_byte_code_length, ID3D10InputLayout **input_layout)
 {
+    struct d3d10_device *This = (struct d3d10_device *)iface;
     struct d3d10_input_layout *object;
+    WINED3DVERTEXELEMENT *wined3d_elements;
+    UINT wined3d_element_count;
+    HRESULT hr;
 
-    FIXME("iface %p, element_descs %p, element_count %u, shader_byte_code %p,"
-            "\tshader_byte_code_length %lu, input_layout %p stub!\n",
+    TRACE("iface %p, element_descs %p, element_count %u, shader_byte_code %p,"
+            "\tshader_byte_code_length %lu, input_layout %p\n",
             iface, element_descs, element_count, shader_byte_code,
             shader_byte_code_length, input_layout);
 
@@ -926,6 +930,19 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateInputLayout(ID3D10Device *if
     object->vtbl = &d3d10_input_layout_vtbl;
     object->refcount = 1;
 
+    hr = d3d10_input_layout_to_wined3d_declaration(element_descs, element_count,
+            shader_byte_code, shader_byte_code_length, &wined3d_elements, &wined3d_element_count);
+    if (FAILED(hr))
+    {
+        HeapFree(GetProcessHeap(), 0, object);
+        return hr;
+    }
+
+    IWineD3DDevice_CreateVertexDeclaration(This->wined3d_device, &object->wined3d_decl,
+            (IUnknown *)object, wined3d_elements, wined3d_element_count);
+
+    HeapFree(GetProcessHeap(), 0, wined3d_elements);
+
     *input_layout = (ID3D10InputLayout *)object;
 
     return S_OK;
diff --git a/dlls/d3d10core/inputlayout.c b/dlls/d3d10core/inputlayout.c
index 034a642..d78ecad 100644
--- a/dlls/d3d10core/inputlayout.c
+++ b/dlls/d3d10core/inputlayout.c
@@ -24,6 +24,144 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d10core);
 
+struct input_signature_element
+{
+    const char *semantic_name;
+    UINT semantic_idx;
+    DWORD unknown; /* system value semantic? */
+    DWORD component_type;
+    UINT register_idx;
+    DWORD mask;
+};
+
+struct input_signature
+{
+    struct input_signature_element *elements;
+    UINT element_count;
+};
+
+static HRESULT parse_isgn(const char *data, struct input_signature *is)
+{
+    struct input_signature_element *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 input signature memory.\n");
+        return E_OUTOFMEMORY;
+    }
+
+    for (i = 0; i < count; ++i)
+    {
+        UINT name_offset;
+
+        read_dword(&ptr, &name_offset);
+        e[i].semantic_name = data + name_offset;
+        read_dword(&ptr, &e[i].semantic_idx);
+        read_dword(&ptr, &e[i].unknown);
+        read_dword(&ptr, &e[i].component_type);
+        read_dword(&ptr, &e[i].register_idx);
+        read_dword(&ptr, &e[i].mask);
+
+        TRACE("semantic: %s, semantic idx: %u, unknown %#x, type %u, register idx: %u, use_mask %#x, input_mask %#x\n",
+                e[i].semantic_name, e[i].semantic_idx, e[i].unknown, e[i].component_type,
+                e[i].register_idx, (e[i].mask >> 8) & 0xff, e[i].mask & 0xff);
+    }
+
+    is->elements = e;
+    is->element_count = count;
+
+    return S_OK;
+}
+
+static HRESULT isgn_handler(const char *data, DWORD data_size, DWORD tag, void *ctx)
+{
+    struct input_signature *is = ctx;
+    const char *ptr = data;
+    char tag_str[5];
+
+    switch(tag)
+    {
+        case TAG_ISGN:
+            return parse_isgn(ptr, is);
+
+        default:
+            memcpy(tag_str, &tag, 4);
+            tag_str[4] = '\0';
+            FIXME("Unhandled chunk %s\n", tag_str);
+            return S_OK;
+    }
+}
+
+HRESULT d3d10_input_layout_to_wined3d_declaration(const D3D10_INPUT_ELEMENT_DESC *element_descs,
+        UINT element_count, const void *shader_byte_code, SIZE_T shader_byte_code_length,
+        WINED3DVERTEXELEMENT **wined3d_elements, UINT *wined3d_element_count)
+{
+    struct input_signature is;
+    HRESULT hr;
+    UINT i;
+
+    hr = parse_dxbc(shader_byte_code, shader_byte_code_length, isgn_handler, &is);
+    if (FAILED(hr))
+    {
+        ERR("Failed to parse input signature.\n");
+        return E_FAIL;
+    }
+
+    *wined3d_elements = HeapAlloc(GetProcessHeap(), 0, element_count * sizeof(**wined3d_elements));
+    if (!*wined3d_elements)
+    {
+        ERR("Failed to allocate wined3d vertex element array memory.\n");
+        HeapFree(GetProcessHeap(), 0, is.elements);
+        return E_OUTOFMEMORY;
+    }
+    *wined3d_element_count = 0;
+
+    for (i = 0; i < element_count; ++i)
+    {
+        UINT j;
+
+        for (j = 0; j < is.element_count; ++j)
+        {
+            if (!strcmp(element_descs[i].SemanticName, is.elements[j].semantic_name)
+                    && element_descs[i].SemanticIndex == is.elements[j].semantic_idx)
+            {
+                WINED3DVERTEXELEMENT *e = &(*wined3d_elements)[(*wined3d_element_count)++];
+                const D3D10_INPUT_ELEMENT_DESC *f = &element_descs[i];
+
+                e->format = wined3dformat_from_dxgi_format(f->Format);
+                e->input_slot = f->InputSlot;
+                e->offset = f->AlignedByteOffset;
+                e->output_slot = is.elements[j].register_idx;
+                e->method = WINED3DDECLMETHOD_DEFAULT;
+                e->usage = 0;
+                e->usage_idx = 0;
+
+                if (f->AlignedByteOffset == D3D10_APPEND_ALIGNED_ELEMENT)
+                    FIXME("D3D10_APPEND_ALIGNED_ELEMENT not supported\n");
+                if (f->InputSlotClass != D3D10_INPUT_PER_VERTEX_DATA)
+                    FIXME("Ignoring input slot class (%#x)\n", f->InputSlotClass);
+                if (f->InstanceDataStepRate)
+                    FIXME("Ignoring instace data step rate (%#x)\n", f->InstanceDataStepRate);
+
+                break;
+            }
+        }
+    }
+
+    HeapFree(GetProcessHeap(), 0, is.elements);
+
+    return S_OK;
+}
+
 /* IUnknown methods */
 
 static HRESULT STDMETHODCALLTYPE d3d10_input_layout_QueryInterface(ID3D10InputLayout *iface,
@@ -65,6 +203,7 @@ static ULONG STDMETHODCALLTYPE d3d10_input_layout_Release(ID3D10InputLayout *ifa
 
     if (!refcount)
     {
+        IWineD3DVertexDeclaration_Release(This->wined3d_decl);
         HeapFree(GetProcessHeap(), 0, This);
     }
 
-- 
1.6.0.6



--------------010705080409090603020602--



More information about the wine-patches mailing list