Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/wined3d/glsl_shader.c | 83 +++++++++++++++++++++++----------- dlls/wined3d/shader.c | 18 +++----- dlls/wined3d/wined3d_private.h | 5 +- 3 files changed, 66 insertions(+), 40 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index ba2c62165b53..4de0f82115df 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -819,11 +819,12 @@ static void append_transform_feedback_skip_components(const char **varyings, }
static BOOL shader_glsl_generate_transform_feedback_varyings(struct wined3d_string_buffer *buffer, - const char **varyings, unsigned int *varying_count, - char *strings, unsigned int *strings_length, GLenum buffer_mode, - const struct wined3d_stream_output_desc *so_desc, const unsigned int *output_register_idx) + const char **varyings, unsigned int *varying_count, char *strings, unsigned int *strings_length, + GLenum buffer_mode, struct wined3d_shader *shader) { - unsigned int i, buffer_idx, count, length, highest_output_slot, stride; + unsigned int i, component_idx, buffer_idx, count, length, highest_output_slot, stride; + const struct wined3d_stream_output_desc *so_desc = &shader->u.gs.so_desc; + const struct wined3d_shader_signature_element *output; BOOL have_varyings_to_record = FALSE;
count = length = 0; @@ -855,23 +856,34 @@ static BOOL shader_glsl_generate_transform_feedback_varyings(struct wined3d_stri continue; }
- if (e->component_idx || e->component_count != 4) + if (!(output = shader_find_signature_element(&shader->output_signature, + e->stream_idx, e->semantic_name, e->semantic_idx))) + continue; + + for (component_idx = 0; component_idx < 4; ++component_idx) + { + if ((1u << component_idx) & output->mask) + break; + } + component_idx += e->component_idx; + + if (component_idx || e->component_count != 4) { if (so_desc->rasterizer_stream_idx != WINED3D_NO_RASTERIZER_STREAM) { - FIXME("Unsupported component range %u-%u.\n", e->component_idx, e->component_count); + FIXME("Unsupported component range %u-%u.\n", component_idx, e->component_count); append_transform_feedback_skip_components(varyings, &count, &strings, &length, buffer, e->component_count); continue; }
string_buffer_sprintf(buffer, "shader_in_out.reg%u_%u_%u", - output_register_idx[i], e->component_idx, e->component_idx + e->component_count - 1); + output->register_idx, component_idx, component_idx + e->component_count - 1); append_transform_feedback_varying(varyings, &count, &strings, &length, buffer); } else { - string_buffer_sprintf(buffer, "shader_in_out.reg%u", output_register_idx[i]); + string_buffer_sprintf(buffer, "shader_in_out.reg%u", output->register_idx); append_transform_feedback_varying(varyings, &count, &strings, &length, buffer); }
@@ -907,7 +919,6 @@ static BOOL shader_glsl_generate_transform_feedback_varyings(struct wined3d_stri static void shader_glsl_init_transform_feedback(const struct wined3d_context *context, struct shader_glsl_priv *priv, GLuint program_id, struct wined3d_shader *shader) { - const unsigned int *output_register_idx = shader->u.gs.output_register_idx; const struct wined3d_stream_output_desc *so_desc = &shader->u.gs.so_desc; const struct wined3d_gl_info *gl_info = context->gl_info; struct wined3d_string_buffer *buffer; @@ -962,7 +973,7 @@ static void shader_glsl_init_transform_feedback(const struct wined3d_context *co
buffer = string_buffer_get(&priv->string_buffers);
- if (!shader_glsl_generate_transform_feedback_varyings(buffer, NULL, &count, NULL, &length, mode, so_desc, output_register_idx)) + if (!shader_glsl_generate_transform_feedback_varyings(buffer, NULL, &count, NULL, &length, mode, shader)) { FIXME("No varyings to record, disabling transform feedback.\n"); shader->u.gs.so_desc.element_count = 0; @@ -984,7 +995,7 @@ static void shader_glsl_init_transform_feedback(const struct wined3d_context *co return; }
- shader_glsl_generate_transform_feedback_varyings(buffer, varyings, NULL, strings, NULL, mode, so_desc, output_register_idx); + shader_glsl_generate_transform_feedback_varyings(buffer, varyings, NULL, strings, NULL, mode, shader); GL_EXTCALL(glTransformFeedbackVaryings(program_id, count, varyings, mode)); checkGLcall("glTransformFeedbackVaryings");
@@ -7422,12 +7433,12 @@ static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl return ret; }
-static void shader_glsl_generate_stream_output_setup(struct shader_glsl_priv *priv, - const struct wined3d_shader *shader, const struct wined3d_stream_output_desc *so_desc, - const unsigned int *output_register_idx) +static void shader_glsl_generate_stream_output_setup(struct wined3d_string_buffer *buffer, + const struct wined3d_shader *shader) { - struct wined3d_string_buffer *buffer = &priv->shader_buffer; - unsigned int i; + const struct wined3d_stream_output_desc *so_desc = &shader->u.gs.so_desc; + const struct wined3d_shader_signature_element *output; + unsigned int i, component_idx;
shader_addline(buffer, "out shader_in_out\n{\n"); for (i = 0; i < so_desc->element_count; ++i) @@ -7441,19 +7452,30 @@ static void shader_glsl_generate_stream_output_setup(struct shader_glsl_priv *pr } if (!e->semantic_name) continue; + if (!(output = shader_find_signature_element(&shader->output_signature, + e->stream_idx, e->semantic_name, e->semantic_idx))) + continue; + + for (component_idx = 0; component_idx < 4; ++component_idx) + { + if ((1u << component_idx) & output->mask) + break; + } + component_idx += e->component_idx;
- if (e->component_idx || e->component_count != 4) + if (component_idx || e->component_count != 4) { if (e->component_count == 1) shader_addline(buffer, "float"); else shader_addline(buffer, "vec%u", e->component_count); + shader_addline(buffer, " reg%u_%u_%u;\n", - output_register_idx[i], e->component_idx, e->component_idx + e->component_count - 1); + output->register_idx, component_idx, component_idx + e->component_count - 1); } else { - shader_addline(buffer, "vec4 reg%u;\n", output_register_idx[i]); + shader_addline(buffer, "vec4 reg%u;\n", output->register_idx); } } shader_addline(buffer, "} shader_out;\n"); @@ -7471,22 +7493,32 @@ static void shader_glsl_generate_stream_output_setup(struct shader_glsl_priv *pr } if (!e->semantic_name) continue; + if (!(output = shader_find_signature_element(&shader->output_signature, + e->stream_idx, e->semantic_name, e->semantic_idx))) + continue; + + for (component_idx = 0; component_idx < 4; ++component_idx) + { + if ((1u << component_idx) & output->mask) + break; + } + component_idx += e->component_idx;
- if (e->component_idx || e->component_count != 4) + if (component_idx || e->component_count != 4) { DWORD write_mask; char str_mask[6];
- write_mask = ((1u << e->component_count) - 1) << e->component_idx; + write_mask = ((1u << e->component_count) - 1) << component_idx; shader_glsl_write_mask_to_str(write_mask, str_mask); shader_addline(buffer, "shader_out.reg%u_%u_%u = outputs[%u]%s;\n", - output_register_idx[i], e->component_idx, e->component_idx + e->component_count - 1, - output_register_idx[i], str_mask); + output->register_idx, component_idx, component_idx + e->component_count - 1, + output->register_idx, str_mask); } else { shader_addline(buffer, "shader_out.reg%u = outputs[%u];\n", - output_register_idx[i], output_register_idx[i]); + output->register_idx, output->register_idx); } } shader_addline(buffer, "}\n"); @@ -8532,8 +8564,7 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context
if (is_rasterization_disabled(shader)) { - shader_glsl_generate_stream_output_setup(priv, shader, - &shader->u.gs.so_desc, shader->u.gs.output_register_idx); + shader_glsl_generate_stream_output_setup(buffer, shader); } else { diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index a52b9a1c83a9..a7d0e6911901 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -3145,7 +3145,6 @@ static void shader_cleanup(struct wined3d_shader *shader) else if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY) { heap_free((void *)shader->u.gs.so_desc.elements); - heap_free(shader->u.gs.output_register_idx); }
heap_free(shader->patch_constant_signature.elements); @@ -3729,7 +3728,7 @@ static HRESULT vertex_shader_init(struct wined3d_shader *shader, struct wined3d_ return WINED3D_OK; }
-static struct wined3d_shader_signature_element *shader_find_signature_element(const struct wined3d_shader_signature *s, +struct wined3d_shader_signature_element *shader_find_signature_element(const struct wined3d_shader_signature *s, unsigned int stream_idx, const char *semantic_name, unsigned int semantic_idx) { struct wined3d_shader_signature_element *e = s->elements; @@ -3753,7 +3752,7 @@ static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader, const struct wined3d_shader_signature_element *output; struct wined3d_stream_output_element *elements; struct wined3d_shader_version shader_version; - unsigned int i, j, mask; + unsigned int i, component_idx, mask; const DWORD *ptr; void *fe_data; HRESULT hr; @@ -3792,9 +3791,6 @@ static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader, return hr; }
- if (!(shader->u.gs.output_register_idx = heap_calloc(so_desc->element_count, sizeof(*shader->u.gs.output_register_idx)))) - return E_OUTOFMEMORY; - if (!(elements = heap_calloc(so_desc->element_count, sizeof(*elements)))) return E_OUTOFMEMORY;
@@ -3816,16 +3812,14 @@ static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader, }
e->semantic_name = output->semantic_name; - shader->u.gs.output_register_idx[i] = output->register_idx;
- for (j = 0; j < 4; ++j) + for (component_idx = 0; component_idx < 4; ++component_idx) { - if ((1u << j) & output->mask) + if ((1u << component_idx) & output->mask) break; } - e->component_idx += j; - - mask = ((1u << e->component_count) - 1) << e->component_idx; + component_idx += e->component_idx; + mask = ((1u << e->component_count) - 1) << component_idx; if ((output->mask & 0xff & mask) != mask) { WARN("Invalid component range %u-%u (mask %#x), output mask %#x.\n", diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 07d77011f1d5..187c9e18c523 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1266,7 +1266,9 @@ extern const struct wined3d_shader_frontend sm1_shader_frontend DECLSPEC_HIDDEN; extern const struct wined3d_shader_frontend sm4_shader_frontend DECLSPEC_HIDDEN;
HRESULT shader_extract_from_dxbc(struct wined3d_shader *shader, - unsigned int max_shader_version, enum wined3d_shader_byte_code_format *format); + unsigned int max_shader_version, enum wined3d_shader_byte_code_format *format) DECLSPEC_HIDDEN; +struct wined3d_shader_signature_element *shader_find_signature_element(const struct wined3d_shader_signature *s, + unsigned int stream_idx, const char *semantic_name, unsigned int semantic_idx) DECLSPEC_HIDDEN;
typedef void (*SHADER_HANDLER)(const struct wined3d_shader_instruction *);
@@ -4198,7 +4200,6 @@ struct wined3d_geometry_shader unsigned int instance_count;
struct wined3d_stream_output_desc so_desc; - unsigned int *output_register_idx; };
struct wined3d_pixel_shader
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=47447
Your paranoid android.
=== debian9 (32 bit report) ===
d3d11: Unhandled exception: page fault on execute access to 0x00000000 in 32-bit code (0x00000000).
=== debian9 (32 bit Chinese:China report) ===
d3d11: d3d11.c:5346: Test failed: Got unexpected hr 0x8876086a for query type 4. d3d11.c:5593: Test failed: Got unexpected hr 0x8876086a. Unhandled exception: page fault on read access to 0x3f800000 in 32-bit code (0x7eb65f6d).
=== debian9 (32 bit WoW report) ===
d3d11: Unhandled exception: page fault on read access to 0x3f800000 in 32-bit code (0x7ed03f6d).