[PATCH 2/6] wined3d: Keep original component index in stream output elements.

Józef Kucia jkucia at codeweavers.com
Mon Feb 11 09:32:13 CST 2019


Signed-off-by: Józef Kucia <jkucia at 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
-- 
2.19.2




More information about the wine-devel mailing list