Module: wine Branch: master Commit: 46b3a03a97f9299b9c022703523f9524f3b9124c URL: http://source.winehq.org/git/wine.git/?a=commit;h=46b3a03a97f9299b9c02270352...
Author: Józef Kucia jkucia@codeweavers.com Date: Wed Oct 18 00:25:07 2017 +0200
wined3d: Implement interpolation mode when GLSL 4.40 is available.
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
---
dlls/wined3d/glsl_shader.c | 33 +++++++++++++++++++++++++++++---- dlls/wined3d/shader.c | 14 ++++++++++++++ dlls/wined3d/wined3d_private.h | 2 ++ 3 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 45a7b98..911c9fe 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -2125,8 +2125,25 @@ static const char *shader_glsl_shader_output_name(const struct wined3d_gl_info * return shader_glsl_use_interface_blocks(gl_info) ? "shader_out.reg" : "ps_link"; }
+static const char *shader_glsl_interpolation_qualifiers(enum wined3d_shader_interpolation_mode mode) +{ + switch (mode) + { + case WINED3DSIM_CONSTANT: + return "flat"; + case WINED3DSIM_LINEAR_NOPERSPECTIVE: + return "noperspective"; + default: + FIXME("Unhandled interpolation mode %#x.\n", mode); + case WINED3DSIM_NONE: + case WINED3DSIM_LINEAR: + return ""; + } +} + static void shader_glsl_declare_shader_inputs(const struct wined3d_gl_info *gl_info, - struct wined3d_string_buffer *buffer, unsigned int element_count, BOOL unroll) + struct wined3d_string_buffer *buffer, unsigned int element_count, + const enum wined3d_shader_interpolation_mode *interpolation_mode, BOOL unroll) { unsigned int i;
@@ -2136,7 +2153,14 @@ static void shader_glsl_declare_shader_inputs(const struct wined3d_gl_info *gl_i { shader_addline(buffer, "in shader_in_out {\n"); for (i = 0; i < element_count; ++i) - shader_addline(buffer, " vec4 reg%u;\n", i); + { + const char *interpolation_qualifiers = ""; + if (shader_glsl_get_version(gl_info) >= 440) + interpolation_qualifiers = shader_glsl_interpolation_qualifiers(interpolation_mode[i]); + else if (interpolation_mode[i] && interpolation_mode[i] != WINED3DSIM_LINEAR) + FIXME("Unhandled interpolation mode %#x.\n", interpolation_mode[i]); + shader_addline(buffer, "%s vec4 reg%u;\n", interpolation_qualifiers, i); + } shader_addline(buffer, "} shader_in;\n"); } else @@ -7379,7 +7403,8 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context unsigned int in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input);
if (args->vp_mode == vertexshader && reg_maps->input_registers) - shader_glsl_declare_shader_inputs(gl_info, buffer, in_count, version->major >= 4); + shader_glsl_declare_shader_inputs(gl_info, buffer, in_count, + shader->u.ps.interpolation_mode, version->major >= 4); shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count); }
@@ -10780,7 +10805,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_DCL_INPUT */ shader_glsl_nop, /* WINED3DSIH_DCL_INPUT_CONTROL_POINT_COUNT */ shader_glsl_nop, /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ shader_glsl_nop, - /* WINED3DSIH_DCL_INPUT_PS */ NULL, + /* WINED3DSIH_DCL_INPUT_PS */ shader_glsl_nop, /* WINED3DSIH_DCL_INPUT_PS_SGV */ NULL, /* WINED3DSIH_DCL_INPUT_PS_SIV */ NULL, /* WINED3DSIH_DCL_INPUT_SGV */ shader_glsl_nop, diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 02880b0..de58ade 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -1148,6 +1148,20 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st FIXME("Invalid instruction %#x for shader type %#x.\n", ins.handler_idx, shader_version.type); } + else if (ins.handler_idx == WINED3DSIH_DCL_INPUT_PS) + { + unsigned int reg_idx = ins.declaration.dst.reg.idx[0].offset; + if (reg_idx >= ARRAY_SIZE(shader->u.ps.interpolation_mode)) + { + ERR("Invalid register index %u.\n", reg_idx); + break; + } + if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL) + shader->u.ps.interpolation_mode[reg_idx] = ins.flags; + else + FIXME("Invalid instruction %#x for shader type %#x.\n", + ins.handler_idx, shader_version.type); + } else if (ins.handler_idx == WINED3DSIH_DCL_OUTPUT) { if (ins.declaration.dst.reg.type == WINED3DSPR_DEPTHOUT diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 4fca08d..7ffa45b 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -549,6 +549,7 @@ enum wined3d_shader_dst_modifier
enum wined3d_shader_interpolation_mode { + WINED3DSIM_NONE = 0, WINED3DSIM_CONSTANT = 1, WINED3DSIM_LINEAR = 2, WINED3DSIM_LINEAR_CENTROID = 3, @@ -3908,6 +3909,7 @@ struct wined3d_pixel_shader
BOOL force_early_depth_stencil; enum wined3d_shader_register_type depth_output; + enum wined3d_shader_interpolation_mode interpolation_mode[MAX_REG_INPUT]; };
struct wined3d_compute_shader