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,
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;
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)
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;
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;
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
{

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)
{
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",

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;
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