wined3d: Add support for patch constant signatures.

Signed-off-by: Józef Kucia <jkucia@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Józef Kucia 2017-05-12 15:09:17 +02:00 committed by Alexandre Julliard
parent 35483da628
commit 487d2e0279
8 changed files with 71 additions and 42 deletions

View File

@ -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')

View File

@ -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;
}

View File

@ -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);

View File

@ -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();

View File

@ -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();

View File

@ -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);

View File

@ -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 */

View File

@ -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;
};