From: Matteo Bruni Subject: [PATCH 5/8] wined3d: Fixup vertex position in geometry shaders. Message-Id: <1461085013-7434-5-git-send-email-mbruni@codeweavers.com> Date: Tue, 19 Apr 2016 18:56:50 +0200 In-Reply-To: <1461085013-7434-1-git-send-email-mbruni@codeweavers.com> References: <1461085013-7434-1-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- dlls/wined3d/glsl_shader.c | 70 ++++++++++++++++++++++++++++-------------- dlls/wined3d/state.c | 2 +- dlls/wined3d/wined3d_private.h | 2 +- 3 files changed, 49 insertions(+), 25 deletions(-) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index c0a5e11..eb11481 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -159,6 +159,8 @@ struct glsl_gs_program { struct list shader_entry; GLuint id; + + GLint pos_fixup_location; }; struct glsl_ps_program @@ -1344,10 +1346,13 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context if (update_mask & WINED3D_SHADER_CONST_VS_POINTSIZE) shader_glsl_pointsize_uniform(context, state, prog); - if (update_mask & WINED3D_SHADER_CONST_VS_POS_FIXUP) + if (update_mask & WINED3D_SHADER_CONST_POS_FIXUP) { shader_get_position_fixup(context, state, position_fixup); - GL_EXTCALL(glUniform4fv(prog->vs.pos_fixup_location, 1, position_fixup)); + if (state->shader[WINED3D_SHADER_TYPE_GEOMETRY]) + GL_EXTCALL(glUniform4fv(prog->gs.pos_fixup_location, 1, position_fixup)); + else + GL_EXTCALL(glUniform4fv(prog->vs.pos_fixup_location, 1, position_fixup)); checkGLcall("glUniform4fv"); } @@ -1946,7 +1951,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); } - shader_addline(buffer, "uniform vec4 posFixup;\n"); + shader_addline(buffer, "uniform vec4 pos_fixup;\n"); shader_addline(buffer, "void setup_vs_output(in vec4[%u]);\n", shader->limits->packed_output); } else if (version->type == WINED3D_SHADER_TYPE_GEOMETRY) @@ -5473,6 +5478,28 @@ static GLuint shader_glsl_generate_vs_rasterizer_input_setup(struct shader_glsl_ return ret; } +static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer) +{ + /* Write the final position. + * + * OpenGL coordinates specify the center of the pixel while D3D coords + * specify the corner. The offsets are stored in z and w in + * pos_fixup. pos_fixup.y contains 1.0 or -1.0 to turn the rendering + * upside down for offscreen rendering. pos_fixup.x contains 1.0 to allow + * a MAD. */ + shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup.y;\n"); + shader_addline(buffer, "gl_Position.xy += pos_fixup.zw * gl_Position.ww;\n"); + + /* Z coord [0;1]->[-1;1] mapping, see comment in get_projection_matrix() + * in utils.c + * + * Basically we want (in homogeneous coordinates) z = z * 2 - 1. However, + * shaders are run before the homogeneous divide, so we have to take the w + * into account: z = ((z / w) * 2 - 1) * w, which is the same as + * z = z * 2 - w. */ + shader_addline(buffer, "gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;\n"); +} + /* Context activation is done by the caller. */ static GLuint shader_glsl_generate_vs_gs_setup(struct shader_glsl_priv *priv, const struct wined3d_shader *vs, const struct wined3d_shader *gs, @@ -5513,11 +5540,14 @@ static GLuint shader_glsl_generate_gs_rasterizer_input_setup(struct shader_glsl_ shader_addline(buffer, "%s\n", shader_glsl_get_version(gl_info, &gs->reg_maps.shader_version)); declare_out_varying(gl_info, buffer, FALSE, "vec4 ps_link[%u];\n", in_count); + shader_addline(buffer, "uniform vec4 pos_fixup;\n"); shader_addline(buffer, "void setup_gs_output(in vec4 shader_out[%u])\n{\n", gs->limits->packed_output); shader_glsl_setup_sm3_rasterizer_input(priv, gl_info, ps->u.ps.input_reg_map, &ps->input_signature, &ps->reg_maps, &gs->output_signature, &gs->reg_maps, FALSE); + shader_glsl_fixup_position(buffer); + shader_addline(buffer, "}\n"); ret = GL_EXTCALL(glCreateShader(GL_GEOMETRY_SHADER)); @@ -5761,23 +5791,7 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context if (args->point_size && !args->per_vertex_point_size) shader_addline(buffer, "gl_PointSize = clamp(ffp_point.size, ffp_point.size_min, ffp_point.size_max);\n"); - /* Write the final position. - * - * OpenGL coordinates specify the center of the pixel while d3d coords specify - * the corner. The offsets are stored in z and w in posFixup. posFixup.y contains - * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x - * contains 1.0 to allow a mad. - */ - shader_addline(buffer, "gl_Position.y = gl_Position.y * posFixup.y;\n"); - shader_addline(buffer, "gl_Position.xy += posFixup.zw * gl_Position.ww;\n"); - - /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c - * - * Basically we want (in homogeneous coordinates) z = z * 2 - 1. However, shaders are run - * before the homogeneous divide, so we have to take the w into account: z = ((z / w) * 2 - 1) * w, - * which is the same as z = z * 2 - w. - */ - shader_addline(buffer, "gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;\n"); + shader_glsl_fixup_position(buffer); shader_addline(buffer, "}\n"); @@ -7188,7 +7202,7 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info * vs->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); } - vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "posFixup")); + vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "pos_fixup")); for (i = 0; i < MAX_VERTEX_BLENDS; ++i) { @@ -7245,6 +7259,12 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info * string_buffer_release(&priv->string_buffers, name); } +static void shader_glsl_init_gs_uniform_locations(const struct wined3d_gl_info *gl_info, + struct shader_glsl_priv *priv, GLuint program_id, struct glsl_gs_program *gs) +{ + gs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "pos_fixup")); +} + static void shader_glsl_init_ps_uniform_locations(const struct wined3d_gl_info *gl_info, struct shader_glsl_priv *priv, GLuint program_id, struct glsl_ps_program *ps, unsigned int ps_c_count) { @@ -7539,6 +7559,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const shader_glsl_init_vs_uniform_locations(gl_info, priv, program_id, &entry->vs, vshader ? min(vshader->limits->constant_float, gl_info->limits.glsl_vs_float_constants) : 0); + shader_glsl_init_gs_uniform_locations(gl_info, priv, program_id, &entry->gs); shader_glsl_init_ps_uniform_locations(gl_info, priv, program_id, &entry->ps, pshader ? min(pshader->limits->constant_float, gl_info->limits.glsl_ps_float_constants) : 0); checkGLcall("Find glsl program uniform locations"); @@ -7580,7 +7601,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_I; if (vshader->reg_maps.boolean_constants) entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_B; - entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_POS_FIXUP; + entry->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP; shader_glsl_init_uniform_block_bindings(gl_info, priv, program_id, &vshader->reg_maps, 0, gl_info->limits.vertex_uniform_blocks); @@ -7619,8 +7640,11 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_POINTSIZE; if (gshader) + { + entry->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP; shader_glsl_init_uniform_block_bindings(gl_info, priv, program_id, &gshader->reg_maps, gl_info->limits.vertex_uniform_blocks, gl_info->limits.geometry_uniform_blocks); + } if (ps_id) { @@ -8711,7 +8735,7 @@ static void glsl_vertex_pipe_viewport(struct wined3d_context *context, if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)) && state->render_states[WINED3D_RS_POINTSCALEENABLE]) context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POINTSIZE; - context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POS_FIXUP; + context->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP; } static void glsl_vertex_pipe_texmatrix(struct wined3d_context *context, diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 44962fa..878de54 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -4608,7 +4608,7 @@ static void viewport_vertexpart(struct wined3d_context *context, const struct wi && state->render_states[WINED3D_RS_POINTSCALEENABLE]) state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)); /* Update the position fixup. */ - context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POS_FIXUP; + context->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP; } static void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index ebda4d6..c7b208e 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -331,7 +331,7 @@ enum wined3d_shader_resource_type #define WINED3D_SHADER_CONST_VS_I 0x00000002 #define WINED3D_SHADER_CONST_VS_B 0x00000004 #define WINED3D_SHADER_CONST_VS_POINTSIZE 0x00000008 -#define WINED3D_SHADER_CONST_VS_POS_FIXUP 0x00000010 +#define WINED3D_SHADER_CONST_POS_FIXUP 0x00000010 #define WINED3D_SHADER_CONST_PS_F 0x00000020 #define WINED3D_SHADER_CONST_PS_I 0x00000040 #define WINED3D_SHADER_CONST_PS_B 0x00000080 -- 2.7.3