[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