wined3d: Keep original component index in stream output elements.

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 2019-02-11 16:32:13 +01:00 committed by Alexandre Julliard
parent b750934589
commit a2ea5a98ee
3 changed files with 66 additions and 40 deletions

View File

@ -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, static BOOL shader_glsl_generate_transform_feedback_varyings(struct wined3d_string_buffer *buffer,
const char **varyings, unsigned int *varying_count, const char **varyings, unsigned int *varying_count, char *strings, unsigned int *strings_length,
char *strings, unsigned int *strings_length, GLenum buffer_mode, GLenum buffer_mode, struct wined3d_shader *shader)
const struct wined3d_stream_output_desc *so_desc, const unsigned int *output_register_idx)
{ {
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; BOOL have_varyings_to_record = FALSE;
count = length = 0; count = length = 0;
@ -855,23 +856,34 @@ static BOOL shader_glsl_generate_transform_feedback_varyings(struct wined3d_stri
continue; 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) 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, append_transform_feedback_skip_components(varyings, &count,
&strings, &length, buffer, e->component_count); &strings, &length, buffer, e->component_count);
continue; continue;
} }
string_buffer_sprintf(buffer, "shader_in_out.reg%u_%u_%u", 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); append_transform_feedback_varying(varyings, &count, &strings, &length, buffer);
} }
else 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); 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, static void shader_glsl_init_transform_feedback(const struct wined3d_context *context,
struct shader_glsl_priv *priv, GLuint program_id, struct wined3d_shader *shader) 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_stream_output_desc *so_desc = &shader->u.gs.so_desc;
const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_gl_info *gl_info = context->gl_info;
struct wined3d_string_buffer *buffer; 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); 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"); FIXME("No varyings to record, disabling transform feedback.\n");
shader->u.gs.so_desc.element_count = 0; 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; 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)); GL_EXTCALL(glTransformFeedbackVaryings(program_id, count, varyings, mode));
checkGLcall("glTransformFeedbackVaryings"); checkGLcall("glTransformFeedbackVaryings");
@ -7422,12 +7433,12 @@ static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl
return ret; return ret;
} }
static void shader_glsl_generate_stream_output_setup(struct shader_glsl_priv *priv, static void shader_glsl_generate_stream_output_setup(struct wined3d_string_buffer *buffer,
const struct wined3d_shader *shader, const struct wined3d_stream_output_desc *so_desc, const struct wined3d_shader *shader)
const unsigned int *output_register_idx)
{ {
struct wined3d_string_buffer *buffer = &priv->shader_buffer; const struct wined3d_stream_output_desc *so_desc = &shader->u.gs.so_desc;
unsigned int i; const struct wined3d_shader_signature_element *output;
unsigned int i, component_idx;
shader_addline(buffer, "out shader_in_out\n{\n"); shader_addline(buffer, "out shader_in_out\n{\n");
for (i = 0; i < so_desc->element_count; ++i) 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) if (!e->semantic_name)
continue; continue;
if (!(output = shader_find_signature_element(&shader->output_signature,
e->stream_idx, e->semantic_name, e->semantic_idx)))
continue;
if (e->component_idx || e->component_count != 4) 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 (e->component_count == 1) if (e->component_count == 1)
shader_addline(buffer, "float"); shader_addline(buffer, "float");
else else
shader_addline(buffer, "vec%u", e->component_count); shader_addline(buffer, "vec%u", e->component_count);
shader_addline(buffer, " reg%u_%u_%u;\n", 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 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"); 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) if (!e->semantic_name)
continue; continue;
if (!(output = shader_find_signature_element(&shader->output_signature,
e->stream_idx, e->semantic_name, e->semantic_idx)))
continue;
if (e->component_idx || e->component_count != 4) 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)
{ {
DWORD write_mask; DWORD write_mask;
char str_mask[6]; 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_glsl_write_mask_to_str(write_mask, str_mask);
shader_addline(buffer, "shader_out.reg%u_%u_%u = outputs[%u]%s;\n", 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, component_idx, component_idx + e->component_count - 1,
output_register_idx[i], str_mask); output->register_idx, str_mask);
} }
else else
{ {
shader_addline(buffer, "shader_out.reg%u = outputs[%u];\n", 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"); shader_addline(buffer, "}\n");
@ -8532,8 +8564,7 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context
if (is_rasterization_disabled(shader)) if (is_rasterization_disabled(shader))
{ {
shader_glsl_generate_stream_output_setup(priv, shader, shader_glsl_generate_stream_output_setup(buffer, shader);
&shader->u.gs.so_desc, shader->u.gs.output_register_idx);
} }
else else
{ {

View File

@ -3145,7 +3145,6 @@ static void shader_cleanup(struct wined3d_shader *shader)
else if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY) else if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY)
{ {
heap_free((void *)shader->u.gs.so_desc.elements); heap_free((void *)shader->u.gs.so_desc.elements);
heap_free(shader->u.gs.output_register_idx);
} }
heap_free(shader->patch_constant_signature.elements); 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; 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) unsigned int stream_idx, const char *semantic_name, unsigned int semantic_idx)
{ {
struct wined3d_shader_signature_element *e = s->elements; 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; const struct wined3d_shader_signature_element *output;
struct wined3d_stream_output_element *elements; struct wined3d_stream_output_element *elements;
struct wined3d_shader_version shader_version; struct wined3d_shader_version shader_version;
unsigned int i, j, mask; unsigned int i, component_idx, mask;
const DWORD *ptr; const DWORD *ptr;
void *fe_data; void *fe_data;
HRESULT hr; HRESULT hr;
@ -3792,9 +3791,6 @@ static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader,
return hr; 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)))) if (!(elements = heap_calloc(so_desc->element_count, sizeof(*elements))))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
@ -3816,16 +3812,14 @@ static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader,
} }
e->semantic_name = output->semantic_name; 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; break;
} }
e->component_idx += j; component_idx += e->component_idx;
mask = ((1u << e->component_count) - 1) << component_idx;
mask = ((1u << e->component_count) - 1) << e->component_idx;
if ((output->mask & 0xff & mask) != mask) if ((output->mask & 0xff & mask) != mask)
{ {
WARN("Invalid component range %u-%u (mask %#x), output mask %#x.\n", WARN("Invalid component range %u-%u (mask %#x), output mask %#x.\n",

View File

@ -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; extern const struct wined3d_shader_frontend sm4_shader_frontend DECLSPEC_HIDDEN;
HRESULT shader_extract_from_dxbc(struct wined3d_shader *shader, 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 *); typedef void (*SHADER_HANDLER)(const struct wined3d_shader_instruction *);
@ -4198,7 +4200,6 @@ struct wined3d_geometry_shader
unsigned int instance_count; unsigned int instance_count;
struct wined3d_stream_output_desc so_desc; struct wined3d_stream_output_desc so_desc;
unsigned int *output_register_idx;
}; };
struct wined3d_pixel_shader struct wined3d_pixel_shader