d3d11: Pass full DXBC to wined3d.
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:
parent
72ea1419d5
commit
800720dad2
|
@ -24,156 +24,19 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
|
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;
|
struct wined3d_shader_signature *signature = context;
|
||||||
DWORD shader_version;
|
|
||||||
DWORD unknown;
|
|
||||||
DWORD byte_code_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct shader_handler_context
|
if (tag != TAG_OSGN && tag != TAG_OSG5)
|
||||||
{
|
return S_OK;
|
||||||
D3D_FEATURE_LEVEL feature_level;
|
|
||||||
struct wined3d_shader_desc *desc;
|
|
||||||
};
|
|
||||||
|
|
||||||
static HRESULT shdr_handler(const char *data, DWORD data_size, DWORD tag, void *context)
|
if (signature->elements)
|
||||||
{
|
|
||||||
const struct shader_handler_context *ctx = context;
|
|
||||||
struct wined3d_shader_desc *desc = ctx->desc;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
switch (tag)
|
|
||||||
{
|
{
|
||||||
case TAG_ISGN:
|
FIXME("Multiple input signatures.\n");
|
||||||
if (ctx->feature_level <= D3D_FEATURE_LEVEL_9_3)
|
shader_free_signature(signature);
|
||||||
{
|
|
||||||
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 shader_parse_signature(tag, data, data_size, signature);
|
||||||
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));
|
|
||||||
|
|
||||||
hr = parse_dxbc(dxbc, dxbc_length, shdr_handler, &ctx);
|
|
||||||
if (!desc->byte_code)
|
|
||||||
hr = E_INVALIDARG;
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
FIXME("Failed to parse shader, hr %#x.\n", hr);
|
|
||||||
free_shader_desc(desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *shader_get_string(const char *data, size_t data_size, DWORD offset)
|
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_mutex_lock();
|
||||||
wined3d_private_store_init(&shader->private_store);
|
wined3d_private_store_init(&shader->private_store);
|
||||||
|
|
||||||
if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
|
desc.byte_code = byte_code;
|
||||||
{
|
desc.byte_code_size = byte_code_length;
|
||||||
WARN("Failed to extract shader, hr %#x.\n", hr);
|
desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_DXBC;
|
||||||
wined3d_private_store_cleanup(&shader->private_store);
|
if (FAILED(hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader,
|
||||||
wined3d_mutex_unlock();
|
&d3d_vertex_shader_wined3d_parent_ops, &shader->wined3d_shader)))
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr);
|
WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr);
|
||||||
wined3d_private_store_cleanup(&shader->private_store);
|
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_mutex_lock();
|
||||||
wined3d_private_store_init(&shader->private_store);
|
wined3d_private_store_init(&shader->private_store);
|
||||||
|
|
||||||
if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
|
desc.byte_code = byte_code;
|
||||||
{
|
desc.byte_code_size = byte_code_length;
|
||||||
WARN("Failed to extract shader, hr %#x.\n", hr);
|
desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_DXBC;
|
||||||
wined3d_private_store_cleanup(&shader->private_store);
|
if (FAILED(hr = wined3d_shader_create_hs(device->wined3d_device, &desc, shader,
|
||||||
wined3d_mutex_unlock();
|
&d3d11_hull_shader_wined3d_parent_ops, &shader->wined3d_shader)))
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
WARN("Failed to create wined3d hull shader, hr %#x.\n", hr);
|
WARN("Failed to create wined3d hull shader, hr %#x.\n", hr);
|
||||||
wined3d_private_store_cleanup(&shader->private_store);
|
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_mutex_lock();
|
||||||
wined3d_private_store_init(&shader->private_store);
|
wined3d_private_store_init(&shader->private_store);
|
||||||
|
|
||||||
if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
|
desc.byte_code = byte_code;
|
||||||
{
|
desc.byte_code_size = byte_code_length;
|
||||||
WARN("Failed to extract shader, hr %#x.\n", hr);
|
desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_DXBC;
|
||||||
wined3d_private_store_cleanup(&shader->private_store);
|
if (FAILED(hr = wined3d_shader_create_ds(device->wined3d_device, &desc, shader,
|
||||||
wined3d_mutex_unlock();
|
&d3d11_domain_shader_wined3d_parent_ops, &shader->wined3d_shader)))
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
WARN("Failed to create wined3d domain shader, hr %#x.\n", hr);
|
WARN("Failed to create wined3d domain shader, hr %#x.\n", hr);
|
||||||
wined3d_private_store_cleanup(&shader->private_store);
|
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)
|
unsigned int rasterizer_stream)
|
||||||
{
|
{
|
||||||
struct wined3d_stream_output_desc so_desc;
|
struct wined3d_stream_output_desc so_desc;
|
||||||
|
struct wined3d_shader_signature signature;
|
||||||
struct wined3d_shader_desc desc;
|
struct wined3d_shader_desc desc;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
HRESULT hr;
|
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)))
|
desc.byte_code = byte_code;
|
||||||
{
|
desc.byte_code_size = byte_code_length;
|
||||||
WARN("Failed to extract shader, hr %#x.\n", hr);
|
desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_DXBC;
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&so_desc, 0, sizeof(so_desc));
|
memset(&so_desc, 0, sizeof(so_desc));
|
||||||
if (so_entries)
|
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))))
|
if (!(so_desc.elements = heap_calloc(so_entry_count, sizeof(*so_desc.elements))))
|
||||||
{
|
{
|
||||||
ERR("Failed to allocate wined3d stream output element array memory.\n");
|
ERR("Failed to allocate wined3d stream output element array memory.\n");
|
||||||
free_shader_desc(&desc);
|
|
||||||
return E_OUTOFMEMORY;
|
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,
|
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);
|
heap_free(so_desc.elements);
|
||||||
free_shader_desc(&desc);
|
|
||||||
return hr;
|
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,
|
hr = wined3d_shader_create_gs(device->wined3d_device, &desc, so_entries ? &so_desc : NULL,
|
||||||
shader, &d3d_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader);
|
shader, &d3d_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader);
|
||||||
heap_free(so_desc.elements);
|
heap_free(so_desc.elements);
|
||||||
free_shader_desc(&desc);
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
WARN("Failed to create wined3d geometry shader, hr %#x.\n", 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_mutex_lock();
|
||||||
wined3d_private_store_init(&shader->private_store);
|
wined3d_private_store_init(&shader->private_store);
|
||||||
|
|
||||||
if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
|
desc.byte_code = byte_code;
|
||||||
{
|
desc.byte_code_size = byte_code_length;
|
||||||
WARN("Failed to extract shader, hr %#x.\n", hr);
|
desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_DXBC;
|
||||||
wined3d_private_store_cleanup(&shader->private_store);
|
if (FAILED(hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader,
|
||||||
wined3d_mutex_unlock();
|
&d3d_pixel_shader_wined3d_parent_ops, &shader->wined3d_shader)))
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr);
|
WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr);
|
||||||
wined3d_private_store_cleanup(&shader->private_store);
|
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_mutex_lock();
|
||||||
wined3d_private_store_init(&shader->private_store);
|
wined3d_private_store_init(&shader->private_store);
|
||||||
|
|
||||||
if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
|
desc.byte_code = byte_code;
|
||||||
{
|
desc.byte_code_size = byte_code_length;
|
||||||
WARN("Failed to extract shader, hr %#x.\n", hr);
|
desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_DXBC;
|
||||||
wined3d_private_store_cleanup(&shader->private_store);
|
if (FAILED(hr = wined3d_shader_create_cs(device->wined3d_device, &desc, shader,
|
||||||
wined3d_mutex_unlock();
|
&d3d11_compute_shader_wined3d_parent_ops, &shader->wined3d_shader)))
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
WARN("Failed to create wined3d compute shader, hr %#x.\n", hr);
|
WARN("Failed to create wined3d compute shader, hr %#x.\n", hr);
|
||||||
wined3d_private_store_cleanup(&shader->private_store);
|
wined3d_private_store_cleanup(&shader->private_store);
|
||||||
|
|
Loading…
Reference in New Issue