From 59012c31337f104aedfe69ca6d3cf784581df544 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 4 Nov 2011 16:32:02 -0700 Subject: [PATCH] mesa: Implement glGetFragDataLocation Fixes piglit's getfragdatalocation test. Signed-off-by: Ian Romanick Reviewed-by: Paul Berry Reviewed-by: Eric Anholt --- src/mesa/main/shader_query.cpp | 56 ++++++++++++++++++++++++++++++++++ src/mesa/main/shaderapi.c | 20 ------------ 2 files changed, 56 insertions(+), 20 deletions(-) diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp index 23667a13328..38bacdb747b 100644 --- a/src/mesa/main/shader_query.cpp +++ b/src/mesa/main/shader_query.cpp @@ -274,3 +274,59 @@ _mesa_BindFragDataLocation(GLuint program, GLuint colorNumber, * glLinkProgram is called again. */ } + +GLint GLAPIENTRY +_mesa_GetFragDataLocation(GLuint program, const GLchar *name) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *const shProg = + _mesa_lookup_shader_program_err(ctx, program, "glGetFragDataLocation"); + + if (!shProg) { + return -1; + } + + if (!shProg->LinkStatus) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetFragDataLocation(program not linked)"); + return -1; + } + + if (!name) + return -1; + + if (strncmp(name, "gl_", 3) == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetFragDataLocation(illegal name)"); + return -1; + } + + /* Not having a fragment shader is not an error. + */ + if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) + return -1; + + exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir; + foreach_list(node, ir) { + const ir_variable *const var = ((ir_instruction *) node)->as_variable(); + + /* The extra check against FRAG_RESULT_DATA0 is because + * glGetFragDataLocation cannot be used on "conventional" attributes. + * + * From page 95 of the OpenGL 3.0 spec: + * + * "If name is not an active attribute, if name is a conventional + * attribute, or if an error occurs, -1 will be returned." + */ + if (var == NULL + || var->mode != ir_var_out + || var->location == -1 + || var->location < FRAG_RESULT_DATA0) + continue; + + if (strcmp(var->name, name) == 0) + return var->location - FRAG_RESULT_DATA0; + } + + return -1; +} diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 1d8af3ea06b..c4d01abc705 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -496,16 +496,6 @@ get_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount, } -static GLint -get_frag_data_location(struct gl_context *ctx, GLuint program, - const GLchar *name) -{ - _mesa_problem(ctx, "get_frag_data_location() not implemented yet"); - return -1; -} - - - /** * glGetHandleARB() - return ID/name of currently bound shader program. */ @@ -1178,16 +1168,6 @@ _mesa_GetAttachedShaders(GLuint program, GLsizei maxCount, } -/* GL_EXT_gpu_shader4, GL3 */ -GLint GLAPIENTRY -_mesa_GetFragDataLocation(GLuint program, const GLchar *name) -{ - GET_CURRENT_CONTEXT(ctx); - return get_frag_data_location(ctx, program, name); -} - - - void GLAPIENTRY _mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length, GLcharARB * infoLog) -- 2.30.2