[PATCH 5/8] wined3d: Fixup vertex position in geometry shaders.
Matteo Bruni
mbruni at codeweavers.com
Tue Apr 19 11:56:50 CDT 2016
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
---
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
More information about the wine-patches
mailing list