From: Matteo Bruni Subject: [PATCH 1/5] wined3d: Declare the correct number and type of fragment shader color outputs. Message-Id: <20180605223240.4752-1-mbruni@codeweavers.com> Date: Wed, 6 Jun 2018 00:32:36 +0200 Signed-off-by: Matteo Bruni --- dlls/wined3d/glsl_shader.c | 116 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 109 insertions(+), 7 deletions(-) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index a99762b151f..bc714f8de78 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -7613,6 +7613,53 @@ 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) +{ + const struct wined3d_shader_signature *output_signature = &shader->output_signature; + unsigned int i; + + 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 (strncasecmp(output->semantic_name, "SV_Target", sizeof("SV_Target"))) + continue; + switch (output->component_type) + { + case WINED3D_TYPE_UINT: + shader_addline(buffer, "color_out%u = floatBitsToUint(ps_out[%u]);\n", + output->semantic_idx, output->semantic_idx); + break; + case WINED3D_TYPE_INT: + shader_addline(buffer, "color_out%u = floatBitsToInt(ps_out[%u]);\n", + output->semantic_idx, output->semantic_idx); + break; + + default: + FIXME("Unhandled type %#x.\n", output->component_type); + /* Fall through. */ + case WINED3D_TYPE_UNKNOWN: + case WINED3D_TYPE_FLOAT: + shader_addline(buffer, "color_out%u = ps_out[%u];\n", + output->semantic_idx, output->semantic_idx); + } + } + } + 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) @@ -7634,6 +7681,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); +} + +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. */ @@ -7816,9 +7883,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 (strncasecmp(output->semantic_name, "SV_Target", sizeof("SV_Target"))) + 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) @@ -9536,9 +9629,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"); @@ -9878,6 +9972,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"); @@ -10419,13 +10515,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) @@ -12793,6 +12893,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.1