<div dir="ltr">On 20 November 2013 01:28, Chris Forbes <span dir="ltr"><<a href="mailto:chrisf@ijw.co.nz" target="_blank">chrisf@ijw.co.nz</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
If I'm reading this right, there is now *always* a GS in the clear<br>
program, if the driver can support it -- is this possibly silly, given<br>
that most clears will be nonlayered?<br>
<br>
My understanding is that switching the GS stage on and off carries<br>
pretty severe penalties on some hardware.<br></blockquote><div><br></div><div>I'd be curious to hear more about this. I'm not aware of it carrying severe penalties on i965, for example.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
It might be that this turns out not to be a factor, if everyone tries<br>
to use a better clear path than meta.<br></blockquote><div><br></div><div>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.<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
-- Chris<br>
<div><div class="h5"><br>
On Wed, Nov 20, 2013 at 5:47 PM, Paul Berry <<a href="mailto:stereotype441@gmail.com">stereotype441@gmail.com</a>> wrote:<br>
> From section 4.4.7 (Layered Framebuffers) of the GLSL 3.2 spec:<br>
><br>
> When the Clear or ClearBuffer* commands are used to clear a<br>
> layered framebuffer attachment, all layers of the attachment are<br>
> cleared.<br>
><br>
> This patch fixes meta clears to properly clear all layers of a layered<br>
> framebuffer attachment. We accomplish this by adding a geometry<br>
> shader to the meta clear program which sets gl_Layer to a uniform<br>
> value. When clearing a layered framebuffer, we execute in a loop,<br>
> setting the uniform to point to each layer in turn.<br>
><br>
> Cc: "10.0" <<a href="mailto:mesa-stable@lists.freedesktop.org">mesa-stable@lists.freedesktop.org</a>><br>
> ---<br>
> src/mesa/drivers/common/meta.c | 51 +++++++++++++++++++++++++++++++++++++++---<br>
> 1 file changed, 48 insertions(+), 3 deletions(-)<br>
><br>
> diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c<br>
> index 99b02ba..a6d5098 100644<br>
> --- a/src/mesa/drivers/common/meta.c<br>
> +++ b/src/mesa/drivers/common/meta.c<br>
> @@ -241,9 +241,11 @@ struct clear_state<br>
> GLuint VBO;<br>
> GLuint ShaderProg;<br>
> GLint ColorLocation;<br>
> + GLint LayerLocation;<br>
><br>
> GLuint IntegerShaderProg;<br>
> GLint IntegerColorLocation;<br>
> + GLint IntegerLayerLocation;<br>
> };<br>
><br>
><br>
> @@ -2145,6 +2147,19 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)<br>
> "{\n"<br>
> " gl_Position = position;\n"<br>
> "}\n";<br>
> + const char *gs_source =<br>
> + "#version 150\n"<br>
> + "layout(triangles) in;\n"<br>
> + "layout(triangle_strip, max_vertices = 4) out;\n"<br>
> + "uniform int layer;\n"<br>
> + "void main()\n"<br>
> + "{\n"<br>
> + " for (int i = 0; i < 3; i++) {\n"<br>
> + " gl_Layer = layer;\n"<br>
> + " gl_Position = gl_in[i].gl_Position;\n"<br>
> + " EmitVertex();\n"<br>
> + " }\n"<br>
> + "}\n";<br>
> const char *fs_source =<br>
> "#ifdef GL_ES\n"<br>
> "precision highp float;\n"<br>
> @@ -2154,7 +2169,7 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)<br>
> "{\n"<br>
> " gl_FragColor = color;\n"<br>
> "}\n";<br>
> - GLuint vs, fs;<br>
> + GLuint vs, gs = 0, fs;<br>
> bool has_integer_textures;<br>
><br>
> if (clear->ArrayObj != 0)<br>
> @@ -2176,6 +2191,12 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)<br>
> _mesa_ShaderSource(vs, 1, &vs_source, NULL);<br>
> _mesa_CompileShader(vs);<br>
><br>
> + if (_mesa_has_geometry_shaders(ctx)) {<br>
> + gs = _mesa_CreateShaderObjectARB(GL_GEOMETRY_SHADER);<br>
> + _mesa_ShaderSource(gs, 1, &gs_source, NULL);<br>
> + _mesa_CompileShader(gs);<br>
> + }<br>
> +<br>
> fs = _mesa_CreateShaderObjectARB(GL_FRAGMENT_SHADER);<br>
> _mesa_ShaderSource(fs, 1, &fs_source, NULL);<br>
> _mesa_CompileShader(fs);<br>
> @@ -2183,6 +2204,8 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)<br>
> clear->ShaderProg = _mesa_CreateProgramObjectARB();<br>
> _mesa_AttachShader(clear->ShaderProg, fs);<br>
> _mesa_DeleteObjectARB(fs);<br>
> + if (gs != 0)<br>
> + _mesa_AttachShader(clear->ShaderProg, gs);<br>
> _mesa_AttachShader(clear->ShaderProg, vs);<br>
> _mesa_DeleteObjectARB(vs);<br>
> _mesa_BindAttribLocation(clear->ShaderProg, 0, "position");<br>
> @@ -2190,6 +2213,10 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)<br>
><br>
> clear->ColorLocation = _mesa_GetUniformLocation(clear->ShaderProg,<br>
> "color");<br>
> + if (gs != 0) {<br>
> + clear->LayerLocation = _mesa_GetUniformLocation(clear->ShaderProg,<br>
> + "layer");<br>
> + }<br>
><br>
> has_integer_textures = _mesa_is_gles3(ctx) ||<br>
> (_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130);<br>
> @@ -2227,6 +2254,8 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)<br>
> clear->IntegerShaderProg = _mesa_CreateProgramObjectARB();<br>
> _mesa_AttachShader(clear->IntegerShaderProg, fs);<br>
> _mesa_DeleteObjectARB(fs);<br>
> + if (gs != 0)<br>
> + _mesa_AttachShader(clear->IntegerShaderProg, gs);<br>
> _mesa_AttachShader(clear->IntegerShaderProg, vs);<br>
> _mesa_DeleteObjectARB(vs);<br>
> _mesa_BindAttribLocation(clear->IntegerShaderProg, 0, "position");<br>
> @@ -2240,7 +2269,13 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)<br>
><br>
> clear->IntegerColorLocation =<br>
> _mesa_GetUniformLocation(clear->IntegerShaderProg, "color");<br>
> + if (gs != 0) {<br>
> + clear->IntegerLayerLocation =<br>
> + _mesa_GetUniformLocation(clear->IntegerShaderProg, "layer");<br>
> + }<br>
> }<br>
> + if (gs != 0)<br>
> + _mesa_DeleteObjectARB(gs);<br>
> }<br>
><br>
> static void<br>
> @@ -2371,8 +2406,18 @@ _mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers)<br>
> _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,<br>
> GL_DYNAMIC_DRAW_ARB);<br>
><br>
> - /* draw quad */<br>
> - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);<br>
> + /* draw quad(s) */<br>
> + if (fb->Layered) {<br>
> + for (unsigned layer = 0; layer < fb->NumLayers; layer++) {<br>
> + if (fb->_IntegerColor)<br>
> + _mesa_Uniform1i(clear->IntegerLayerLocation, layer);<br>
> + else<br>
> + _mesa_Uniform1i(clear->LayerLocation, layer);<br>
> + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);<br>
> + }<br>
> + } else {<br>
> + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);<br>
> + }<br>
><br>
> _mesa_meta_end(ctx);<br>
> }<br>
> --<br>
> 1.8.4.2<br>
><br>
</div></div>> _______________________________________________<br>
> mesa-dev mailing list<br>
> <a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> <a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</blockquote></div><br></div></div>