[PATCH 2/8] d3d11: Parse OSG5 output signatures.

Józef Kucia jkucia at codeweavers.com
Thu Apr 6 04:47:47 CDT 2017


Fixes geometry shaders compiled as gs_5_0.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 dlls/d3d11/d3d11_private.h |  6 ++++--
 dlls/d3d11/inputlayout.c   |  4 ++--
 dlls/d3d11/shader.c        | 40 ++++++++++++++++++++++++++++------------
 3 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h
index 6caca05..10709c4 100644
--- a/dlls/d3d11/d3d11_private.h
+++ b/dlls/d3d11/d3d11_private.h
@@ -47,6 +47,7 @@
 #define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C')
 #define TAG_ISGN MAKE_TAG('I', 'S', 'G', 'N')
 #define TAG_OSGN MAKE_TAG('O', 'S', 'G', 'N')
+#define TAG_OSG5 MAKE_TAG('O', 'S', 'G', '5')
 #define TAG_SHDR MAKE_TAG('S', 'H', 'D', 'R')
 #define TAG_SHEX MAKE_TAG('S', 'H', 'E', 'X')
 #define TAG_AON9 MAKE_TAG('A', 'o', 'n', '9')
@@ -358,9 +359,10 @@ HRESULT d3d11_compute_shader_create(struct d3d_device *device, const void *byte_
         struct d3d11_compute_shader **shader) DECLSPEC_HIDDEN;
 struct d3d11_compute_shader *unsafe_impl_from_ID3D11ComputeShader(ID3D11ComputeShader *iface) DECLSPEC_HIDDEN;
 
-HRESULT shader_parse_signature(const char *data, DWORD data_size, struct wined3d_shader_signature *s) DECLSPEC_HIDDEN;
+HRESULT shader_parse_signature(DWORD tag, const char *data, DWORD data_size,
+        struct wined3d_shader_signature *s) DECLSPEC_HIDDEN;
 struct wined3d_shader_signature_element *shader_find_signature_element(const struct wined3d_shader_signature *s,
-        const char *semantic_name, unsigned int semantic_idx) DECLSPEC_HIDDEN;
+        const char *semantic_name, unsigned int semantic_idx, unsigned int stream_idx) DECLSPEC_HIDDEN;
 void shader_free_signature(struct wined3d_shader_signature *s) DECLSPEC_HIDDEN;
 
 /* ID3D11ClassLinkage */
diff --git a/dlls/d3d11/inputlayout.c b/dlls/d3d11/inputlayout.c
index 1fdb2c3..e9c3094 100644
--- a/dlls/d3d11/inputlayout.c
+++ b/dlls/d3d11/inputlayout.c
@@ -36,7 +36,7 @@ static HRESULT isgn_handler(const char *data, DWORD data_size, DWORD tag, void *
         FIXME("Multiple input signatures.\n");
         shader_free_signature(is);
     }
-    return shader_parse_signature(data, data_size, is);
+    return shader_parse_signature(tag, data, data_size, is);
 }
 
 static HRESULT d3d11_input_layout_to_wined3d_declaration(const D3D11_INPUT_ELEMENT_DESC *element_descs,
@@ -77,7 +77,7 @@ static HRESULT d3d11_input_layout_to_wined3d_declaration(const D3D11_INPUT_ELEME
         e->usage = 0;
         e->usage_idx = 0;
 
-        if ((element = shader_find_signature_element(&is, f->SemanticName, f->SemanticIndex)))
+        if ((element = shader_find_signature_element(&is, f->SemanticName, f->SemanticIndex, 0)))
             e->output_slot = element->register_idx;
         else
             WARN("Unused input element %u.\n", i);
diff --git a/dlls/d3d11/shader.c b/dlls/d3d11/shader.c
index d1b3e38..420a47d 100644
--- a/dlls/d3d11/shader.c
+++ b/dlls/d3d11/shader.c
@@ -52,17 +52,28 @@ static HRESULT shdr_handler(const char *data, DWORD data_size, DWORD tag, void *
                 TRACE("Skipping shader input signature on feature level %#x.\n", ctx->feature_level);
                 break;
             }
-            if (FAILED(hr = shader_parse_signature(data, data_size, &desc->input_signature)))
+            if (desc->input_signature.elements)
+            {
+                FIXME("Multiple input signatures.\n");
+                break;
+            }
+            if (FAILED(hr = shader_parse_signature(tag, data, data_size, &desc->input_signature)))
                 return hr;
             break;
 
         case TAG_OSGN:
+        case TAG_OSG5:
             if (ctx->feature_level <= D3D_FEATURE_LEVEL_9_3)
             {
                 TRACE("Skipping shader output signature on feature level %#x.\n", ctx->feature_level);
                 break;
             }
-            if (FAILED(hr = shader_parse_signature(data, data_size, &desc->output_signature)))
+            if (desc->output_signature.elements)
+            {
+                FIXME("Multiple output signatures.\n");
+                break;
+            }
+            if (FAILED(hr = shader_parse_signature(tag, data, data_size, &desc->output_signature)))
                 return hr;
             break;
 
@@ -167,7 +178,8 @@ static const char *shader_get_string(const char *data, size_t data_size, DWORD o
     return data + offset;
 }
 
-HRESULT shader_parse_signature(const char *data, DWORD data_size, struct wined3d_shader_signature *s)
+HRESULT shader_parse_signature(DWORD tag, const char *data, DWORD data_size,
+        struct wined3d_shader_signature *s)
 {
     struct wined3d_shader_signature_element *e;
     const char *ptr = data;
@@ -181,7 +193,7 @@ HRESULT shader_parse_signature(const char *data, DWORD data_size, struct wined3d
     }
 
     read_dword(&ptr, &count);
-    TRACE("%u elements\n", count);
+    TRACE("%u elements.\n", count);
 
     skip_dword_unknown(&ptr, 1); /* It seems to always be 0x00000008. */
 
@@ -199,9 +211,12 @@ HRESULT shader_parse_signature(const char *data, DWORD data_size, struct wined3d
 
     for (i = 0; i < count; ++i)
     {
-        UINT name_offset;
+        DWORD name_offset;
 
-        e[i].stream_idx = 0;
+        if (tag == TAG_OSG5)
+            read_dword(&ptr, &e[i].stream_idx);
+        else
+            e[i].stream_idx = 0;
         read_dword(&ptr, &name_offset);
         if (!(e[i].semantic_name = shader_get_string(data, data_size, name_offset)))
         {
@@ -215,9 +230,9 @@ HRESULT shader_parse_signature(const char *data, DWORD data_size, struct wined3d
         read_dword(&ptr, &e[i].register_idx);
         read_dword(&ptr, &e[i].mask);
 
-        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].semantic_name), e[i].semantic_idx, e[i].sysval_semantic,
+        TRACE("Stream: %u, semantic: %s, semantic idx: %u, sysval_semantic %#x, "
+                "type %u, register idx: %u, use_mask %#x, input_mask %#x.\n",
+                e[i].stream_idx, debugstr_a(e[i].semantic_name), e[i].semantic_idx, e[i].sysval_semantic,
                 e[i].component_type, e[i].register_idx, (e[i].mask >> 8) & 0xff, e[i].mask & 0xff);
     }
 
@@ -228,14 +243,15 @@ HRESULT shader_parse_signature(const char *data, DWORD data_size, struct wined3d
 }
 
 struct wined3d_shader_signature_element *shader_find_signature_element(const struct wined3d_shader_signature *s,
-        const char *semantic_name, unsigned int semantic_idx)
+        const char *semantic_name, unsigned int semantic_idx, unsigned int stream_idx)
 {
     struct wined3d_shader_signature_element *e = s->elements;
     unsigned int i;
 
     for (i = 0; i < s->element_count; ++i)
     {
-        if (!strcasecmp(e[i].semantic_name, semantic_name) && e[i].semantic_idx == semantic_idx)
+        if (!strcasecmp(e[i].semantic_name, semantic_name) && e[i].semantic_idx == semantic_idx
+                && e[i].stream_idx == stream_idx)
             return &e[i];
     }
 
@@ -1248,7 +1264,7 @@ static HRESULT wined3d_so_elements_from_d3d11_so_entries(struct wined3d_stream_o
 
             e->register_idx = WINED3D_STREAM_OUTPUT_GAP;
         }
-        else if ((output = shader_find_signature_element(os, f->SemanticName, f->SemanticIndex)))
+        else if ((output = shader_find_signature_element(os, f->SemanticName, f->SemanticIndex, f->Stream)))
         {
             if (e->component_idx > 3 || e->component_count > 4 || !e->component_count
                     || e->component_idx + e->component_count > 4)
-- 
2.10.2




More information about the wine-patches mailing list