[Mesa-dev] [PATCH 4/4] mesa: Implement glGetFragDataLocation

Ian Romanick idr at freedesktop.org
Wed Nov 9 14:20:34 PST 2011


On 11/08/2011 08:16 PM, Kenneth Graunke wrote:
> On 11/08/2011 08:10 PM, Kenneth Graunke wrote:
>> On 11/04/2011 04:41 PM, Ian Romanick wrote:
>>> From: Ian Romanick<ian.d.romanick at intel.com>
>>>
>>> Fixes piglit's getfragdatalocation test.
>>>
>>> Signed-off-by: Ian Romanick<ian.d.romanick at intel.com>
>>> ---
>>>   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 23667a1..644916c 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 VERT_ATTRIB_GENERIC0 is because
>>
>> Ditto Eric's comment...FRAG_RESULT_DATA0.
>>
>>> +       * 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."
>>> +       */
>>
>> I don't think this is quite sufficient: according to the man page, it's
>> only legal to call glGetFragDataLocation on user-defined FS outputs.
>> But gl_FragData has location>= FRAG_RESULT_DATA0, doesn't it?
>>
>> Maybe you need to strncmp(var->name, "gl_", 3) == 0 instead?
>
> Durr...I can read.  You already checked that above.
>
> I assert that all FS outputs with var->location<  FRAG_RESULT_DATA0 have
> names that begin with "gl_".  So, this check is just redundant, and you
> can drop it.  Right?
>
> After all, the only "conventional" attributes are gl_FragColor,
> gl_FragData, and gl_FragDepth.

You mean, drop the 'var->location < FRAG_RESULT_DATA0' from the 
if-statement below?  That is probably true.  It was a copy-and-paste 
from GetAttributeLocation.  The check *is* necessary there because there 
is no 'strncmp("gl_", name)' in that function.  GetAttributeLocation can 
get away with that because there is no shared locations between built-in 
and user-defined.  In the GetFragDataLocation, gl_FragData[] and 
user-defined variables overlap.

How would you feel about a follow-on patch that makes the two functions 
consistent with each other by removing the check from both loops and 
adding the strcmp outside the loop in GetAttributeLocation?

>>> +      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 078f534..c766bd4 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.
>>>    */
>>> @@ -1167,16 +1157,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)


More information about the mesa-dev mailing list