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

Paul Berry stereotype441 at gmail.com
Wed Nov 20 14:22:39 PST 2013


On 20 November 2013 01:28, Chris Forbes <chrisf at ijw.co.nz> wrote:

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

I'd be curious to hear more about this.  I'm not aware of it carrying
severe penalties on i965, for example.


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

I suspect this is the case.  i965 uses a blorp-based clear in most
circumstances, and only falls back on Meta if that fails for some reason.
Gallium-based drivers don't use Meta at all.  IIRC, the only other driver
that uses Meta is i915, which doesn't support geometry shaders so it won't
be affected by these changes.


>
> -- 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20131120/aa7caa39/attachment-0001.html>


More information about the mesa-dev mailing list