[Mesa-dev] [PATCH 2/5] meta: fix meta clear of layered framebuffers

Chris Forbes chrisf at ijw.co.nz
Wed Nov 20 01:28:46 PST 2013


If I'm reading this right, there is now *always* a GS in the clear
program, if the driver can support it -- is this possibly silly, given
that most clears will be nonlayered?

My understanding is that switching the GS stage on and off carries
pretty severe penalties on some hardware.

It might be that this turns out not to be a factor, if everyone tries
to use a better clear path than meta.

-- Chris

On Wed, Nov 20, 2013 at 5:47 PM, Paul Berry <stereotype441 at gmail.com> wrote:
> From section 4.4.7 (Layered Framebuffers) of the GLSL 3.2 spec:
>
>     When the Clear or ClearBuffer* commands are used to clear a
>     layered framebuffer attachment, all layers of the attachment are
>     cleared.
>
> This patch fixes meta clears to properly clear all layers of a layered
> framebuffer attachment.  We accomplish this by adding a geometry
> shader to the meta clear program which sets gl_Layer to a uniform
> value.  When clearing a layered framebuffer, we execute in a loop,
> setting the uniform to point to each layer in turn.
>
> Cc: "10.0" <mesa-stable at lists.freedesktop.org>
> ---
>  src/mesa/drivers/common/meta.c | 51 +++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 48 insertions(+), 3 deletions(-)
>
> diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
> index 99b02ba..a6d5098 100644
> --- a/src/mesa/drivers/common/meta.c
> +++ b/src/mesa/drivers/common/meta.c
> @@ -241,9 +241,11 @@ struct clear_state
>     GLuint VBO;
>     GLuint ShaderProg;
>     GLint ColorLocation;
> +   GLint LayerLocation;
>
>     GLuint IntegerShaderProg;
>     GLint IntegerColorLocation;
> +   GLint IntegerLayerLocation;
>  };
>
>
> @@ -2145,6 +2147,19 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
>        "{\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"
> +      "}\n";
>     const char *fs_source =
>        "#ifdef GL_ES\n"
>        "precision highp float;\n"
> @@ -2154,7 +2169,7 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
>        "{\n"
>        "   gl_FragColor = color;\n"
>        "}\n";
> -   GLuint vs, fs;
> +   GLuint vs, gs = 0, fs;
>     bool has_integer_textures;
>
>     if (clear->ArrayObj != 0)
> @@ -2176,6 +2191,12 @@ 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_CreateShaderObjectARB(GL_GEOMETRY_SHADER);
> +      _mesa_ShaderSource(gs, 1, &gs_source, NULL);
> +      _mesa_CompileShader(gs);
> +   }
> +
>     fs = _mesa_CreateShaderObjectARB(GL_FRAGMENT_SHADER);
>     _mesa_ShaderSource(fs, 1, &fs_source, NULL);
>     _mesa_CompileShader(fs);
> @@ -2183,6 +2204,8 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
>     clear->ShaderProg = _mesa_CreateProgramObjectARB();
>     _mesa_AttachShader(clear->ShaderProg, fs);
>     _mesa_DeleteObjectARB(fs);
> +   if (gs != 0)
> +      _mesa_AttachShader(clear->ShaderProg, gs);
>     _mesa_AttachShader(clear->ShaderProg, vs);
>     _mesa_DeleteObjectARB(vs);
>     _mesa_BindAttribLocation(clear->ShaderProg, 0, "position");
> @@ -2190,6 +2213,10 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
>
>     clear->ColorLocation = _mesa_GetUniformLocation(clear->ShaderProg,
>                                                       "color");
> +   if (gs != 0) {
> +      clear->LayerLocation = _mesa_GetUniformLocation(clear->ShaderProg,
> +                                                     "layer");
> +   }
>
>     has_integer_textures = _mesa_is_gles3(ctx) ||
>        (_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130);
> @@ -2227,6 +2254,8 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
>        clear->IntegerShaderProg = _mesa_CreateProgramObjectARB();
>        _mesa_AttachShader(clear->IntegerShaderProg, fs);
>        _mesa_DeleteObjectARB(fs);
> +      if (gs != 0)
> +         _mesa_AttachShader(clear->IntegerShaderProg, gs);
>        _mesa_AttachShader(clear->IntegerShaderProg, vs);
>        _mesa_DeleteObjectARB(vs);
>        _mesa_BindAttribLocation(clear->IntegerShaderProg, 0, "position");
> @@ -2240,7 +2269,13 @@ 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");
> +      }
>     }
> +   if (gs != 0)
> +      _mesa_DeleteObjectARB(gs);
>  }
>
>  static void
> @@ -2371,8 +2406,18 @@ _mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers)
>     _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
>                        GL_DYNAMIC_DRAW_ARB);
>
> -   /* draw quad */
> -   _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
> +   /* draw quad(s) */
> +   if (fb->Layered) {
> +      for (unsigned layer = 0; layer < fb->NumLayers; layer++) {
> +         if (fb->_IntegerColor)
> +            _mesa_Uniform1i(clear->IntegerLayerLocation, layer);
> +         else
> +            _mesa_Uniform1i(clear->LayerLocation, layer);
> +         _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
> +      }
> +   } else {
> +      _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
> +   }
>
>     _mesa_meta_end(ctx);
>  }
> --
> 1.8.4.2
>
> _______________________________________________
> 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