Mesa (master): meta: Use AMD_vertex_shader_layer instead of a GS for layered clears.

Kenneth Graunke kwg at kemper.freedesktop.org
Mon Jun 30 07:13:49 UTC 2014


Module: Mesa
Branch: master
Commit: 7577cdd8300068bdf1eda426951d7141450283aa
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7577cdd8300068bdf1eda426951d7141450283aa

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Sun Jun 22 22:27:49 2014 -0700

meta: Use AMD_vertex_shader_layer instead of a GS for layered clears.

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 universally.

Using AMD_vertex_shader_layer allows us to skip setting up the GS
altogether, while achieving the same effect.

According to Ilia, current nVidia GPUs can't do AMD_vertex_shader_layer.
However, since nouveau is Gallium-based, they're unlikely to ever care
about this path.  Intel and AMD GPUs both support the extension.

Since i965 is the only driver using this path which does layered
rendering, we may as well target it at that.

v2: Improve commit message.  No code changes.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
Reviewed-by: Chris Forbes <chrisf at ijw.co.nz>
Reviewed-by: Jordan Justen <jordan.l.justen at intel.com>

---

 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 1a2e453..f313f56 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);




More information about the mesa-commit mailing list