From: Matteo Bruni Subject: [PATCH 4/8] wined3d: Handle GS inputs and outputs. Message-Id: <1461085013-7434-4-git-send-email-mbruni@codeweavers.com> Date: Tue, 19 Apr 2016 18:56:49 +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 --- 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