Khronos Public Bugzilla
Bug 748 - 4.3 GetProgramResourceIndex(): Which one?
4.3 GetProgramResourceIndex(): Which one?
Status: ASSIGNED
Product: OpenGL
Classification: Unclassified
Component: API Specification
4.3
All All
: P3 normal
: ---
Assigned To: Pat Brown
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2012-10-22 20:21 PDT by Alfonse
Modified: 2013-08-23 05:24 PDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alfonse 2012-10-22 20:21:55 PDT
Consider the following GLSL code:

uniform BlockName
{
  int a_name;
} instance_name;

uniform int a_name;

This is completely legal GLSL code, because the block uses an instance name. Thus, in GLSL, you must prefix the name of its members with the instance name. "instance_name.a_name" is therefore separate from "a_name".

Now glGetProgramResourceIndex retrieves the index for a resource by its name. According to 7.3.1 of the OpenGL 4.3 specification, neither the block name nor the instance name is used when building the name of *members* of that block. Therefore, if you query the index for BlockName, you will find that GL_NUM_ACTIVE_VARIABLES​ is 1. GL_ACTIVE_VARIABLES​ will tell us the index for its one member.

The question is this: will glGetProgramResourceIndex(prog, GL_UNIFORM, "a_name") return the same index as for the member of BlockName, or will it return the global one? The specification is unclear about this; it simply says that it will return "the index of the matched resource is returned". But there are two possible matches; which is returned?

Or am I wrong about section 7.3.1; did I overlook something? Or even worse, is this a spec bug? Should the name of members of an interface block be prefixed with the block name? Or should they be prefixed with the block name only if they were created with an instance name (thus identical to GLSL rules, only with a different name)?
Comment 1 Alfonse 2013-01-02 17:36:04 PST
This information is in the GLSL specification, 4.3.9, folio page 52. However, it makes more sense to put it in the OpenGL specification, in the list from 7.3.1. That's where people will naturally go to look for it.
Comment 2 Pat Brown 2013-08-22 12:16:43 PDT
Assigning to research.  ARB_program_interface_query in 4.3 made a number of changes to try and clarify past ambiguities on what strings are accepted/returned for these APIs; not sure if it affects this bug.
Comment 3 Pat Brown 2013-08-22 14:49:42 PDT
As I noted in comment #1, ARB_program_interface_query (and 4.3) attempted to add unambiguous language in the OpenGL specification that should be sufficient to determine the the name strings that can be passed to or returned from OpenGL APIs for examples like the one in the description.  We've had a number of bug reports where it wasn't clear what name strings should be used/returned in cases like arrays, structures, arrays of structures, and so forth, and I hoped to clear things up once and for all in ARB_program_interface_query.

The names of these variables used in the API should be "BlockName.a_name" and "a_name", respectively, which is consistent with the language in the GLSL specification noted in comment #1.  That hadn't really propagated to the OpenGL API specification, though.

What *should* happen was actually discussed in detail in issue (16) of the ARB_program_interface_query specification, but it looks like I failed to add actual spec language for this case.

I think that the edit I would propose, relative to the OpenGL 4.4 Compatibility Profile spec dated July 21, 2013 would be as follows:

  (add a bullet on p. 93 following "For an active variable declared 
   as an array")

  * For an active variable declared as the member of an interface 
    block with an instance name, a single set of entries will 
    be generated, even when the block is declared as an array of 
    instances.  The name of each entry in this set is formed by
    concatenating the block name (not the instance name) from the
    shader source, the "." character, and the name of the block 
    member.  If the block member is an aggregate type, these 
    enumeration rules are applied recursively.  For members of 
    interface blocks without an instance name, entry names are 
    formed using the name of the block member without prepending 
    the name of the block and the "." character.

This edit also catches the array-of-instances case as it applies to block members:

uniform BlockName {
    int a_name;
  } instance_name[8];

where there are eight separate uniform blocks/buffers, holding a single member.  We don't enumerate 8 copies of "BlockName.a_name" since all eight
block instances are laid out identically.

Does this edit look reasonable?  If so, I'll try to get it incorporated into the ARB_program_interface_query spec and relevant API specification updates.
Comment 4 Alfonse 2013-08-23 05:24:29 PDT
That seems reasonable. Thank you.