summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2014-06-22 22:27:49 -0700
committerKenneth Graunke <[email protected]>2014-06-30 00:08:54 -0700
commit7577cdd8300068bdf1eda426951d7141450283aa (patch)
tree545c6133c9922612147d1e431d6daa668e6d2d65
parentf3c5b2f7d08f8a2a41df0a224cd6600ce4260fa1 (diff)
meta: Use AMD_vertex_shader_layer instead of a GS for layered clears.
On i965, enabling and disabling the GS is not free: you have to do a full pipeline stall, reconfigure the URB and push constant space, and emit a bunch of state. Most clears aren't layered, so the GS isn't needed in the common case. But we turned it on universally. Using AMD_vertex_shader_layer allows us to skip setting up the GS altogether, while achieving the same effect. According to Ilia, current nVidia GPUs can't do AMD_vertex_shader_layer. However, since nouveau is Gallium-based, they're unlikely to ever care about this path. Intel and AMD GPUs both support the extension. Since i965 is the only driver using this path which does layered rendering, we may as well target it at that. v2: Improve commit message. No code changes. Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Chris Forbes <[email protected]> Reviewed-by: Jordan Justen <[email protected]>
-rw-r--r--src/mesa/drivers/common/meta.c53
1 files changed, 16 insertions, 37 deletions
diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index 1a2e4532058..f313f5645b4 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -1515,23 +1515,15 @@ static void
meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
{
const char *vs_source =
+ "#extension GL_AMD_vertex_shader_layer : enable\n"
"attribute vec4 position;\n"
- "void main()\n"
- "{\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"
+ "#ifdef GL_AMD_vertex_shader_layer\n"
+ " gl_Layer = layer;\n"
+ "#endif\n"
+ " gl_Position = position;\n"
"}\n";
const char *fs_source =
"uniform vec4 color;\n"
@@ -1539,7 +1531,7 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
"{\n"
" gl_FragColor = color;\n"
"}\n";
- GLuint vs, gs = 0, fs;
+ GLuint vs, fs;
bool has_integer_textures;
_mesa_meta_setup_vertex_objects(&clear->VAO, &clear->VBO, true, 3, 0, 0);
@@ -1551,12 +1543,6 @@ 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_CreateShader(GL_GEOMETRY_SHADER);
- _mesa_ShaderSource(gs, 1, &gs_source, NULL);
- _mesa_CompileShader(gs);
- }
-
fs = _mesa_CreateShader(GL_FRAGMENT_SHADER);
_mesa_ShaderSource(fs, 1, &fs_source, NULL);
_mesa_CompileShader(fs);
@@ -1564,20 +1550,14 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
clear->ShaderProg = _mesa_CreateProgram();
_mesa_AttachShader(clear->ShaderProg, fs);
_mesa_DeleteShader(fs);
- if (gs != 0)
- _mesa_AttachShader(clear->ShaderProg, gs);
_mesa_AttachShader(clear->ShaderProg, vs);
_mesa_DeleteShader(vs);
_mesa_BindAttribLocation(clear->ShaderProg, 0, "position");
_mesa_ObjectLabel(GL_PROGRAM, clear->ShaderProg, -1, "meta clear");
_mesa_LinkProgram(clear->ShaderProg);
- clear->ColorLocation = _mesa_GetUniformLocation(clear->ShaderProg,
- "color");
- if (gs != 0) {
- clear->LayerLocation = _mesa_GetUniformLocation(clear->ShaderProg,
- "layer");
- }
+ clear->ColorLocation = _mesa_GetUniformLocation(clear->ShaderProg, "color");
+ clear->LayerLocation = _mesa_GetUniformLocation(clear->ShaderProg, "layer");
has_integer_textures = _mesa_is_gles3(ctx) ||
(_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130);
@@ -1587,9 +1567,14 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
const char *vs_int_source =
ralloc_asprintf(shader_source_mem_ctx,
"#version 130\n"
+ "#extension GL_AMD_vertex_shader_layer : enable\n"
"in vec4 position;\n"
+ "uniform int layer;\n"
"void main()\n"
"{\n"
+ "#ifdef GL_AMD_vertex_shader_layer\n"
+ " gl_Layer = layer;\n"
+ "#endif\n"
" gl_Position = position;\n"
"}\n");
const char *fs_int_source =
@@ -1612,8 +1597,6 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
clear->IntegerShaderProg = _mesa_CreateProgram();
_mesa_AttachShader(clear->IntegerShaderProg, fs);
_mesa_DeleteShader(fs);
- if (gs != 0)
- _mesa_AttachShader(clear->IntegerShaderProg, gs);
_mesa_AttachShader(clear->IntegerShaderProg, vs);
_mesa_DeleteShader(vs);
_mesa_BindAttribLocation(clear->IntegerShaderProg, 0, "position");
@@ -1629,13 +1612,9 @@ 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");
- }
+ clear->IntegerLayerLocation =
+ _mesa_GetUniformLocation(clear->IntegerShaderProg, "layer");
}
- if (gs != 0)
- _mesa_DeleteShader(gs);
}
static void
@@ -1843,7 +1822,7 @@ meta_clear(struct gl_context *ctx, GLbitfield buffers, bool glsl)
/* draw quad(s) */
if (fb->MaxNumLayers > 0) {
unsigned layer;
- assert(glsl);
+ assert(glsl && clear->LayerLocation != -1);
for (layer = 0; layer < fb->MaxNumLayers; layer++) {
if (fb->_IntegerColor)
_mesa_Uniform1i(clear->IntegerLayerLocation, layer);