[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