[PATCH v2 resend 4/5] wined3d: Declare the correct number and type of fragment shader color outputs.

Matteo Bruni mbruni at codeweavers.com
Wed Jun 20 17:48:25 CDT 2018


Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
---
 dlls/wined3d/glsl_shader.c | 128 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 111 insertions(+), 17 deletions(-)

diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index cd4780a6419..d5dc8be136a 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -3318,12 +3318,12 @@ static void shader_glsl_get_swizzle(const struct wined3d_shader_src_param *param
         shader_glsl_swizzle_to_str(param->swizzle, fixup, mask, swizzle_str);
 }
 
-static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, const char *src_param,
+static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *buffer, const char *arg,
         enum wined3d_component_type dst_type, enum wined3d_component_type src_type)
 {
     if (dst_type == src_type)
     {
-        string_buffer_sprintf(dst_param, "%s", src_param);
+        string_buffer_sprintf(buffer, "%s", arg);
         return;
     }
 
@@ -3332,10 +3332,10 @@ static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, co
         switch (dst_type)
         {
             case WINED3D_TYPE_INT:
-                string_buffer_sprintf(dst_param, "floatBitsToInt(%s)", src_param);
+                string_buffer_sprintf(buffer, "floatBitsToInt(%s)", arg);
                 return;
             case WINED3D_TYPE_UINT:
-                string_buffer_sprintf(dst_param, "floatBitsToUint(%s)", src_param);
+                string_buffer_sprintf(buffer, "floatBitsToUint(%s)", arg);
                 return;
             default:
                 break;
@@ -3344,18 +3344,18 @@ static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, co
 
     if (src_type == WINED3D_TYPE_UINT && dst_type == WINED3D_TYPE_FLOAT)
     {
-        string_buffer_sprintf(dst_param, "uintBitsToFloat(%s)", src_param);
+        string_buffer_sprintf(buffer, "uintBitsToFloat(%s)", arg);
         return;
     }
 
     if (src_type == WINED3D_TYPE_INT && dst_type == WINED3D_TYPE_FLOAT)
     {
-        string_buffer_sprintf(dst_param, "intBitsToFloat(%s)", src_param);
+        string_buffer_sprintf(buffer, "intBitsToFloat(%s)", arg);
         return;
     }
 
     FIXME("Unhandled cast from %#x to %#x.\n", src_type, dst_type);
-    string_buffer_sprintf(dst_param, "%s", src_param);
+    string_buffer_sprintf(buffer, "%s", arg);
 }
 
 /* From a given parameter token, generate the corresponding GLSL string.
@@ -7616,9 +7616,48 @@ static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer,
         shader_addline(buffer, "#extension GL_EXT_texture_array : enable\n");
 }
 
+static void shader_glsl_generate_color_output(struct wined3d_string_buffer *buffer,
+        const struct wined3d_gl_info *gl_info, const struct wined3d_shader *shader,
+        struct wined3d_string_buffer_list *string_buffers)
+{
+    const struct wined3d_shader_signature *output_signature = &shader->output_signature;
+    struct wined3d_string_buffer *src, *assignment;
+    unsigned int i;
+
+    if (output_signature->element_count)
+    {
+        src = string_buffer_get(string_buffers);
+        assignment = string_buffer_get(string_buffers);
+        for (i = 0; i < output_signature->element_count; ++i)
+        {
+            const struct wined3d_shader_signature_element *output = &output_signature->elements[i];
+
+            /* register_idx is set to ~0u for non-color outputs. */
+            if (output->register_idx == ~0u)
+                continue;
+            shader_addline(buffer, "color_out%u = ", output->semantic_idx);
+            string_buffer_sprintf(src, "ps_out[%u]", output->semantic_idx);
+            shader_glsl_sprintf_cast(assignment, src->buffer, output->component_type, WINED3D_TYPE_FLOAT);
+            shader_addline(buffer, "%s;\n", assignment->buffer);
+        }
+        string_buffer_release(string_buffers, src);
+        string_buffer_release(string_buffers, assignment);
+    }
+    else
+    {
+        DWORD mask = shader->reg_maps.rt_mask;
+
+        while (mask)
+        {
+            i = wined3d_bit_scan(&mask);
+            shader_addline(buffer, "color_out%u = ps_out[%u];\n", i, i);
+        }
+    }
+}
+
 static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_info,
         struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader,
-        const struct ps_compile_args *args)
+        const struct ps_compile_args *args, struct wined3d_string_buffer_list *string_buffers)
 {
     const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
 
@@ -7637,6 +7676,26 @@ static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_in
 
     if (reg_maps->sample_mask)
         shader_addline(buffer, "gl_SampleMask[0] = floatBitsToInt(sample_mask);\n");
+
+    if (!needs_legacy_glsl_syntax(gl_info))
+        shader_glsl_generate_color_output(buffer, gl_info, shader, string_buffers);
+}
+
+static const char *shader_glsl_get_ps_output_format(enum wined3d_component_type component_type)
+{
+    static const char formats[][6] =
+    {
+        "", /* WINED3D_TYPE_UNKNOWN */
+        "uvec4", /* WINED3D_TYPE_UINT */
+        "ivec4", /* WINED3D_TYPE_INT */
+        "vec4", /* WINED3D_TYPE_FLOAT */
+    };
+    if (component_type < WINED3D_TYPE_UNKNOWN || component_type > WINED3D_TYPE_FLOAT)
+    {
+        WARN("Unexpected component_type %#x.\n", component_type);
+        return formats[WINED3D_TYPE_FLOAT];
+    }
+    return formats[component_type];
 }
 
 /* Context activation is done by the caller. */
@@ -7819,9 +7878,35 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
 
     if (!needs_legacy_glsl_syntax(gl_info))
     {
-        if (shader_glsl_use_explicit_attrib_location(gl_info))
-            shader_addline(buffer, "layout(location = 0) ");
-        shader_addline(buffer, "out vec4 ps_out[%u];\n", gl_info->limits.buffers);
+        const struct wined3d_shader_signature *output_signature = &shader->output_signature;
+
+        shader_addline(buffer, "vec4 ps_out[%u];\n", gl_info->limits.buffers);
+        if (output_signature->element_count)
+        {
+            for (i = 0; i < output_signature->element_count; ++i)
+            {
+                const struct wined3d_shader_signature_element *output = &output_signature->elements[i];
+
+                if (output->register_idx == ~0u)
+                    continue;
+                if (shader_glsl_use_explicit_attrib_location(gl_info))
+                    shader_addline(buffer, "layout(location = %u) ", output->semantic_idx);
+                shader_addline(buffer, "out %s color_out%u;\n",
+                        shader_glsl_get_ps_output_format(output->component_type), output->semantic_idx);
+            }
+        }
+        else
+        {
+            DWORD mask = reg_maps->rt_mask;
+
+            while (mask)
+            {
+                i = wined3d_bit_scan(&mask);
+                if (shader_glsl_use_explicit_attrib_location(gl_info))
+                    shader_addline(buffer, "layout(location = %u) ", i);
+                shader_addline(buffer, "out vec4 color_out%u;\n", i);
+            }
+        }
     }
 
     if (shader->limits->constant_float + extra_constants_needed >= gl_info->limits.glsl_ps_float_constants)
@@ -7906,7 +7991,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
 
     /* In SM4+ the shader epilogue is generated by the "ret" instruction. */
     if (reg_maps->shader_version.major < 4)
-        shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, args);
+        shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, args, string_buffers);
 
     shader_addline(buffer, "}\n");
 
@@ -8403,7 +8488,7 @@ static void shader_glsl_generate_shader_epilogue(const struct wined3d_shader_con
     switch (shader->reg_maps.shader_version.type)
     {
         case WINED3D_SHADER_TYPE_PIXEL:
-            shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, priv->cur_ps_args);
+            shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, priv->cur_ps_args, priv->string_buffers);
             break;
         case WINED3D_SHADER_TYPE_VERTEX:
             shader_glsl_generate_vs_epilogue(gl_info, buffer, shader, priv->cur_vs_args);
@@ -9539,9 +9624,10 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
 
     if (!needs_legacy_glsl_syntax(gl_info))
     {
+        shader_addline(buffer, "vec4 ps_out[1];\n");
         if (shader_glsl_use_explicit_attrib_location(gl_info))
             shader_addline(buffer, "layout(location = 0) ");
-        shader_addline(buffer, "out vec4 ps_out[1];\n");
+        shader_addline(buffer, "out vec4 color_out0;\n");
     }
 
     shader_addline(buffer, "vec4 tmp0, tmp1;\n");
@@ -9881,6 +9967,8 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
     shader_glsl_generate_fog_code(buffer, gl_info, settings->fog);
 
     shader_glsl_generate_alpha_test(buffer, gl_info, alpha_test_func);
+    if (!needs_legacy_glsl_syntax(gl_info))
+        shader_addline(buffer, "color_out0 = ps_out[0];\n");
 
     shader_addline(buffer, "}\n");
 
@@ -10422,13 +10510,17 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
             }
         }
         checkGLcall("glBindAttribLocation");
-        string_buffer_release(&priv->string_buffers, tmp_name);
 
         if (!needs_legacy_glsl_syntax(gl_info))
         {
-            GL_EXTCALL(glBindFragDataLocation(program_id, 0, "ps_out"));
-            checkGLcall("glBindFragDataLocation");
+            for (i = 0; i < MAX_RENDER_TARGET_VIEWS; ++i)
+            {
+                string_buffer_sprintf(tmp_name, "color_out%u", i);
+                GL_EXTCALL(glBindFragDataLocation(program_id, i, tmp_name->buffer));
+                checkGLcall("glBindFragDataLocation");
+            }
         }
+        string_buffer_release(&priv->string_buffers, tmp_name);
     }
 
     if (hshader)
@@ -12796,6 +12888,8 @@ static GLuint glsl_blitter_generate_program(struct wined3d_glsl_blitter *blitter
     shader_glsl_add_version_declaration(buffer, gl_info);
     shader_addline(buffer, "uniform sampler%s sampler;\n", tex_type);
     declare_in_varying(gl_info, buffer, FALSE, "vec3 out_texcoord;\n");
+    /* TODO: Declare the out variable with the correct type (and put it in the
+     * blitter args). */
     if (!needs_legacy_glsl_syntax(gl_info))
         shader_addline(buffer, "out vec4 ps_out[1];\n");
 
-- 
2.16.4




More information about the wine-devel mailing list