[Mesa-dev] [PATCH 08/10] meta: Add support for glClear() to integer color buffers.
Eric Anholt
eric at anholt.net
Fri Nov 4 15:01:29 PDT 2011
This requires using a new fragment shader to get the integer color
output, and a new vertex shader because #version has to match between
the two.
---
src/mesa/drivers/common/meta.c | 108 ++++++++++++++++++++++++++++++++++++++--
1 files changed, 104 insertions(+), 4 deletions(-)
diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index 3e55334..fcff0ae 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -182,7 +182,6 @@ struct save_state
GLboolean Lighting;
};
-
/**
* Temporary texture used for glBlitFramebuffer, glDrawPixels, etc.
* This is currently shared by all the meta ops. But we could create a
@@ -221,6 +220,9 @@ struct clear_state
GLuint VBO;
GLuint ShaderProg;
GLint ColorLocation;
+
+ GLuint IntegerShaderProg;
+ GLint IntegerColorLocation;
};
@@ -310,6 +312,67 @@ struct gl_meta_state
struct drawtex_state DrawTex; /**< For _mesa_meta_DrawTex() */
};
+static GLuint
+compile_shader_with_debug(struct gl_context *ctx, GLenum target, const GLcharARB *source)
+{
+ GLuint shader;
+ GLint ok, size;
+ GLchar *info;
+
+ shader = _mesa_CreateShaderObjectARB(target);
+ _mesa_ShaderSourceARB(shader, 1, &source, NULL);
+ _mesa_CompileShaderARB(shader);
+
+ _mesa_GetShaderiv(shader, GL_COMPILE_STATUS, &ok);
+ if (ok)
+ return shader;
+
+ _mesa_GetShaderiv(shader, GL_INFO_LOG_LENGTH, &size);
+ if (size == 0)
+ return 0;
+
+ info = malloc(size);
+ if (!info)
+ return 0;
+
+ _mesa_GetProgramInfoLog(shader, size, NULL, info);
+ _mesa_problem(ctx,
+ "meta program compile failed:\n%s\n"
+ "source:\n%s\n",
+ info, source);
+
+ free(info);
+
+ return 0;
+}
+
+static GLuint
+link_program_with_debug(struct gl_context *ctx, GLuint program)
+{
+ GLint ok, size;
+ GLchar *info;
+
+ _mesa_LinkProgramARB(program);
+
+ _mesa_GetProgramiv(program, GL_LINK_STATUS, &ok);
+ if (ok)
+ return program;
+
+ _mesa_GetProgramiv(program, GL_INFO_LOG_LENGTH, &size);
+ if (size == 0)
+ return 0;
+
+ info = malloc(size);
+ if (!info)
+ return 0;
+
+ _mesa_GetProgramInfoLog(program, size, NULL, info);
+ _mesa_problem(ctx, "meta program link failed:\n%s", info);
+
+ free(info);
+
+ return 0;
+}
/**
* Initialize meta-ops for a context.
@@ -1646,6 +1709,22 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
"{\n"
" gl_FragColor = color;\n"
"}\n";
+ const char *vs_int_source =
+ "#version 130\n"
+ "attribute vec4 position;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = position;\n"
+ "}\n";
+ const char *fs_int_source =
+ "#version 130\n"
+ "uniform ivec4 color;\n"
+ "out ivec4 out_color;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " out_color = color;\n"
+ "}\n";
GLuint vs, fs;
if (clear->ArrayObj != 0)
@@ -1679,6 +1758,21 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
clear->ColorLocation = _mesa_GetUniformLocationARB(clear->ShaderProg,
"color");
+
+ if (ctx->Const.GLSLVersion >= 130) {
+ vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_int_source);
+ fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_int_source);
+
+ clear->IntegerShaderProg = _mesa_CreateProgramObjectARB();
+ _mesa_AttachShader(clear->IntegerShaderProg, fs);
+ _mesa_AttachShader(clear->IntegerShaderProg, vs);
+ _mesa_BindAttribLocationARB(clear->IntegerShaderProg, 0, "position");
+
+ link_program_with_debug(ctx, clear->IntegerShaderProg);
+
+ clear->IntegerColorLocation =
+ _mesa_GetUniformLocationARB(clear->IntegerShaderProg, "color");
+ }
}
/**
@@ -1722,9 +1816,15 @@ _mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers)
meta_glsl_clear_init(ctx, clear);
- _mesa_UseProgramObjectARB(clear->ShaderProg);
- _mesa_Uniform4fvARB(clear->ColorLocation, 1,
- ctx->Color.ClearColor.f);
+ if (fb->_IntegerColor) {
+ _mesa_UseProgramObjectARB(clear->IntegerShaderProg);
+ _mesa_Uniform4ivARB(clear->IntegerColorLocation, 1,
+ ctx->Color.ClearColor.i);
+ } else {
+ _mesa_UseProgramObjectARB(clear->ShaderProg);
+ _mesa_Uniform4fvARB(clear->ColorLocation, 1,
+ ctx->Color.ClearColor.f);
+ }
_mesa_BindVertexArray(clear->ArrayObj);
_mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
--
1.7.7
More information about the mesa-dev
mailing list