I currently work on a simpler solution for Gallium. I'm using AMD_vertex_shader_layer and this vertex shader (I wrote it in TGSI though):
void main() { gl_Position = gl_Vertex; gl_TexCoord[0] = MultiTexCoord0; // clear color gl_Layer = gl_InstanceID; } Then I render the quad with DrawArraysInstanced and set the instance count = NumLayers. That way each instance (each quad) is sent to a different layer and everything is cleared in one draw call. Drivers not supporting AMD_vertex_shader_layer will have to use a GS though. Marek On Wed, Nov 20, 2013 at 5:47 AM, Paul Berry <stereotype...@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-sta...@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev