[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