[PATCH v2 1/6] wined3d: Add support for patch constant signatures.

Józef Kucia jkucia at codeweavers.com
Fri May 12 08:09:17 CDT 2017


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---

Version 2: Make sure to not overflow "total".

---
 dlls/d3d11/d3d11_private.h     |  1 +
 dlls/d3d11/inputlayout.c       |  2 +-
 dlls/d3d11/shader.c            | 49 ++++++++++++++++++++++---------------
 dlls/d3d8/shader.c             |  2 ++
 dlls/d3d9/shader.c             |  2 ++
 dlls/wined3d/shader.c          | 55 ++++++++++++++++++++++++++----------------
 dlls/wined3d/wined3d_private.h |  1 +
 include/wine/wined3d.h         |  1 +
 8 files changed, 71 insertions(+), 42 deletions(-)

diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h
index b86486e..3f6622f 100644
--- a/dlls/d3d11/d3d11_private.h
+++ b/dlls/d3d11/d3d11_private.h
@@ -48,6 +48,7 @@
 #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_PCSG MAKE_TAG('P', 'C', 'S', 'G')
 #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')
diff --git a/dlls/d3d11/inputlayout.c b/dlls/d3d11/inputlayout.c
index 37b6993..2f194e0 100644
--- a/dlls/d3d11/inputlayout.c
+++ b/dlls/d3d11/inputlayout.c
@@ -57,7 +57,7 @@ static HRESULT d3d11_input_layout_to_wined3d_declaration(const D3D11_INPUT_ELEME
     if (!(*wined3d_elements = d3d11_calloc(element_count, sizeof(**wined3d_elements))))
     {
         ERR("Failed to allocate wined3d vertex element array memory.\n");
-        HeapFree(GetProcessHeap(), 0, is.elements);
+        shader_free_signature(&is);
         return E_OUTOFMEMORY;
     }
 
diff --git a/dlls/d3d11/shader.c b/dlls/d3d11/shader.c
index 3699851..bd9eb66 100644
--- a/dlls/d3d11/shader.c
+++ b/dlls/d3d11/shader.c
@@ -77,6 +77,16 @@ static HRESULT shdr_handler(const char *data, DWORD data_size, DWORD tag, void *
                 return hr;
             break;
 
+        case TAG_PCSG:
+            if (desc->patch_constant_signature.elements)
+            {
+                FIXME("Multiple patch constant signatures.\n");
+                break;
+            }
+            if (FAILED(hr = shader_parse_signature(tag, data, data_size, &desc->patch_constant_signature)))
+                return hr;
+            break;
+
         case TAG_SHDR:
         case TAG_SHEX:
             if (ctx->feature_level <= D3D_FEATURE_LEVEL_9_3)
@@ -134,8 +144,15 @@ static HRESULT shdr_handler(const char *data, DWORD data_size, DWORD tag, void *
     return S_OK;
 }
 
-static HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, struct wined3d_shader_desc *desc,
-        D3D_FEATURE_LEVEL feature_level)
+static void free_shader_desc(struct wined3d_shader_desc *desc)
+{
+    shader_free_signature(&desc->input_signature);
+    shader_free_signature(&desc->output_signature);
+    shader_free_signature(&desc->patch_constant_signature);
+}
+
+static HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length,
+        struct wined3d_shader_desc *desc, D3D_FEATURE_LEVEL feature_level)
 {
     struct shader_handler_context ctx = {feature_level, desc};
     HRESULT hr;
@@ -144,6 +161,7 @@ static HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, st
     desc->byte_code_size = 0;
     memset(&desc->input_signature, 0, sizeof(desc->input_signature));
     memset(&desc->output_signature, 0, sizeof(desc->output_signature));
+    memset(&desc->patch_constant_signature, 0, sizeof(desc->patch_constant_signature));
 
     hr = parse_dxbc(dxbc, dxbc_length, shdr_handler, &ctx);
     if (!desc->byte_code)
@@ -152,8 +170,7 @@ static HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, st
     if (FAILED(hr))
     {
         FIXME("Failed to parse shader, hr %#x.\n", hr);
-        shader_free_signature(&desc->input_signature);
-        shader_free_signature(&desc->output_signature);
+        free_shader_desc(desc);
     }
 
     return hr;
@@ -544,8 +561,7 @@ static HRESULT d3d_vertex_shader_init(struct d3d_vertex_shader *shader, struct d
 
     hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader,
             &d3d_vertex_shader_wined3d_parent_ops, &shader->wined3d_shader);
-    shader_free_signature(&desc.input_signature);
-    shader_free_signature(&desc.output_signature);
+    free_shader_desc(&desc);
     if (FAILED(hr))
     {
         WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr);
@@ -758,8 +774,7 @@ static HRESULT d3d11_hull_shader_init(struct d3d11_hull_shader *shader, struct d
 
     hr = wined3d_shader_create_hs(device->wined3d_device, &desc, shader,
             &d3d11_hull_shader_wined3d_parent_ops, &shader->wined3d_shader);
-    shader_free_signature(&desc.input_signature);
-    shader_free_signature(&desc.output_signature);
+    free_shader_desc(&desc);
     if (FAILED(hr))
     {
         WARN("Failed to create wined3d hull shader, hr %#x.\n", hr);
@@ -962,8 +977,7 @@ static HRESULT d3d11_domain_shader_init(struct d3d11_domain_shader *shader, stru
 
     hr = wined3d_shader_create_ds(device->wined3d_device, &desc, shader,
             &d3d11_domain_shader_wined3d_parent_ops, &shader->wined3d_shader);
-    shader_free_signature(&desc.input_signature);
-    shader_free_signature(&desc.output_signature);
+    free_shader_desc(&desc);
     if (FAILED(hr))
     {
         WARN("Failed to create wined3d domain shader, hr %#x.\n", hr);
@@ -1480,8 +1494,7 @@ static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader,
         if (!(so_desc.elements = d3d11_calloc(so_entry_count, sizeof(*so_desc.elements))))
         {
             ERR("Failed to allocate wined3d stream output element array memory.\n");
-            shader_free_signature(&desc.input_signature);
-            shader_free_signature(&desc.output_signature);
+            free_shader_desc(&desc);
             return E_OUTOFMEMORY;
         }
         if (FAILED(hr = wined3d_so_elements_from_d3d11_so_entries(so_desc.elements,
@@ -1489,8 +1502,7 @@ static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader,
                 &desc.output_signature, device->feature_level)))
         {
             HeapFree(GetProcessHeap(), 0, so_desc.elements);
-            shader_free_signature(&desc.input_signature);
-            shader_free_signature(&desc.output_signature);
+            free_shader_desc(&desc);
             return hr;
         }
     }
@@ -1504,8 +1516,7 @@ static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader,
     hr = wined3d_shader_create_gs(device->wined3d_device, &desc, so_entries ? &so_desc : NULL,
             shader, &d3d_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader);
     HeapFree(GetProcessHeap(), 0, so_desc.elements);
-    shader_free_signature(&desc.input_signature);
-    shader_free_signature(&desc.output_signature);
+    free_shader_desc(&desc);
     if (FAILED(hr))
     {
         WARN("Failed to create wined3d geometry shader, hr %#x.\n", hr);
@@ -1824,8 +1835,7 @@ static HRESULT d3d_pixel_shader_init(struct d3d_pixel_shader *shader, struct d3d
 
     hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader,
             &d3d_pixel_shader_wined3d_parent_ops, &shader->wined3d_shader);
-    shader_free_signature(&desc.input_signature);
-    shader_free_signature(&desc.output_signature);
+    free_shader_desc(&desc);
     if (FAILED(hr))
     {
         WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr);
@@ -2036,8 +2046,7 @@ static HRESULT d3d11_compute_shader_init(struct d3d11_compute_shader *shader, st
 
     hr = wined3d_shader_create_cs(device->wined3d_device, &desc, shader,
             &d3d11_compute_shader_wined3d_parent_ops, &shader->wined3d_shader);
-    shader_free_signature(&desc.input_signature);
-    shader_free_signature(&desc.output_signature);
+    free_shader_desc(&desc);
     if (FAILED(hr))
     {
         WARN("Failed to create wined3d compute shader, hr %#x.\n", hr);
diff --git a/dlls/d3d8/shader.c b/dlls/d3d8/shader.c
index ee78b7c..093cb5a 100644
--- a/dlls/d3d8/shader.c
+++ b/dlls/d3d8/shader.c
@@ -121,6 +121,7 @@ HRESULT d3d8_vertex_shader_init(struct d3d8_vertex_shader *shader, struct d3d8_d
         desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM1;
         desc.input_signature.element_count = 0;
         desc.output_signature.element_count = 0;
+        desc.patch_constant_signature.element_count = 0;
         desc.max_version = 1;
 
         wined3d_mutex_lock();
@@ -172,6 +173,7 @@ HRESULT d3d8_pixel_shader_init(struct d3d8_pixel_shader *shader, struct d3d8_dev
     desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM1;
     desc.input_signature.element_count = 0;
     desc.output_signature.element_count = 0;
+    desc.patch_constant_signature.element_count = 0;
     desc.max_version = 1;
 
     wined3d_mutex_lock();
diff --git a/dlls/d3d9/shader.c b/dlls/d3d9/shader.c
index 05f21e4..8aa3eaa 100644
--- a/dlls/d3d9/shader.c
+++ b/dlls/d3d9/shader.c
@@ -147,6 +147,7 @@ HRESULT vertexshader_init(struct d3d9_vertexshader *shader, struct d3d9_device *
     desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM1;
     desc.input_signature.element_count = 0;
     desc.output_signature.element_count = 0;
+    desc.patch_constant_signature.element_count = 0;
     desc.max_version = 3;
 
     wined3d_mutex_lock();
@@ -300,6 +301,7 @@ HRESULT pixelshader_init(struct d3d9_pixelshader *shader, struct d3d9_device *de
     desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM1;
     desc.input_signature.element_count = 0;
     desc.output_signature.element_count = 0;
+    desc.patch_constant_signature.element_count = 0;
     desc.max_version = 3;
 
     wined3d_mutex_lock();
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index c83ef1f..5717767 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -2843,6 +2843,7 @@ static void shader_cleanup(struct wined3d_shader *shader)
     if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY)
         HeapFree(GetProcessHeap(), 0, shader->u.gs.so_desc.elements);
 
+    HeapFree(GetProcessHeap(), 0, shader->patch_constant_signature.elements);
     HeapFree(GetProcessHeap(), 0, shader->output_signature.elements);
     HeapFree(GetProcessHeap(), 0, shader->input_signature.elements);
     HeapFree(GetProcessHeap(), 0, shader->signature_strings);
@@ -3251,6 +3252,25 @@ BOOL vshader_get_input(const struct wined3d_shader *shader,
     return FALSE;
 }
 
+static HRESULT shader_signature_calculate_strings_length(const struct wined3d_shader_signature *signature,
+        SIZE_T *total)
+{
+    struct wined3d_shader_signature_element *e;
+    unsigned int i;
+    SIZE_T len;
+
+    for (i = 0; i < signature->element_count; ++i)
+    {
+        e = &signature->elements[i];
+        len = strlen(e->semantic_name);
+        if (len >= ~(SIZE_T)0 - *total)
+            return E_OUTOFMEMORY;
+
+        *total += len + 1;
+    }
+    return WINED3D_OK;
+}
+
 static HRESULT shader_signature_copy(struct wined3d_shader_signature *dst,
         const struct wined3d_shader_signature *src, char **signature_strings)
 {
@@ -3288,10 +3308,8 @@ static HRESULT shader_init(struct wined3d_shader *shader, struct wined3d_device
         const struct wined3d_shader_desc *desc, DWORD float_const_count, enum wined3d_shader_type type,
         void *parent, const struct wined3d_parent_ops *parent_ops)
 {
-    struct wined3d_shader_signature_element *e;
     size_t byte_code_size;
-    SIZE_T total, len;
-    unsigned int i;
+    SIZE_T total;
     HRESULT hr;
     char *ptr;
 
@@ -3313,24 +3331,12 @@ static HRESULT shader_init(struct wined3d_shader *shader, struct wined3d_device
     shader->parent_ops = parent_ops;
 
     total = 0;
-    for (i = 0; i < desc->input_signature.element_count; ++i)
-    {
-        e = &desc->input_signature.elements[i];
-        len = strlen(e->semantic_name);
-        if (len >= ~(SIZE_T)0 - total)
-            return E_OUTOFMEMORY;
-
-        total += len + 1;
-    }
-    for (i = 0; i < desc->output_signature.element_count; ++i)
-    {
-        e = &desc->output_signature.elements[i];
-        len = strlen(e->semantic_name);
-        if (len >= ~(SIZE_T)0 - total)
-            return E_OUTOFMEMORY;
-
-        total += len + 1;
-    }
+    if (FAILED(hr = shader_signature_calculate_strings_length(&desc->input_signature, &total)))
+        return hr;
+    if (FAILED(hr = shader_signature_calculate_strings_length(&desc->output_signature, &total)))
+        return hr;
+    if (FAILED(hr = shader_signature_calculate_strings_length(&desc->patch_constant_signature, &total)))
+        return hr;
     if (total && !(shader->signature_strings = HeapAlloc(GetProcessHeap(), 0, total)))
         return E_OUTOFMEMORY;
     ptr = shader->signature_strings;
@@ -3346,6 +3352,13 @@ static HRESULT shader_init(struct wined3d_shader *shader, struct wined3d_device
         HeapFree(GetProcessHeap(), 0, shader->signature_strings);
         return hr;
     }
+    if (FAILED(hr = shader_signature_copy(&shader->patch_constant_signature, &desc->patch_constant_signature, &ptr)))
+    {
+        HeapFree(GetProcessHeap(), 0, shader->output_signature.elements);
+        HeapFree(GetProcessHeap(), 0, shader->input_signature.elements);
+        HeapFree(GetProcessHeap(), 0, shader->signature_strings);
+        return hr;
+    }
 
     list_init(&shader->linked_programs);
     list_init(&shader->constantsF);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index f8ed9aa..e68f03a 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3739,6 +3739,7 @@ struct wined3d_shader
 
     struct wined3d_shader_signature input_signature;
     struct wined3d_shader_signature output_signature;
+    struct wined3d_shader_signature patch_constant_signature;
     char *signature_strings;
 
     /* Pointer to the parent device */
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 4c0f47d..96de6f9 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -1991,6 +1991,7 @@ struct wined3d_shader_desc
     enum wined3d_shader_byte_code_format format;
     struct wined3d_shader_signature input_signature;
     struct wined3d_shader_signature output_signature;
+    struct wined3d_shader_signature patch_constant_signature;
     unsigned int max_version;
 };
 
-- 
2.10.2




More information about the wine-patches mailing list