Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/d3d11/shader.c | 264 ++++++++++------------------------------------------ 1 file changed, 49 insertions(+), 215 deletions(-)
diff --git a/dlls/d3d11/shader.c b/dlls/d3d11/shader.c index a1da9effc2b8..4b4969135387 100644 --- a/dlls/d3d11/shader.c +++ b/dlls/d3d11/shader.c @@ -24,156 +24,19 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
-struct aon9_header +static HRESULT osgn_handler(const char *data, DWORD data_size, DWORD tag, void *context) { - DWORD chunk_size; - DWORD shader_version; - DWORD unknown; - DWORD byte_code_offset; -}; - -struct shader_handler_context -{ - D3D_FEATURE_LEVEL feature_level; - struct wined3d_shader_desc *desc; -}; - -static HRESULT shdr_handler(const char *data, DWORD data_size, DWORD tag, void *context) -{ - const struct shader_handler_context *ctx = context; - struct wined3d_shader_desc *desc = ctx->desc; - HRESULT hr; - - switch (tag) - { - case TAG_ISGN: - if (ctx->feature_level <= D3D_FEATURE_LEVEL_9_3) - { - TRACE("Skipping shader input signature on feature level %#x.\n", ctx->feature_level); - break; - } - 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 (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; - - 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) - { - TRACE("Skipping SM4+ shader code on feature level %#x.\n", ctx->feature_level); - break; - } - if (desc->byte_code) - FIXME("Multiple shader code chunks.\n"); - desc->byte_code = (const DWORD *)data; - desc->byte_code_size = data_size; - desc->format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM4; - break; - - case TAG_AON9: - if (ctx->feature_level <= D3D_FEATURE_LEVEL_9_3) - { - const struct aon9_header *header = (const struct aon9_header *)data; - unsigned int unknown_dword_count; - const char *byte_code; - - if (data_size < sizeof(*header)) - { - WARN("Invalid Aon9 data size %#x.\n", data_size); - return E_FAIL; - } - byte_code = data + header->byte_code_offset; - unknown_dword_count = (header->byte_code_offset - sizeof(*header)) / sizeof(DWORD); - - if (data_size - 2 * sizeof(DWORD) < header->byte_code_offset) - { - WARN("Invalid byte code offset %#x (size %#x).\n", header->byte_code_offset, data_size); - return E_FAIL; - } - FIXME("Skipping %u unknown DWORDs.\n", unknown_dword_count); - - if (desc->byte_code) - FIXME("Multiple shader code chunks.\n"); - desc->byte_code = (const DWORD *)byte_code; - desc->byte_code_size = data_size - header->byte_code_offset; - desc->format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM1; - TRACE("Feature level 9 shader version 0%08x, 0%08x.\n", header->shader_version, *desc->byte_code); - } - else - { - TRACE("Skipping feature level 9 shader code on feature level %#x.\n", ctx->feature_level); - } - break; - - default: - TRACE("Skipping chunk %s.\n", debugstr_an((const char *)&tag, 4)); - break; - } - - return S_OK; -} - -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; - - desc->byte_code = NULL; - 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)); + struct wined3d_shader_signature *signature = context;
- hr = parse_dxbc(dxbc, dxbc_length, shdr_handler, &ctx); - if (!desc->byte_code) - hr = E_INVALIDARG; + if (tag != TAG_OSGN && tag != TAG_OSG5) + return S_OK;
- if (FAILED(hr)) + if (signature->elements) { - FIXME("Failed to parse shader, hr %#x.\n", hr); - free_shader_desc(desc); + FIXME("Multiple input signatures.\n"); + shader_free_signature(signature); } - - return hr; + return shader_parse_signature(tag, data, data_size, signature); }
static const char *shader_get_string(const char *data, size_t data_size, DWORD offset) @@ -529,18 +392,11 @@ static HRESULT d3d_vertex_shader_init(struct d3d_vertex_shader *shader, struct d wined3d_mutex_lock(); wined3d_private_store_init(&shader->private_store);
- if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level))) - { - WARN("Failed to extract shader, hr %#x.\n", hr); - wined3d_private_store_cleanup(&shader->private_store); - wined3d_mutex_unlock(); - return hr; - } - - hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader, - &d3d_vertex_shader_wined3d_parent_ops, &shader->wined3d_shader); - free_shader_desc(&desc); - if (FAILED(hr)) + desc.byte_code = byte_code; + desc.byte_code_size = byte_code_length; + desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_DXBC; + if (FAILED(hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader, + &d3d_vertex_shader_wined3d_parent_ops, &shader->wined3d_shader))) { WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr); wined3d_private_store_cleanup(&shader->private_store); @@ -740,18 +596,11 @@ static HRESULT d3d11_hull_shader_init(struct d3d11_hull_shader *shader, struct d wined3d_mutex_lock(); wined3d_private_store_init(&shader->private_store);
- if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level))) - { - WARN("Failed to extract shader, hr %#x.\n", hr); - wined3d_private_store_cleanup(&shader->private_store); - wined3d_mutex_unlock(); - return hr; - } - - hr = wined3d_shader_create_hs(device->wined3d_device, &desc, shader, - &d3d11_hull_shader_wined3d_parent_ops, &shader->wined3d_shader); - free_shader_desc(&desc); - if (FAILED(hr)) + desc.byte_code = byte_code; + desc.byte_code_size = byte_code_length; + desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_DXBC; + if (FAILED(hr = wined3d_shader_create_hs(device->wined3d_device, &desc, shader, + &d3d11_hull_shader_wined3d_parent_ops, &shader->wined3d_shader))) { WARN("Failed to create wined3d hull shader, hr %#x.\n", hr); wined3d_private_store_cleanup(&shader->private_store); @@ -941,18 +790,11 @@ static HRESULT d3d11_domain_shader_init(struct d3d11_domain_shader *shader, stru wined3d_mutex_lock(); wined3d_private_store_init(&shader->private_store);
- if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level))) - { - WARN("Failed to extract shader, hr %#x.\n", hr); - wined3d_private_store_cleanup(&shader->private_store); - wined3d_mutex_unlock(); - return hr; - } - - hr = wined3d_shader_create_ds(device->wined3d_device, &desc, shader, - &d3d11_domain_shader_wined3d_parent_ops, &shader->wined3d_shader); - free_shader_desc(&desc); - if (FAILED(hr)) + desc.byte_code = byte_code; + desc.byte_code_size = byte_code_length; + desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_DXBC; + if (FAILED(hr = wined3d_shader_create_ds(device->wined3d_device, &desc, shader, + &d3d11_domain_shader_wined3d_parent_ops, &shader->wined3d_shader))) { WARN("Failed to create wined3d domain shader, hr %#x.\n", hr); wined3d_private_store_cleanup(&shader->private_store); @@ -1412,6 +1254,7 @@ static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader, unsigned int rasterizer_stream) { struct wined3d_stream_output_desc so_desc; + struct wined3d_shader_signature signature; struct wined3d_shader_desc desc; unsigned int i; HRESULT hr; @@ -1448,11 +1291,9 @@ static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader, } }
- if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level))) - { - WARN("Failed to extract shader, hr %#x.\n", hr); - return hr; - } + desc.byte_code = byte_code; + desc.byte_code_size = byte_code_length; + desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_DXBC;
memset(&so_desc, 0, sizeof(so_desc)); if (so_entries) @@ -1466,15 +1307,23 @@ static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader, if (!(so_desc.elements = heap_calloc(so_entry_count, sizeof(*so_desc.elements)))) { ERR("Failed to allocate wined3d stream output element array memory.\n"); - free_shader_desc(&desc); return E_OUTOFMEMORY; } - if (FAILED(hr = wined3d_so_elements_from_d3d11_so_entries(so_desc.elements, + + memset(&signature, 0, sizeof(signature)); + if (FAILED(hr = parse_dxbc(byte_code, byte_code_length, osgn_handler, &signature))) + { + ERR("Failed to parse input signature.\n"); + heap_free(so_desc.elements); + return E_FAIL; + } + hr = wined3d_so_elements_from_d3d11_so_entries(so_desc.elements, so_entries, so_entry_count, buffer_strides, buffer_stride_count, - &desc.output_signature, device->feature_level))) + &signature, device->feature_level); + shader_free_signature(&signature); + if (FAILED(hr)) { heap_free(so_desc.elements); - free_shader_desc(&desc); return hr; } } @@ -1488,7 +1337,6 @@ 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); heap_free(so_desc.elements); - free_shader_desc(&desc); if (FAILED(hr)) { WARN("Failed to create wined3d geometry shader, hr %#x.\n", hr); @@ -1795,18 +1643,11 @@ static HRESULT d3d_pixel_shader_init(struct d3d_pixel_shader *shader, struct d3d wined3d_mutex_lock(); wined3d_private_store_init(&shader->private_store);
- if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level))) - { - WARN("Failed to extract shader, hr %#x.\n", hr); - wined3d_private_store_cleanup(&shader->private_store); - wined3d_mutex_unlock(); - return hr; - } - - hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader, - &d3d_pixel_shader_wined3d_parent_ops, &shader->wined3d_shader); - free_shader_desc(&desc); - if (FAILED(hr)) + desc.byte_code = byte_code; + desc.byte_code_size = byte_code_length; + desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_DXBC; + if (FAILED(hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader, + &d3d_pixel_shader_wined3d_parent_ops, &shader->wined3d_shader))) { WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr); wined3d_private_store_cleanup(&shader->private_store); @@ -2004,18 +1845,11 @@ static HRESULT d3d11_compute_shader_init(struct d3d11_compute_shader *shader, st wined3d_mutex_lock(); wined3d_private_store_init(&shader->private_store);
- if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level))) - { - WARN("Failed to extract shader, hr %#x.\n", hr); - wined3d_private_store_cleanup(&shader->private_store); - wined3d_mutex_unlock(); - return hr; - } - - hr = wined3d_shader_create_cs(device->wined3d_device, &desc, shader, - &d3d11_compute_shader_wined3d_parent_ops, &shader->wined3d_shader); - free_shader_desc(&desc); - if (FAILED(hr)) + desc.byte_code = byte_code; + desc.byte_code_size = byte_code_length; + desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_DXBC; + if (FAILED(hr = wined3d_shader_create_cs(device->wined3d_device, &desc, shader, + &d3d11_compute_shader_wined3d_parent_ops, &shader->wined3d_shader))) { WARN("Failed to create wined3d compute shader, hr %#x.\n", hr); wined3d_private_store_cleanup(&shader->private_store);