summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Berry <stereotype441@gmail.com>2013-11-19 13:31:20 -0800
committerPaul Berry <stereotype441@gmail.com>2013-11-21 18:16:34 -0800
commit068a073c1d4853b5c8f33efdeb481026f42e23a5 (patch)
treefc9e9592ff3401705c35cc98b1577f78b3c639b9
parent95140740ad1c6cd8a34002c307556f5c49a34589 (diff)
meta: fix meta clear of layered framebuffers
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@lists.freedesktop.org> Reviewed-by: Eric Anholt <eric@anholt.net> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
-rw-r--r--src/mesa/drivers/common/meta.c51
1 files changed, 48 insertions, 3 deletions
diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index 99b02baadc5..0c05cc02596 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->NumLayers > 0) {
+ 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);
}