[PATCH 4/8] wined3d: Handle GS inputs and outputs.
Matteo Bruni
mbruni at codeweavers.com
Tue Apr 19 11:56:49 CDT 2016
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
---
It should be relatively easy to modify shader_glsl_generate_vs_gs_setup()
to make it also handle the VS->HS case (and, with some more work, also
DS->GS).
The other option would be to create new functions for those cases, most
of the code is in shader_glsl_setup_sm4_shader_output() anyway.
WRT HS->DS, there is the additional catch of per-patch variables. I
haven't thought much about it yet but I imagine it should be possible to
handle those in a similar fashion to the per-vertex variables in VS->GS.
Similar points for shader_glsl_generate_gs_rasterizer_input_setup() and
extending it to also handle DS->PS.
I think D3D requires to have both HS and DS or neither of them, which
would mean we don't have to handle a couple shader stages combinations
(compared to OpenGL).
dlls/wined3d/glsl_shader.c | 76 +++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 72 insertions(+), 4 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 0ab0936..c0a5e11 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -1952,6 +1952,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
else if (version->type == WINED3D_SHADER_TYPE_GEOMETRY)
{
shader_addline(buffer, "varying in vec4 gs_in[][%u];\n", shader->limits->packed_input);
+ shader_addline(buffer, "void setup_gs_output(in vec4[%u]);\n", shader->limits->packed_output);
}
else if (version->type == WINED3D_SHADER_TYPE_PIXEL)
{
@@ -4132,6 +4133,7 @@ static void shader_glsl_else(const struct wined3d_shader_instruction *ins)
static void shader_glsl_emit(const struct wined3d_shader_instruction *ins)
{
+ shader_addline(ins->ctx->buffer, "setup_gs_output(gs_out);\n");
shader_addline(ins->ctx->buffer, "EmitVertex();\n");
}
@@ -5471,6 +5473,60 @@ static GLuint shader_glsl_generate_vs_rasterizer_input_setup(struct shader_glsl_
return ret;
}
+/* 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,
+ const struct wined3d_gl_info *gl_info)
+{
+ struct wined3d_string_buffer *buffer = &priv->shader_buffer;
+ GLuint ret;
+
+ string_buffer_clear(buffer);
+
+ shader_addline(buffer, "%s\n", shader_glsl_get_version(gl_info, &vs->reg_maps.shader_version));
+
+ shader_addline(buffer, "varying out vec4 gs_in[%u];\n", gs->limits->packed_input);
+ shader_addline(buffer, "void setup_vs_output(in vec4 shader_out[%u])\n{\n", vs->limits->packed_output);
+
+ shader_glsl_setup_sm4_shader_output(priv, &vs->output_signature, &vs->reg_maps, "gs_in");
+
+ shader_addline(buffer, "}\n");
+
+ ret = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
+ checkGLcall("glCreateShader(GL_VERTEX_SHADER)");
+ shader_glsl_compile(gl_info, ret, buffer->buffer);
+
+ return ret;
+}
+
+/* Context activation is done by the caller. */
+static GLuint shader_glsl_generate_gs_rasterizer_input_setup(struct shader_glsl_priv *priv,
+ const struct wined3d_shader *gs, const struct wined3d_shader *ps,
+ const struct wined3d_gl_info *gl_info)
+{
+ unsigned int in_count = min(vec4_varyings(4, gl_info), ps->limits->packed_input);
+ struct wined3d_string_buffer *buffer = &priv->shader_buffer;
+ GLuint ret;
+
+ string_buffer_clear(buffer);
+
+ 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, "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_addline(buffer, "}\n");
+
+ ret = GL_EXTCALL(glCreateShader(GL_GEOMETRY_SHADER));
+ checkGLcall("glCreateShader(GL_GEOMETRY_SHADER)");
+ shader_glsl_compile(gl_info, ret, buffer->buffer);
+
+ return ret;
+}
+
static void shader_glsl_generate_srgb_write_correction(struct wined3d_string_buffer *buffer,
const struct wined3d_gl_info *gl_info)
{
@@ -7395,10 +7451,17 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
if (vshader)
{
attribs_map = vshader->reg_maps.input_registers;
- reorder_shader_id = shader_glsl_generate_vs_rasterizer_input_setup(priv, vshader, pshader,
- state->gl_primitive_type == GL_POINTS && vshader->reg_maps.point_size,
- d3d_info->emulated_flatshading
- && state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT, gl_info);
+ if (gshader)
+ {
+ reorder_shader_id = shader_glsl_generate_vs_gs_setup(priv, vshader, gshader, gl_info);
+ }
+ else
+ {
+ reorder_shader_id = shader_glsl_generate_vs_rasterizer_input_setup(priv, vshader, pshader,
+ state->gl_primitive_type == GL_POINTS && vshader->reg_maps.point_size,
+ d3d_info->emulated_flatshading
+ && state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT, gl_info);
+ }
TRACE("Attaching GLSL shader object %u to program %u.\n", reorder_shader_id, program_id);
GL_EXTCALL(glAttachShader(program_id, reorder_shader_id));
checkGLcall("glAttachShader");
@@ -7439,6 +7502,11 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
GL_EXTCALL(glAttachShader(program_id, gs_id));
checkGLcall("glAttachShader");
+ reorder_shader_id = shader_glsl_generate_gs_rasterizer_input_setup(priv, gshader, pshader, gl_info);
+ TRACE("Attaching GLSL shader object %u to program %u.\n", reorder_shader_id, program_id);
+ GL_EXTCALL(glAttachShader(program_id, reorder_shader_id));
+ checkGLcall("glAttachShader");
+
TRACE("input type %s, output type %s, vertices out %u.\n",
debug_d3dprimitivetype(gshader->u.gs.input_type),
debug_d3dprimitivetype(gshader->u.gs.output_type),
--
2.7.3
More information about the wine-patches
mailing list