Józef Kucia : d3d11: Correctly handle multiple stream output elements for single output register.
Module: wine Branch: master Commit: c09aa3af2383e670729e06588b184502d05aed38 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c09aa3af2383e670729e06588b... Author: Józef Kucia <jkucia(a)codeweavers.com> Date: Tue Mar 28 12:00:02 2017 +0200 d3d11: Correctly handle multiple stream output elements for single output register. Multiple output variables can be packed together into a single output register. Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/d3d11/shader.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/dlls/d3d11/shader.c b/dlls/d3d11/shader.c index 552ab0e..3025a1c 100644 --- a/dlls/d3d11/shader.c +++ b/dlls/d3d11/shader.c @@ -1192,13 +1192,13 @@ static HRESULT wined3d_so_elements_from_d3d11_so_entries(struct wined3d_stream_o const D3D11_SO_DECLARATION_ENTRY *entries, unsigned int entry_count, const struct wined3d_shader_signature *os) { - unsigned int i; + unsigned int i, j, mask; for (i = 0; i < entry_count; ++i) { struct wined3d_stream_output_element *e = &elements[i]; const D3D11_SO_DECLARATION_ENTRY *f = &entries[i]; - struct wined3d_shader_signature_element *element; + struct wined3d_shader_signature_element *output; TRACE("Stream: %u, semantic: %s, semantic idx: %u, start component: %u, " "component count %u, output slot %u.\n", @@ -1214,10 +1214,32 @@ static HRESULT wined3d_so_elements_from_d3d11_so_entries(struct wined3d_stream_o { e->register_idx = WINED3D_STREAM_OUTPUT_GAP; } - else if ((element = shader_find_signature_element(os, f->SemanticName, f->SemanticIndex))) + else if ((output = shader_find_signature_element(os, f->SemanticName, f->SemanticIndex))) { - e->register_idx = element->register_idx; - TRACE("Register idx: %u.\n", e->register_idx); + if (e->component_idx > 3 || e->component_count > 4 + || e->component_idx + e->component_count > 4) + { + WARN("Invalid component range %u-%u.\n", e->component_idx, e->component_count); + return E_INVALIDARG; + } + + for (j = 0; j < 4; ++j) + { + if ((1u << j) & output->mask) + break; + } + e->component_idx += j; + mask = ((1u << e->component_count) - 1) << e->component_idx; + if ((output->mask & 0xff & mask) != mask) + { + WARN("Invalid component range %u-%u (mask %#x), output mask %#x.\n", + e->component_idx, e->component_count, mask, output->mask & 0xff); + return E_INVALIDARG; + } + + e->register_idx = output->register_idx; + TRACE("Register idx: %u, register component idx %u, register mask %#x.\n", + e->register_idx, e->component_idx, mask); } else {
participants (1)
-
Alexandre Julliard