[Mesa-dev] [PATCH] meta: Use AMD_vertex_shader_layer instead of a GS for layered clears.

Jordan Justen jljusten at gmail.com
Thu Jun 26 11:55:14 PDT 2014


Reviewed-by: Jordan Justen <jordan.l.justen at intel.com>

On Sun, Jun 22, 2014 at 10:27 PM, Kenneth Graunke <kenneth at whitecape.org> wrote:
> On i965, enabling and disabling the GS is not free: you have to do a
> full pipeline stall, reconfigure the URB and push constant space, and
> emit a bunch of state.  Most clears aren't layered, so the GS isn't
> needed in the common case.  But we turned it on anyway.
>
> As far as I know, most GPUs that support layered rendering can support
> the GL_AMD_vertex_shader_layer extension.  i965 does, and it's also the
> only driver using this path that does layered rendering.  Doing so
> allows us to skip setting up the GS.
>
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> ---
>  src/mesa/drivers/common/meta.c | 53 +++++++++++++-----------------------------
>  1 file changed, 16 insertions(+), 37 deletions(-)
>
> diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
> index cab0dd8..a4634a3 100644
> --- a/src/mesa/drivers/common/meta.c
> +++ b/src/mesa/drivers/common/meta.c
> @@ -1515,23 +1515,15 @@ static void
>  meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
>  {
>     const char *vs_source =
> +      "#extension GL_AMD_vertex_shader_layer : enable\n"
>        "attribute vec4 position;\n"
> -      "void main()\n"
> -      "{\n"
> -      "   gl_Position = position;\n"
> -      "}\n";
> -   const char *gs_source =
> -      "#version 150\n"
> -      "layout(triangles) in;\n"
> -      "layout(triangle_strip, max_vertices = 4) out;\n"
>        "uniform int layer;\n"
>        "void main()\n"
>        "{\n"
> -      "  for (int i = 0; i < 3; i++) {\n"
> -      "    gl_Layer = layer;\n"
> -      "    gl_Position = gl_in[i].gl_Position;\n"
> -      "    EmitVertex();\n"
> -      "  }\n"
> +      "#ifdef GL_AMD_vertex_shader_layer\n"
> +      "   gl_Layer = layer;\n"
> +      "#endif\n"
> +      "   gl_Position = position;\n"
>        "}\n";
>     const char *fs_source =
>        "uniform vec4 color;\n"
> @@ -1539,7 +1531,7 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
>        "{\n"
>        "   gl_FragColor = color;\n"
>        "}\n";
> -   GLuint vs, gs = 0, fs;
> +   GLuint vs, fs;
>     bool has_integer_textures;
>
>     _mesa_meta_setup_vertex_objects(&clear->VAO, &clear->VBO, true, 3, 0, 0);
> @@ -1551,12 +1543,6 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
>     _mesa_ShaderSource(vs, 1, &vs_source, NULL);
>     _mesa_CompileShader(vs);
>
> -   if (_mesa_has_geometry_shaders(ctx)) {
> -      gs = _mesa_CreateShader(GL_GEOMETRY_SHADER);
> -      _mesa_ShaderSource(gs, 1, &gs_source, NULL);
> -      _mesa_CompileShader(gs);
> -   }
> -
>     fs = _mesa_CreateShader(GL_FRAGMENT_SHADER);
>     _mesa_ShaderSource(fs, 1, &fs_source, NULL);
>     _mesa_CompileShader(fs);
> @@ -1564,20 +1550,14 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
>     clear->ShaderProg = _mesa_CreateProgram();
>     _mesa_AttachShader(clear->ShaderProg, fs);
>     _mesa_DeleteShader(fs);
> -   if (gs != 0)
> -      _mesa_AttachShader(clear->ShaderProg, gs);
>     _mesa_AttachShader(clear->ShaderProg, vs);
>     _mesa_DeleteShader(vs);
>     _mesa_BindAttribLocation(clear->ShaderProg, 0, "position");
>     _mesa_ObjectLabel(GL_PROGRAM, clear->ShaderProg, -1, "meta clear");
>     _mesa_LinkProgram(clear->ShaderProg);
>
> -   clear->ColorLocation = _mesa_GetUniformLocation(clear->ShaderProg,
> -                                                     "color");
> -   if (gs != 0) {
> -      clear->LayerLocation = _mesa_GetUniformLocation(clear->ShaderProg,
> -                                                     "layer");
> -   }
> +   clear->ColorLocation = _mesa_GetUniformLocation(clear->ShaderProg, "color");
> +   clear->LayerLocation = _mesa_GetUniformLocation(clear->ShaderProg, "layer");
>
>     has_integer_textures = _mesa_is_gles3(ctx) ||
>        (_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130);
> @@ -1587,9 +1567,14 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
>        const char *vs_int_source =
>           ralloc_asprintf(shader_source_mem_ctx,
>                           "#version 130\n"
> +                         "#extension GL_AMD_vertex_shader_layer : enable\n"
>                           "in vec4 position;\n"
> +                         "uniform int layer;\n"
>                           "void main()\n"
>                           "{\n"
> +                         "#ifdef GL_AMD_vertex_shader_layer\n"
> +                         "   gl_Layer = layer;\n"
> +                         "#endif\n"
>                           "   gl_Position = position;\n"
>                           "}\n");
>        const char *fs_int_source =
> @@ -1612,8 +1597,6 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
>        clear->IntegerShaderProg = _mesa_CreateProgram();
>        _mesa_AttachShader(clear->IntegerShaderProg, fs);
>        _mesa_DeleteShader(fs);
> -      if (gs != 0)
> -         _mesa_AttachShader(clear->IntegerShaderProg, gs);
>        _mesa_AttachShader(clear->IntegerShaderProg, vs);
>        _mesa_DeleteShader(vs);
>        _mesa_BindAttribLocation(clear->IntegerShaderProg, 0, "position");
> @@ -1629,13 +1612,9 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
>
>        clear->IntegerColorLocation =
>          _mesa_GetUniformLocation(clear->IntegerShaderProg, "color");
> -      if (gs != 0) {
> -         clear->IntegerLayerLocation =
> -            _mesa_GetUniformLocation(clear->IntegerShaderProg, "layer");
> -      }
> +      clear->IntegerLayerLocation =
> +         _mesa_GetUniformLocation(clear->IntegerShaderProg, "layer");
>     }
> -   if (gs != 0)
> -      _mesa_DeleteShader(gs);
>  }
>
>  static void
> @@ -1843,7 +1822,7 @@ meta_clear(struct gl_context *ctx, GLbitfield buffers, bool glsl)
>     /* draw quad(s) */
>     if (fb->MaxNumLayers > 0) {
>        unsigned layer;
> -      assert(glsl);
> +      assert(glsl && clear->LayerLocation != -1);
>        for (layer = 0; layer < fb->MaxNumLayers; layer++) {
>           if (fb->_IntegerColor)
>              _mesa_Uniform1i(clear->IntegerLayerLocation, layer);
> --
> 2.0.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list