[18/23] wined3d: Add support for flat interpolation in shaders.

Andrew Wesie awesie at gmail.com
Sun Nov 13 12:35:18 CST 2016


Signed-off-by: Andrew Wesie <awesie at gmail.com>
---
 dlls/wined3d/glsl_shader.c     | 47 ++++++++++++++++++++++++++++++------------
 dlls/wined3d/shader.c          |  7 +++++++
 dlls/wined3d/wined3d_private.h |  1 +
 3 files changed, 42 insertions(+), 13 deletions(-)

diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index df7bd3b..7e2ff33 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -2174,7 +2174,14 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
             UINT in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input);
 
             if (ps_args->vp_mode == vertexshader)
-                declare_in_varying(gl_info, buffer, FALSE, "vec4 %s_link[%u];\n", prefix, in_count);
+            {
+                unsigned int j;
+                for (j = 0; j < in_count; j++)
+                {
+                    declare_in_varying(gl_info, buffer, shader->u.ps.input_reg_flags[j] == WINED3DSIM_CONSTANT,
+                            "vec4 %s_link%u;\n", prefix, j);
+                }
+            }
             shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count);
         }
 
@@ -5375,7 +5382,7 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w
             {
                 if (input->sysval_semantic)
                     FIXME("Unhandled sysval semantic %#x.\n", input->sysval_semantic);
-                shader_addline(buffer, "ps_in[%u]%s = ps_link[%u]%s;\n",
+                shader_addline(buffer, "ps_in[%u]%s = ps_link%u%s;\n",
                         shader->u.ps.input_reg_map[input->register_idx], reg_mask,
                         shader->u.ps.input_reg_map[input->register_idx], reg_mask);
             }
@@ -5467,7 +5474,7 @@ static void shader_glsl_setup_vs3_output(struct shader_glsl_priv *priv,
         const struct wined3d_shader_signature *input_signature,
         const struct wined3d_shader_reg_maps *reg_maps_in,
         const struct wined3d_shader_signature *output_signature,
-        const struct wined3d_shader_reg_maps *reg_maps_out, const char *out_array_name)
+        const struct wined3d_shader_reg_maps *reg_maps_out, const char *out_array_name, BOOL is_array)
 {
     struct wined3d_string_buffer *destination = string_buffer_get(&priv->string_buffers);
     BOOL legacy_context = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT];
@@ -5501,8 +5508,10 @@ static void shader_glsl_setup_vs3_output(struct shader_glsl_priv *priv,
             string_buffer_sprintf(destination, "gl_FrontColor");
         else if (in_idx == in_count + 1)
             string_buffer_sprintf(destination, "gl_FrontSecondaryColor");
-        else
+        else if (is_array)
             string_buffer_sprintf(destination, "%s[%u]", out_array_name, in_idx);
+        else
+            string_buffer_sprintf(destination, "%s%u", out_array_name, in_idx);
 
         if (!set[in_idx])
             set[in_idx] = ~0u;
@@ -5553,8 +5562,10 @@ static void shader_glsl_setup_vs3_output(struct shader_glsl_priv *priv,
             string_buffer_sprintf(destination, "gl_FrontColor");
         else if (i == in_count + 1)
             string_buffer_sprintf(destination, "gl_FrontSecondaryColor");
-        else
+        else if (is_array)
             string_buffer_sprintf(destination, "%s[%u]", out_array_name, i);
+        else
+            string_buffer_sprintf(destination, "%s%u", out_array_name, i);
 
         if (size == 1)
             shader_addline(buffer, "%s.%s = 0.0;\n", destination->buffer, reg_mask);
@@ -5568,7 +5579,7 @@ static void shader_glsl_setup_vs3_output(struct shader_glsl_priv *priv,
 
 static void shader_glsl_setup_sm4_shader_output(struct shader_glsl_priv *priv,
         unsigned int input_count, const struct wined3d_shader_signature *output_signature,
-        const struct wined3d_shader_reg_maps *reg_maps_out, const char *out_array_name)
+        const struct wined3d_shader_reg_maps *reg_maps_out, const char *out_array_name, BOOL is_array)
 {
     struct wined3d_string_buffer *destination = string_buffer_get(&priv->string_buffers);
     struct wined3d_string_buffer *buffer = &priv->shader_buffer;
@@ -5585,7 +5596,10 @@ static void shader_glsl_setup_sm4_shader_output(struct shader_glsl_priv *priv,
         if (output->register_idx >= input_count)
             continue;
 
-        string_buffer_sprintf(destination, "%s[%u]", out_array_name, output->register_idx);
+        if (is_array)
+            string_buffer_sprintf(destination, "%s[%u]", out_array_name, output->register_idx);
+        else
+            string_buffer_sprintf(destination, "%s%u", out_array_name, output->register_idx);
 
         shader_glsl_write_mask_to_str(output->mask, reg_mask);
 
@@ -5611,7 +5625,7 @@ static void shader_glsl_generate_vs_gs_setup(struct shader_glsl_priv *priv,
     shader_addline(buffer, "void setup_vs_output(in vec4 shader_out[%u])\n{\n", vs->limits->packed_output);
 
     shader_glsl_setup_sm4_shader_output(priv, input_count, &vs->output_signature, &vs->reg_maps,
-            legacy_context ? "gs_in" : "gs_in.gs_in");
+            legacy_context ? "gs_in" : "gs_in.gs_in", TRUE);
 
     shader_addline(buffer, "}\n");
 }
@@ -5665,9 +5679,9 @@ static void shader_glsl_setup_sm3_rasterizer_input(struct shader_glsl_priv *priv
     /* Then, setup the pixel shader input. */
     if (reg_maps_out->shader_version.major < 4)
         shader_glsl_setup_vs3_output(priv, gl_info, map, input_signature, reg_maps_in,
-                output_signature, reg_maps_out, "ps_link");
+                output_signature, reg_maps_out, "ps_link", FALSE);
     else
-        shader_glsl_setup_sm4_shader_output(priv, input_count, output_signature, reg_maps_out, "ps_link");
+        shader_glsl_setup_sm4_shader_output(priv, input_count, output_signature, reg_maps_out, "ps_link", FALSE);
 }
 
 /* Context activation is done by the caller. */
@@ -5797,9 +5811,13 @@ static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl
     }
     else
     {
+        unsigned int i;
         UINT in_count = min(vec4_varyings(ps_major, gl_info), ps->limits->packed_input);
 
-        declare_out_varying(gl_info, buffer, FALSE, "vec4 ps_link[%u];\n", in_count);
+        for (i = 0; i < in_count; i++)
+        {
+            declare_out_varying(gl_info, buffer, FALSE, "vec4 ps_link%u;\n", i);
+        }
         shader_addline(buffer, "void setup_vs_output(in vec4 shader_out[%u])\n{\n", vs->limits->packed_output);
         shader_glsl_setup_sm3_rasterizer_input(priv, gl_info, ps->u.ps.input_reg_map, &ps->input_signature,
                 &ps->reg_maps, 0, &vs->output_signature, &vs->reg_maps, per_vertex_point_size);
@@ -5819,9 +5837,12 @@ static void shader_glsl_generate_sm4_rasterizer_input_setup(struct shader_glsl_p
         const struct wined3d_gl_info *gl_info)
 {
     struct wined3d_string_buffer *buffer = &priv->shader_buffer;
+    unsigned int i;
 
-    if (input_count)
-        declare_out_varying(gl_info, buffer, FALSE, "vec4 ps_link[%u];\n", min(vec4_varyings(4, gl_info), input_count));
+    for (i = 0; i < min(vec4_varyings(4, gl_info), input_count); i++)
+    {
+        declare_out_varying(gl_info, buffer, FALSE, "vec4 ps_link%u;\n", i);
+    }
 
     shader_addline(buffer, "void setup_%s_output(in vec4 shader_out[%u])\n{\n",
             shader_glsl_get_prefix(shader->reg_maps.shader_version.type), shader->limits->packed_output);
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 61509d9..057bc13 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -942,6 +942,13 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
                     break;
             }
         }
+        else if (ins.handler_idx == WINED3DSIH_DCL_INPUT_PS)
+        {
+            unsigned int reg_idx = ins.declaration.dst.reg.idx[0].offset;
+            reg_maps->input_registers |= 1u << reg_idx;
+            /* We can assume we are in the pixel shader */
+            shader->u.ps.input_reg_flags[reg_idx] = ins.flags;
+        }
         else if (ins.handler_idx == WINED3DSIH_DCL_CONSTANT_BUFFER)
         {
             struct wined3d_shader_register *reg = &ins.declaration.src.reg;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 93d5c5f..e501cfc 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3439,6 +3439,7 @@ struct wined3d_pixel_shader
     /* Pixel shader input semantics */
     DWORD input_reg_map[MAX_REG_INPUT];
     BOOL input_reg_used[MAX_REG_INPUT];
+    enum wined3d_shader_interpolation_mode input_reg_flags[MAX_REG_INPUT];
     unsigned int declared_in_count;
 
     /* Some information about the shader behavior */
-- 
2.7.4




More information about the wine-patches mailing list