mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 17:50:12 +01:00
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>
This commit is contained in:
parent
95140740ad
commit
068a073c1d
1 changed files with 48 additions and 3 deletions
|
|
@ -241,9 +241,11 @@ struct clear_state
|
||||||
GLuint VBO;
|
GLuint VBO;
|
||||||
GLuint ShaderProg;
|
GLuint ShaderProg;
|
||||||
GLint ColorLocation;
|
GLint ColorLocation;
|
||||||
|
GLint LayerLocation;
|
||||||
|
|
||||||
GLuint IntegerShaderProg;
|
GLuint IntegerShaderProg;
|
||||||
GLint IntegerColorLocation;
|
GLint IntegerColorLocation;
|
||||||
|
GLint IntegerLayerLocation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2145,6 +2147,19 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
|
||||||
"{\n"
|
"{\n"
|
||||||
" gl_Position = position;\n"
|
" gl_Position = position;\n"
|
||||||
"}\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 =
|
const char *fs_source =
|
||||||
"#ifdef GL_ES\n"
|
"#ifdef GL_ES\n"
|
||||||
"precision highp float;\n"
|
"precision highp float;\n"
|
||||||
|
|
@ -2154,7 +2169,7 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
|
||||||
"{\n"
|
"{\n"
|
||||||
" gl_FragColor = color;\n"
|
" gl_FragColor = color;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
GLuint vs, fs;
|
GLuint vs, gs = 0, fs;
|
||||||
bool has_integer_textures;
|
bool has_integer_textures;
|
||||||
|
|
||||||
if (clear->ArrayObj != 0)
|
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_ShaderSource(vs, 1, &vs_source, NULL);
|
||||||
_mesa_CompileShader(vs);
|
_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);
|
fs = _mesa_CreateShaderObjectARB(GL_FRAGMENT_SHADER);
|
||||||
_mesa_ShaderSource(fs, 1, &fs_source, NULL);
|
_mesa_ShaderSource(fs, 1, &fs_source, NULL);
|
||||||
_mesa_CompileShader(fs);
|
_mesa_CompileShader(fs);
|
||||||
|
|
@ -2183,6 +2204,8 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
|
||||||
clear->ShaderProg = _mesa_CreateProgramObjectARB();
|
clear->ShaderProg = _mesa_CreateProgramObjectARB();
|
||||||
_mesa_AttachShader(clear->ShaderProg, fs);
|
_mesa_AttachShader(clear->ShaderProg, fs);
|
||||||
_mesa_DeleteObjectARB(fs);
|
_mesa_DeleteObjectARB(fs);
|
||||||
|
if (gs != 0)
|
||||||
|
_mesa_AttachShader(clear->ShaderProg, gs);
|
||||||
_mesa_AttachShader(clear->ShaderProg, vs);
|
_mesa_AttachShader(clear->ShaderProg, vs);
|
||||||
_mesa_DeleteObjectARB(vs);
|
_mesa_DeleteObjectARB(vs);
|
||||||
_mesa_BindAttribLocation(clear->ShaderProg, 0, "position");
|
_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,
|
clear->ColorLocation = _mesa_GetUniformLocation(clear->ShaderProg,
|
||||||
"color");
|
"color");
|
||||||
|
if (gs != 0) {
|
||||||
|
clear->LayerLocation = _mesa_GetUniformLocation(clear->ShaderProg,
|
||||||
|
"layer");
|
||||||
|
}
|
||||||
|
|
||||||
has_integer_textures = _mesa_is_gles3(ctx) ||
|
has_integer_textures = _mesa_is_gles3(ctx) ||
|
||||||
(_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130);
|
(_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();
|
clear->IntegerShaderProg = _mesa_CreateProgramObjectARB();
|
||||||
_mesa_AttachShader(clear->IntegerShaderProg, fs);
|
_mesa_AttachShader(clear->IntegerShaderProg, fs);
|
||||||
_mesa_DeleteObjectARB(fs);
|
_mesa_DeleteObjectARB(fs);
|
||||||
|
if (gs != 0)
|
||||||
|
_mesa_AttachShader(clear->IntegerShaderProg, gs);
|
||||||
_mesa_AttachShader(clear->IntegerShaderProg, vs);
|
_mesa_AttachShader(clear->IntegerShaderProg, vs);
|
||||||
_mesa_DeleteObjectARB(vs);
|
_mesa_DeleteObjectARB(vs);
|
||||||
_mesa_BindAttribLocation(clear->IntegerShaderProg, 0, "position");
|
_mesa_BindAttribLocation(clear->IntegerShaderProg, 0, "position");
|
||||||
|
|
@ -2240,8 +2269,14 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
|
||||||
|
|
||||||
clear->IntegerColorLocation =
|
clear->IntegerColorLocation =
|
||||||
_mesa_GetUniformLocation(clear->IntegerShaderProg, "color");
|
_mesa_GetUniformLocation(clear->IntegerShaderProg, "color");
|
||||||
|
if (gs != 0) {
|
||||||
|
clear->IntegerLayerLocation =
|
||||||
|
_mesa_GetUniformLocation(clear->IntegerShaderProg, "layer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (gs != 0)
|
||||||
|
_mesa_DeleteObjectARB(gs);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear)
|
meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear)
|
||||||
|
|
@ -2371,8 +2406,18 @@ _mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers)
|
||||||
_mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
|
_mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
|
||||||
GL_DYNAMIC_DRAW_ARB);
|
GL_DYNAMIC_DRAW_ARB);
|
||||||
|
|
||||||
/* draw quad */
|
/* 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);
|
_mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
|
}
|
||||||
|
|
||||||
_mesa_meta_end(ctx);
|
_mesa_meta_end(ctx);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue