Name ARB_program_interface_query Name Strings GL_ARB_program_interface_query Contact Pat Brown, NVIDIA (pbrown 'at' nvidia.com) Contributors Members of the Khronos OpenGL ARB TSG Notice Copyright (c) 2012-2013 The Khronos Group Inc. Copyright terms at http://www.khronos.org/registry/speccopyright.html Specification Update Policy Khronos-approved extension specifications are updated in response to issues and bugs prioritized by the Khronos OpenGL Working Group. For extensions which have been promoted to a core Specification, fixes will first appear in the latest version of that core Specification, and will eventually be backported to the extension document. This policy is described in more detail at https://www.khronos.org/registry/OpenGL/docs/update_policy.php Status Complete. Approved by the ARB on 2012/06/12. Version Last Modified Date: January 10, 2019 Revision: 21 Number ARB Extension #134 Dependencies OpenGL 2.0 is required. This extension is written against the OpenGL 4.2 Compatibility Profile Specification (January 19, 2012). OpenGL 3.0, ARB_transform_feedback, and EXT_transform_feedback affect the definition of this extension. OpenGL 3.1 and ARB_uniform_buffer_object affect the definition of this extension. OpenGL 4.0 and ARB_shader_subroutine affect the definition of this extension. OpenGL 4.2 and ARB_shader_atomic_counters affect the definition of this extension. OpenGL 4.3 and ARB_shader_storage_buffer_object affect the definition of this extension. OpenGL 4.3 and ARB_arrays_of_arrays affect the definition of this extension. OpenGL 4.3 and ARB_compute_shader affect the definition of this extension. OpenGL 4.3 and ARB_explicit_uniform_location affect the definition of this extension. Overview This extension provides a single unified set of query commands that can be used by applications to determine properties of various interfaces and resources used by program objects to communicate with application code, fixed-function OpenGL pipeline stages, and other programs. In unextended OpenGL 4.2, there is a separate set of query commands for each different type of interface or resource used by the program. These different sets of queries are structured nearly identically, but the queries for some interfaces have limited capability (e.g., there is no ability to enumerate fragment shader outputs). With the single set of query commands provided by this extension, a consistent set of queries is available for all interfaces, and a new interface can be added without having to introduce a completely new set of query commands. These queries are intended to provide a superset of the capabilities provided by similar queries in OpenGL 4.2, and should allow for the deprecation of the existing queries. This extension defines two terms: interfaces and active resources. Each interface of a program object provides a way for the program to communicate with application code, fixed-function OpenGL pipeline stages, and other programs. Examples of interfaces for a program object include inputs (receiving values from vertex attributes or outputs of other programs), outputs (sending values to other programs or per-fragment operations), uniforms (receiving values from API calls), uniform blocks (receiving values from bound buffer objects), subroutines and subroutine uniforms (receiving API calls to indicate functions to call during program execution), and atomic counter buffers (holding values to be manipulated by atomic counter shader functions). Each interface of a program has a set of active resources used by the program. For example, the resources of a program's input interface includes all active input variables used by the first stage of the program. The resources of a program's uniform block interface consists of the set of uniform blocks with at least one member used by any shader in the program. IP Status No known IP claims. New Procedures and Functions void GetProgramInterfaceiv(uint program, enum programInterface, enum pname, int *params); uint GetProgramResourceIndex(uint program, enum programInterface, const char *name); void GetProgramResourceName(uint program, enum programInterface, uint index, sizei bufSize, sizei *length, char *name); void GetProgramResourceiv(uint program, enum programInterface, uint index, sizei propCount, const enum *props, sizei bufSize, sizei *length, int *params); int GetProgramResourceLocation(uint program, enum programInterface, const char *name); int GetProgramResourceLocationIndex(uint program, enum programInterface, const char *name); New Tokens Accepted by the parameter of GetProgramInterfaceiv, GetProgramResourceIndex, GetProgramResourceName, GetProgramResourceiv, GetProgramResourceLocation, and GetProgramResourceLocationIndex: UNIFORM 0x92E1 UNIFORM_BLOCK 0x92E2 PROGRAM_INPUT 0x92E3 PROGRAM_OUTPUT 0x92E4 BUFFER_VARIABLE 0x92E5 SHADER_STORAGE_BLOCK 0x92E6 ATOMIC_COUNTER_BUFFER (already in 4.2) VERTEX_SUBROUTINE 0x92E8 TESS_CONTROL_SUBROUTINE 0x92E9 TESS_EVALUATION_SUBROUTINE 0x92EA GEOMETRY_SUBROUTINE 0x92EB FRAGMENT_SUBROUTINE 0x92EC COMPUTE_SUBROUTINE 0x92ED VERTEX_SUBROUTINE_UNIFORM 0x92EE TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 COMPUTE_SUBROUTINE_UNIFORM 0x92F3 TRANSFORM_FEEDBACK_VARYING 0x92F4 Accepted by the parameter of GetProgramInterfaceiv: ACTIVE_RESOURCES 0x92F5 MAX_NAME_LENGTH 0x92F6 MAX_NUM_ACTIVE_VARIABLES 0x92F7 MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 Accepted in the array of GetProgramResourceiv: NAME_LENGTH 0x92F9 TYPE 0x92FA ARRAY_SIZE 0x92FB OFFSET 0x92FC BLOCK_INDEX 0x92FD ARRAY_STRIDE 0x92FE MATRIX_STRIDE 0x92FF IS_ROW_MAJOR 0x9300 ATOMIC_COUNTER_BUFFER_INDEX 0x9301 BUFFER_BINDING 0x9302 BUFFER_DATA_SIZE 0x9303 NUM_ACTIVE_VARIABLES 0x9304 ACTIVE_VARIABLES 0x9305 REFERENCED_BY_VERTEX_SHADER 0x9306 REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 REFERENCED_BY_GEOMETRY_SHADER 0x9309 REFERENCED_BY_FRAGMENT_SHADER 0x930A REFERENCED_BY_COMPUTE_SHADER 0x930B TOP_LEVEL_ARRAY_SIZE 0x930C TOP_LEVEL_ARRAY_STRIDE 0x930D LOCATION 0x930E LOCATION_INDEX 0x930F IS_PER_PATCH 0x92E7 NUM_COMPATIBLE_SUBROUTINES (already in 4.2) COMPATIBLE_SUBROUTINES (already in 4.2) Additions to Chapter 2 of the OpenGL 4.2 (Compatibility Profile) Specification (OpenGL Operation) Modify Section 2.14.3, Program Objects (p. 97) (insert at the end of the section, p. 101) Program Interfaces When a program object is made part of the current rendering state, its executable code may communicate with other GL pipeline stages or application code through a variety of /interfaces/. When a program is linked, the GL builds a list of /active resources/ for each interface. Examples of active resources include variables, interface blocks, and subroutines used by shader code. Resources referenced in shader code are considered /active/ unless the compiler and linker can conclusively determine that they have no observable effect on the results produced by the executable code of the program. For example, variables might be considered inactive if they are declared but not used in executable code, used only in a clause of an "if" statement that would never be executed, used only in functions that are never called, or used only in computations of temporary variables having no effect on any shader output. In cases where the compiler or linker cannot make a conclusive determination, any resource referenced by shader code will be considered active. The set of active resources on for any interface is implementation-dependent because it depends on various analysis and optimizations performed by the compiler and linker. If a program is linked successfully, the GL will generate lists of active resources based on the executable code produced by the link. If a program is linked unsuccessfully, the link may have failed for a number of reasons, including cases where the program required more resources than supported by the implementation. Implementations are permitted, but not required, to record lists of resources that would have been considered active had the program linked successfully. If an implementation does not record information for any given interface, the corresponding list of active resources is considered empty. If a program has never been linked, all lists of active resources are considered empty. The GL provides a number of commands to query properties of the interfaces of a program object. Each such command accepts a token, identifying a specific interface. The supported values for are as follows: * UNIFORM corresponds to the set of active uniform variables (section 2.14.7) used by . * UNIFORM_BLOCK corresponds to the set of active uniform blocks (section 2.14.7) used by . * ATOMIC_COUNTER_BUFFER corresponds to the set of active atomic counter buffer binding points (section 2.14.7) used by . * PROGRAM_INPUT corresponds to the set of active input variables used by the first shader stage of . If includes multiple shader stages, input variables from any shader stage other than the first will not be enumerated. * PROGRAM_OUTPUT corresponds to the set of active output variables (section 2.14.11) used by the last shader stage of . If includes multiple shader stages, output variables from any shader stage other than the last will not be enumerated. * VERTEX_SUBROUTINE, TESS_CONTROL_SUBROUTINE, TESS_EVALUATION_SUBROUTINE, GEOMETRY_SUBROUTINE, FRAGMENT_SUBROUTINE, and COMPUTE_SUBROUTINE correspond to the set of active subroutines for the vertex, tessellation control, tessellation evaluation, geometry, fragment, and compute shader stages of , respectively (section 2.14.8). * VERTEX_SUBROUTINE_UNIFORM, TESS_CONTROL_SUBROUTINE_UNIFORM, TESS_EVALUATION_SUBROUTINE_UNIFORM, GEOMETRY_SUBROUTINE_UNIFORM, FRAGMENT_SUBROUTINE_UNIFORM, and COMPUTE_SUBROUTINE_UNIFORM correspond to the set of active subroutine uniform variables used by the vertex, tessellation control, tessellation evaluation, geometry, fragment, and compute shader stages of , respectively (section 2.14.8). * TRANSFORM_FEEDBACK_VARYING corresponds to the set of output variables in the last non-fragment stage of that would be captured when transform feedback is active (section 2.20.2). * BUFFER_VARIABLE corresponds to the set of active buffer variables (see the ARB_shader_storage_buffer_object extension) used by . * SHADER_STORAGE_BLOCK corresponds to the set of active shader storage blocks (see the ARB_shader_storage_buffer_object extension) used by . When building a list of active variable or interface blocks, resources with aggregate types (such as arrays or structures) may produce multiple entries in the active resource list for the corresponding interface. Additionally, each active variable, interface block, or subroutine in the list is assigned an associated name string that can be used by applications to refer to the resources. For interfaces involving variables, interface blocks, or subroutines, the entries of active resource lists are generated as follows: * For an active variable declared as a single instance of a basic type, a single entry will be generated, using the variable name from the shader source. * For an active variable declared as an array of basic types, a single entry will be generated, with its name string formed by concatenating the name of the array and the string "[0]". * For an active variable declared as a structure, a separate entry will be generated for each active structure member. The name of each entry is formed by concatenating the name of the structure, the "." character, and the name of the structure member. If a structure member to enumerate is itself a structure or array, these enumeration rules are applied recursively. * For an active variable declared as an array of an aggregate data type (structures or arrays), a separate entry will be generated for each active array element, unless noted immediately below. The name of each entry is formed by concatenating the name of the array, the "[" character, an integer identifying the element number, and the "]" character. These enumeration rules are applied recursively, treating each enumerated array element as a separate active variable. * For an active shader storage block member declared as an array, an entry will be generated only for the first array element, regardless of its type. For arrays of aggregate types, the enumeration rules are applied recursively for the single enumerated array element. * For an active interface block not declared as an array of block instances, a single entry will be generated, using the block name from the shader source. * For an active interface block declared as an array of instances, separate entries will be generated for each active instance. The name of the instance is formed by concatenating the block name, the "[" character, an integer identifying the instance number, and the "]" character. * For an active subroutine, a single entry will be generated, using the subroutine name from the shader source. When an integer array element or block instance number is part of the name string, it will be specified in decimal form without a "+" or "-" sign or any extra leading zeroes. Additionally, the name string will not include white space anywhere in the string. The order of the active resource list is implementation-dependent for all interfaces except for TRANSFORM_FEEDBACK_VARYING. For TRANSFORM_FEEDBACK_VARYING, the active resource list will use the variable order specified in the the most recent call to TransformFeedbackVaryings before the last call to LinkProgram. For the ATOMIC_COUNTER_BUFFER interface, the list of active buffer binding points is built by identifying each unique binding point associated with one or more active atomic counter uniform variables. Active atomic counter buffers do not have an associated name string. For the UNIFORM, PROGRAM_INPUT, PROGRAM_OUTPUT, and TRANSFORM_FEEDBACK_VARYING interfaces, the active resource list will include all active variables for the interface, including any active built-in variables. For PROGRAM_INPUT and PROGRAM_OUTPUT interfaces for shaders that recieve or produce patch primitves, the active resource list will include both per-vertex and per-patch inputs and outputs. For the TRANSFORM_FEEDBACK_VARYING interface, the active resource list will entries for the special varying names gl_NextBuffer, gl_SkipComponents1, gl_SkipComponents2, gl_SkipComponents3, and gl_SkipComponents4 (section 2.14.11). These variables are used to control how varying values are written to transform feedback buffers. When enumerating the properties of such resources, these variables are considered to have a TYPE of NONE and an ARRAY_SIZE of 0 (gl_NextBuffer), 1, 2, 3, and 4, respectively. When a program is linked successfully, active variables in the UNIFORM, PROGRAM_INPUT, PROGRAM_OUTPUT interface, or in any of the subroutine uniform interfaces, are assigned one or more signed integer /locations/. These locations can be used by commands to assign values to uniforms and subroutine uniforms, to identify generic vertex attributes associated with vertex shader inputs, or to identify fragment color output numbers and indices associated with fragment shader outputs. For such variables declared as arrays, separate locations will be assigned to each active array element. Not all active variables are assigned valid locations; the following variables will have an effective location of -1: * uniforms declared as atomic counters; * members of a uniform block; * built-in inputs, outputs, and uniforms (starting with "gl_"); and * inputs or outputs not declared with a "location" layout qualifier, except for vertex shader inputs and fragment shader outputs. If a program has not been linked or has was last linked unsuccessfully, no locations will be assigned. The command void GetProgramInterfaceiv(uint program, enum programInterface, enum pname, int *params); queries a property of the interface in program , returning its value in . The property to return is specified by . If is ACTIVE_RESOURCES, the value returned is the number of resources in the active resource list for . If the list of active resources for is empty, zero is returned. If is MAX_NAME_LENGTH, the value returned is the length of the longest active name string for an active resource in . This length includes an extra character for the null terminator. If the list of active resources for is empty, zero is returned. The error INVALID_OPERATION is generated if is ATOMIC_COUNTER_BUFFER, since active atomic counter buffer resources are not assigned name strings. If is MAX_NUM_ACTIVE_VARIABLES, the value returned is the number of active variables belonging to the interface block or atomic counter buffer resource in with the most active variables. If the list of active resources for is empty, zero is returned. The error INVALID_OPERATION is generated if is not UNIFORM_BLOCK, ATOMIC_COUNTER_BUFFER, or SHADER_STORAGE_BLOCK. If is MAX_NUM_COMPATIBLE_SUBROUTINES, the value returned is the number of compatible subroutines belonging to the active subroutine uniform in with the most compatible subroutines. If the list of active resources for is empty, zero is returned. The error INVALID_OPERATION is generated unless is VERTEX_SUBROUTINE_UNIFORM, TESS_CONTROL_SUBROUTINE_UNIFORM, TESS_EVALUATION_SUBROUTINE_UNIFORM, GEOMETRY_SUBROUTINE_UNIFORM, FRAGMENT_SUBROUTINE_UNIFORM, or COMPUTE_SUBROUTINE_UNIFORM. Each entry in the active resource list for an interface is assigned a unique unsigned integer index in the range 0..-1, where is the number of entries in the active resource list. The command uint GetProgramResourceIndex(uint program, enum programInterface, const char *name); returns the unsigned integer index assigned to a resource named in the interface type of program object . The error INVALID_ENUM is generated if is ATOMIC_COUNTER_BUFFER, since active atomic counter buffer resources are not assigned name strings. If exactly matches the name string of one of the active resources for , the index of the matched resource is returned. Additionally, if would exactly match the name string of an active resource if "[0]" were appended to , the index of the matched resource is returned. Otherwise, is considered not to be the name of an active resource, and INVALID_INDEX is returned. Note that if an interface enumerates a single active resource list entry for an array variable (e.g., "a[0]"), a identifying any array element other than the first (e.g., "a[1]") is not considered to match. For the interface TRANSFORM_FEEDBACK_VARYING, the value INVALID_INDEX should be returned when querying the index assigned to the special names "gl_NextBuffer", "gl_SkipComponents1", "gl_SkipComponents2", "gl_SkipComponents3", and "gl_SkipComponents4". The command void GetProgramResourceName(uint program, enum programInterface, uint index, sizei bufSize, sizei *length, char *name); returns the name string assigned to the single active resource with an index of in the interface of program object . The error INVALID_VALUE is generated if is greater than or equal to the number of entries in the active resource list for . The error INVALID_ENUM is generated if is ATOMIC_COUNTER_BUFFER, since active atomic counter buffer resources are not assigned name strings. The name string assigned to the active resource identified by is returned as a null-terminated string in . The actual number of characters written into , excluding the null terminator, is returned in . If is NULL, no length is returned. The maximum number of characters that may be written into , including the null terminator, is specified by . If the length of the name string (including the null terminator) is greater than , the first -1 characters of the name string will be written to , followed by a null terminator. If is zero, no error will be generated but no characters will be written to . The length of the longest name string for , including a null terminator, can be queried by calling GetProgramInterfaceiv with a of MAX_NAME_LENGTH. The command void GetProgramResourceiv(uint program, enum programInterface, uint index, sizei propCount, const enum *props, sizei bufSize, sizei *length, int *params); returns values for multiple properties of a single active resource with an index of in the interface of program object . For each resource, values for properties specified by the array are returned. The error INVALID_VALUE is generated if is zero. The error INVALID_ENUM is generated if any value in is not one of the properties described immediately below. The error INVALID_OPERATION is generated if any value in is not allowed for . The set of allowed values for each property can be found in Table X.1. The values associated with the properties of the active resource are written to consecutive entries in , in increasing order according to position in . If no error is generated, only the first integer values will be written to ; any extra values will not be returned. If is not NULL, the actual number of integer values written to will be written to . Property Supported Interfaces --------------------------- ---------------------------------------- NAME_LENGTH all but ATOMIC_COUNTER_BUFFER TYPE UNIFORM, PROGRAM_INPUT, PROGRAM_OUTPUT, TRANSFORM_FEEDBACK_VARYING, BUFFER_VARIABLE ARRAY_SIZE UNIFORM, BUFFER_VARIABLE, PROGRAM_INPUT, PROGRAM_OUTPUT, VERTEX_SUBROUTINE_ UNIFORM, TESS_CONTROL_SUBROUTINE_UNIFORM, TESS_EVALUATION_SUBROUTINE_UNIFORM, GEOMETRY_SUBROUTINE_UNIFORM, FRAGMENT_ SUBROUTINE_UNIFORM, COMPUTE_SUBROUTINE_ UNIFORM, TRANSFORM_FEEDBACK_VARYING OFFSET UNIFORM, BUFFER_VARIABLE BLOCK_INDEX UNIFORM, BUFFER_VARIABLE ARRAY_STRIDE UNIFORM, BUFFER_VARIABLE MATRIX_STRIDE UNIFORM, BUFFER_VARIABLE IS_ROW_MAJOR UNIFORM, BUFFER_VARIABLE ATOMIC_COUNTER_BUFFER_INDEX UNIFORM BUFFER_BINDING UNIFORM_BLOCK, ATOMIC_COUNTER_BUFFER, SHADER_STORAGE_BLOCK BUFFER_DATA_SIZE UNIFORM_BLOCK, ATOMIC_COUNTER_BUFFER SHADER_STORAGE_BLOCK NUM_ACTIVE_VARIABLES UNIFORM_BLOCK, ATOMIC_COUNTER_BUFFER SHADER_STORAGE_BLOCK ACTIVE_VARIABLES UNIFORM_BLOCK, ATOMIC_COUNTER_BUFFER SHADER_STORAGE_BLOCK REFERENCED_BY_VERTEX_ UNIFORM, UNIFORM_BLOCK, ATOMIC_COUNTER_ SHADER BUFFER, SHADER_STORAGE_BLOCK, BUFFER_VARIABLE, PROGRAM_INPUT, PROGRAM_OUTPUT REFERENCED_BY_TESS_ UNIFORM, UNIFORM_BLOCK, ATOMIC_COUNTER_ CONTROL_SHADER BUFFER, SHADER_STORAGE_BLOCK, BUFFER_VARIABLE, PROGRAM_INPUT, PROGRAM_OUTPUT REFERENCED_BY_TESS_ UNIFORM, UNIFORM_BLOCK, ATOMIC_COUNTER_ EVALUATION_SHADER BUFFER, SHADER_STORAGE_BLOCK, BUFFER_VARIABLE, PROGRAM_INPUT, PROGRAM_OUTPUT REFERENCED_BY_GEOMETRY_ UNIFORM, UNIFORM_BLOCK, ATOMIC_COUNTER_ SHADER BUFFER, SHADER_STORAGE_BLOCK, BUFFER_VARIABLE, PROGRAM_INPUT, PROGRAM_OUTPUT REFERENCED_BY_FRAGMENT_ UNIFORM, UNIFORM_BLOCK, ATOMIC_COUNTER_ SHADER BUFFER, SHADER_STORAGE_BLOCK, BUFFER_VARIABLE, PROGRAM_INPUT, PROGRAM_OUTPUT REFERENCED_BY_COMPUTE_ UNIFORM, UNIFORM_BLOCK, ATOMIC_COUNTER_ SHADER BUFFER, SHADER_STORAGE_BLOCK, BUFFER_VARIABLE, PROGRAM_INPUT, PROGRAM_OUTPUT NUM_COMPATIBLE_SUBROUTINES VERTEX_SUBROUTINE_UNIFORM, TESS_CONTROL_ SUBROUTINE_UNIFORM, TESS_EVALUATION_ SUBROUTINE_UNIFORM, GEOMETRY_SUBROUTINE_ UNIFORM, FRAGMENT_SUBROUTINE_UNIFORM, COMPUTE_SUBROUTINE_UNIFORM COMPATIBLE_SUBROUTINES VERTEX_SUBROUTINE_UNIFORM, TESS_CONTROL_ SUBROUTINE_UNIFORM, TESS_EVALUATION_ SUBROUTINE_UNIFORM, GEOMETRY_SUBROUTINE_ UNIFORM, FRAGMENT_SUBROUTINE_UNIFORM, COMPUTE_SUBROUTINE_UNIFORM TOP_LEVEL_ARRAY_SIZE BUFFER_VARIABLE TOP_LEVEL_ARRAY_STRIDE BUFFER_VARIABLE LOCATION UNIFORM, PROGRAM_INPUT, PROGRAM_OUTPUT, VERTEX_SUBROUTINE_UNIFORM, TESS_CONTROL_ SUBROUTINE_UNIFORM, TESS_EVALUATION_ SUBROUTINE_UNIFORM, GEOMETRY_SUBROUTINE_ UNIFORM, FRAGMENT_SUBROUTINE_UNIFORM, COMPUTE_SUBROUTINE_UNIFORM LOCATION_INDEX PROGRAM_OUTPUT IS_PER_PATCH PROGRAM_INPUT, PROGRAM_OUTPUT Table X.1, GetProgramResourceiv properties and supported interfaces For the property NAME_LENGTH, a single integer identifying the length of the name string associated with an active variable, interface block, or subroutine is written to . The name length includes a terminating null character. For the property TYPE, a single integer identifying the type of an active variable is written to . The integer returned is one of the values found in table 2.16. For the property COMPATIBLE_SUBROUTINES, an array of integers is written to , with each integer specifying the index of an active subroutine that can be assigned to the selected subroutine uniform. The number of values written to for an active subroutine is given by the value of the property NUM_COMPATIBLE_SUBROUTINES for the resource. For the property ARRAY_SIZE, a single integer identifying the number of active array elements of an active variable is written to . The array size returned is in units of the type associated with the property TYPE. For active variables not corresponding to an array of basic types, the value one is written to . If the variable is a shader storage block member in an array with no declared size, the value zero is written to . For the property BLOCK_INDEX, a single integer identifying the index of the active interface block containing an active variable is written to . If the variable is not the member of an interface block, the value -1 is written to . For the property OFFSET, a single integer identifying the offset of an active variable is written to . For active variables backed by a buffer object, the value written is the offset, in basic machine units, relative to the base of buffer range holding the values of the variable. For active variables not backed by a buffer object, an offset of -1 is written to . For the property ARRAY_STRIDE, a single integer identifying the stride between array elements in an active variable is written to . For active variables declared as an array of basic types, the value written is the difference, in basic machine units, between the offsets of consecutive elements in an array. For active variables not declared as an array of basic types, zero is written to . For active variables not backed by a buffer object, -1 is written to , regardless of the variable type. For the property MATRIX_STRIDE, a single integer identifying the stride between columns of a column-major matrix or rows of a row-major matrix is written to . For active variables declared a single matrix or array of matrices, the value written is the difference, in basic machine units, between the offsets of consecutive columns or rows in each matrix. For active variables not declared as a matrix or array of matrices, zero is written to . For active variables not backed by a buffer object, -1 is written to , regardless of the variable type. For the property IS_ROW_MAJOR, a single integer identifying whether an active variable is a row-major matrix is written to . For active variables backed by a buffer object, declared as a single matrix or array of matrices, and stored in row-major order, one is written to . For all other active variables, zero is written to . For the property ATOMIC_COUNTER_BUFFER_INDEX, a single integer identifying the index of the active atomic counter buffer containing an active variable is written to . If the variable is not an atomic counter uniform, the value -1 is written to . For the property of BUFFER_BINDING, to index of the buffer binding point associated with the active uniform block, shader storage block, or atomic counter buffer is written to . For the property of BUFFER_DATA_SIZE, then the implementation-dependent minimum total buffer object size, in basic machine units, required to hold all active variables associated with an active uniform block, shader storage block, or atomic counter buffer is written to . If the final member of an active shader storage block is array with no declared size, the minimum buffer size is computed assuming the array was declared as an array with one element. For the property of NUM_ACTIVE_VARIABLES, the number of active variables associated with an active uniform block, shader storage block, or atomic counter buffer is written to . For the property of ACTIVE_VARIABLES, an array of active variable indices associated with an active uniform block, shader storage block, or atomic counter buffer is written to . The number of values written to for an active resource is given by the value of the property NUM_ACTIVE_VARIABLES for the resource. For the properties REFERENCED_BY_VERTEX_SHADER, REFERENCED_BY_TESS_CONTROL_SHADER, REFERENCED_BY_TESS_EVALUATION_SHADER, REFERENCED_BY_GEOMETRY_SHADER, REFERENCED_BY_FRAGMENT_SHADER, and REFERENCED_BY_COMPUTE_SHADER, a single integer is written to , identifying whether the active resource is referenced by the vertex, tessellation control, tessellation evaluation, geometry, or fragment shaders, respectively, in the program object. The value one is written to if an active variable is referenced by the corresponding shader, or if an active uniform block, shader storage block, or atomic counter buffer contains at least one variable referenced by the corresponding shader. Otherwise, the value zero is written to . For the property TOP_LEVEL_ARRAY_SIZE, a single integer identifying the number of active array elements of the top-level shader storage block member containing to the active variable is written to . If the top-level block member is not declared as an array, the value one is written to . If the top-level block member is an array with no declared size, the value zero is written to . For the property TOP_LEVEL_ARRAY_STRIDE, a single integer identifying the stride between array elements of the top-level shader storage block member containing the active variable is written to . For top-level block members declared as arrays, the value written is the difference, in basic machine units, between the offsets of the active variable for consecutive elements in the top-level array. For top-level block members not declared as an array, zero is written to . For the property LOCATION, a single integer identifying the assigned location for an active uniform, input, output, or subroutine uniform variable is written to . For input, output, or uniform variables with locations specified by a layout qualifier, the specified location is used. For vertex shader input or fragment shader output variables without a layout qualifier, the location assigned when a program is linked is written to . For all other input and output variables, the value -1 is written to . For uniforms in uniform blocks, the value -1 is written to . For the property LOCATION_INDEX, a single integer identifying the fragment color index of an active fragment shader output variable is written to . If the active variable is an output for a non-fragment shader, the value -1 will be written to . For the property IS_PER_PATCH, a single integer identifying whether the input or output is a per-patch attribute. If the active variable is a per-patch attribute (declared with the "patch" qualifier), the value one is written to ; otherwise, the value zero is written to . The commands int GetProgramResourceLocation(uint program, enum programInterface, const char *name); int GetProgramResourceLocationIndex(uint program, enum programInterface, const char *name); returns the location or the fragment color index, respectively, assigned to the variable named in interface of program object . For both commands, the error INVALID_OPERATION is generated if has not been linked or was last linked unsuccessfully. For GetProgramResourceLocation, must be one of UNIFORM, PROGRAM_INPUT, PROGRAM_OUTPUT, VERTEX_SUBROUTINE_UNIFORM, TESS_CONTROL_SUBROUTINE_UNIFORM, TESS_EVALUATION_SUBROUTINE_UNIFORM, GEOMETRY_SUBROUTINE_UNIFORM, FRAGMENT_SUBROUTINE_UNIFORM, or COMPUTE_SUBROUTINE_UNIFORM. For GetProgramResourceLocationIndex, must be PROGRAM_OUTPUT. The value -1 will be returned by either command if an error occurs, if does not identify an active variable on , or if identifies an active variable that does not have a valid location assigned, as described above. The locations returned by these commands are the same locations returned when querying the LOCATION and LOCATION_INDEX resource properties. A string provided to GetProgramResourceLocation or GetProgramResourceLocationIndex is considered to match an active variable if: * the string exactly matches the name of the active variable; * if the string identifies the base name of an active array, where the string would exactly match the name of the variable if the suffix "[0]" were appended to the string; or * if the string identifies an active element of the array, where the string ends with the concatenation of the "[" character, an integer (with no "+" sign, extra leading zeroes, or whitespace) identifying an array element, and the "]" character, the integer is less than the number of active elements of the array variable, and where the string would exactly match the enumerated name of the array if the decimal integer were replaced with zero. Any other string is considered not to identify an active variable. If the string specifies an element of an array variable, GetProgramResourceLocation and GetProgramResourceLocationIndex return the location or fragment color index assigned to that element. If it specifies the base name of an array, it identifies the resources associated with the first element of the array. Modify Section 2.14.6, Vertex Attributes, p. 109 (delete text beginning with the second paragraph of p. 110, through the second paragraph of p. 112) (modify the third paragraph, p. 112, removing the first sentence) The command void BindAttribLocation(uint program, uint index, const char *name); ... (insert after second paragraph, p. 113) To determine the set of active vertex attribute variables used by a program, applications can query the properties and active resources of the PROGRAM_INPUT interface of a program including a vertex shader. Additionally, the command void GetActiveAttrib(uint program, uint index, sizei bufSize, sizei *length, int *size, enum *type, char *name); can be used to determine properties of the active input variable assigned the index in program object . If no error occurs, the command is equivalent to calling: const enum props[] = { ARRAY_SIZE, TYPE }; GetProgramResourceName(program, PROGRAM_INPUT, index, bufSize, length, name); GetProgramResourceiv(program, PROGRAM_INPUT, index, 1, &props[0], 1, NULL, size); GetProgramResourceiv(program, PROGRAM_INPUT, index, 1, &props[1], 1, NULL, (int *) type); If is not the index of an active input variable in , the error INVALID_VALUE is generated. If does not include a vertex shader, it has no active vertex attributes and the error INVALID_VALUE is generated for all values of . For GetActiveAttrib, all active vertex shader input variables are enumerated, including the special built-in inputs gl_VertexID and gl_InstanceID. The command int GetAttribLocation(uint program, const char *name); can be used to determine the location assigned to the active input variable named in program object . The error INVALID_OPERATION is generated and -1 is returned if has not been linked or was last linked unsuccessfully. If has been successfully linked but contains no vertex shader, no error will be generated but -1 will be returned. Otherwise, the command is equivalent to calling: GetProgramResourceLocation(program, PROGRAM_INPUT, name); There is an implementation-dependent limit on the number of active attribute variables [[compatibility profile only: (either conventional or generic)]] in a vertex shader. A program with more than MAX_VERTEX_ATTRIBS active attribute variables may fail to link, unless device-dependent optimizations are able to make the program fit within available hardware resources. For the purposes of this test, attribute variables of the type dvec3, dvec4, dmat2x3, dmat2x4, dmat3, dmat3x4, dmat4x3, and dmat4 may count as consuming twice as many attributes as equivalent single-precision types. While these types use the same number of generic attributes as their single-precision equivalents, implementations are permitted to consume two single-precision vectors of internal storage for each three- or four-component double-precision vector. Modify Section 2.14.7, Uniform Variables, p. 113 (replace text starting with the 3rd paragraph on p. 115 through the 3rd paragraph on p. 127) To determine the set of active uniform variables used by a program, applications can query the properties and active resources of the UNIFORM interface of a program. Additionally, several dedicated commands are provided to query properties of active uniforms. The commands int GetUniformLocation(uint program, const char *name) void GetActiveUniformName(uint program, uint uniformIndex, sizei bufSize, sizei *length, char *uniformName); are equivalent to calling GetProgramResourceLocation(program, UNIFORM, name); GetProgramResourceName(program, UNIFORM, uniformIndex, bufSize, length, uniformName); The command void GetUniformIndices(uint program, sizei uniformCount, const char * const *uniformNames, uint *uniformIndices); is equivalent to for (int i = 0; i < uniformCount; i++) { uniformIndices[i] = GetProgramResourceIndex(program, UNIFORM, uniformNames[i]; } The command void GetActiveUniform(uint program, uint index, sizei bufSize, sizei *length, int *size, enum *type, char *name); is equivalent to const enum props[] = { ARRAY_SIZE, TYPE }; GetProgramResourceName(program, UNIFORM, index, bufSize, length, name); GetProgramResourceiv(program, UNIFORM, index, 1, &props[0], 1, NULL, size); GetProgramResourceiv(program, UNIFORM, index, 1, &props[1], 1, NULL, (int *) type); The command void GetActiveUniformsiv(uint program, sizei uniformCount, const uint *uniformIndices, enum pname, int *params); is equivalent to GLenum prop; for (int i = 0; i < uniformCount; i++) { GetProgramResourceiv(program, UNIFORM, uniformIndices[i], 1, &prop, 1, NULL, ¶ms[i]); } where the value of is taken from Table X.2, based on the value of . ------------------------------ ------------------------------ UNIFORM_TYPE TYPE UNIFORM_SIZE ARRAY_SIZE UNIFORM_NAME_LENGTH NAME_LENGTH UNIFORM_BLOCK_INDEX BLOCK_INDEX UNIFORM_OFFSET OFFSET UNIFORM_ARRAY_STRIDE ARRAY_STRIDE UNIFORM_MATRIX_STRIDE MATRIX_STRIDE UNIFORM_IS_ROW_MAJOR IS_ROW_MAJOR UNIFORM_ATOMIC_COUNTER_ ATOMIC_COUNTER_BUFFER_INDEX BUFFER_INDEX Table X.2, GetProgramResourceiv properties used by GetActiveUniformsiv. To determine the set of active uniform blocks used by a program, applications can query the properties and active resources of the UNIFORM_BLOCK interface of a program. Additionally, several dedicated commands are provided to query properties of active uniform blocks. The commands uint GetUniformBlockIndex(uint program, const char *uniformBlockName); void GetActiveUniformBlockName(uint program, uint uniformBlockIndex, sizei bufSize, sizei length, char *uniformBlockName); are equivalent to calling GetProgramResourceIndex(program, UNIFORM_BLOCK, uniformBlockName); and GetProgramResourceName(program, UNIFORM_BLOCK, uniformBlockIndex, bufSize, length, uniformBlockName); The command void GetActiveUniformBlockiv(uint program, uint uniformBlockIndex, enum pname, int *params); is equivalent to calling GLenum prop; GetProgramResourceiv(program, UNIFORM_BLOCK, uniformBlockIndex, 1, &prop, maxSize, NULL, params); where the value of is taken from Table X.3, based on the value of , and is taken to specify a sufficiently large buffer to receive all values that would be written to . ------------------------------ ------------------------------ UNIFORM_BLOCK_BINDING BUFFER_BINDING UNIFORM_BLOCK_DATA_SIZE BUFFER_DATA_SIZE UNIFORM_BLOCK_NAME_LENGTH NAME_LENGTH UNIFORM_BLOCK_ACTIVE_UNIFORMS NUM_ACTIVE_VARIABLES UNIFORM_BLOCK_ACTIVE_ ACTIVE_VARIABLES UNIFORM_INDICES UNIFORM_BLOCK_REFERENCED_BY_ REFERENCED_BY_VERTEX_SHADER VERTEX_SHADER UNIFORM_BLOCK_REFERENCED_BY_ REFERENCED_BY_TESS_CONTROL_SHADER TESS_CONTROL_SHADER UNIFORM_BLOCK_REFERENCED_BY_ REFERENCED_BY_TESS_EVALUATION_SHADER TESS_EVALUATION_SHADER UNIFORM_BLOCK_REFERENCED_BY_ REFERENCED_BY_GEOMETRY_SHADER GEOMETRY_SHADER UNIFORM_BLOCK_REFERENCED_BY_ REFERENCED_BY_FRAGMENT_SHADER FRAGMENT_SHADER UNIFORM_BLOCK_REFERENCED_BY_ REFERENCED_BY_COMPUTE_SHADER COMPUTE_SHADER Table X.3, GetProgramResourceiv properties used by GetActiveUniformBlockiv. To determine the set of active atomic counter buffer binding points used by a program, applications can query the properties and active resources of the ATOMIC_COUNTER_BUFFER interface of a program. Additionally, the command void GetActiveAtomicCounterBufferiv(uint program, uint bufferIndex, enum pname, int *params); can be used to determine properties of active atomic counter buffer bindings used by and is equivalent to calling GLenum prop; GetProgramResourceiv(program, ATOMIC_COUNTER_BUFFER, bufferIndex, 1, &prop, maxSize, NULL, params); where the value of is taken from Table X.4, based on the value of , and is taken to specify a sufficiently large buffer to receive all values that would be written to . ------------------------------ ------------------------------ ATOMIC_COUNTER_BUFFER_BINDING BUFFER_BINDING ATOMIC_COUNTER_BUFFER_ BUFFER_DATA_SIZE DATA_SIZE ATOMIC_COUNTER_BUFFER_ACTIVE_ NUM_ACTIVE_VARIABLES ATOMIC_COUNTERS ATOMIC_COUNTER_BUFFER_ACTIVE_ ACTIVE_VARIABLES ATOMIC_COUNTER_INDICES ATOMIC_COUNTER_BUFFER_ REFERENCED_BY_VERTEX_SHADER REFERENCED_BY_VERTEX_SHADER ATOMIC_COUNTER_BUFFER_ REFERENCED_BY_TESS_CONTROL_SHADER REFERENCED_BY_TESS_ CONTROL_SHADER ATOMIC_COUNTER_BUFFER_ REFERENCED_BY_TESS_EVALUATION_SHADER REFERENCED_BY_TESS_ EVALUATION_SHADER ATOMIC_COUNTER_BUFFER_ REFERENCED_BY_GEOMETRY_SHADER REFERENCED_BY_GEOMETRY_SHADER ATOMIC_COUNTER_BUFFER_ REFERENCED_BY_FRAGMENT_SHADER REFERENCED_BY_FRAGMENT_SHADER ATOMIC_COUNTER_BUFFER_ REFERENCED_BY_COMPUTE_SHADER REFERENCED_BY_COMPUTE_SHADER Table X.4, GetProgramResourceiv properties used by GetActiveAtomicCounterBufferiv. Modify Section 2.14.8, Subroutine Uniform Variables, p. 136 (This section could probably use some reorganization and a high-level introduction to how subroutines and subroutine variables work. As written now, it mostly talks about the GL APIs operating on these without a lot of conceptual discussion. These edits makes this section smaller by redefining the old APIs in terms of the new ones.) (replace language in the section describing the active subroutine and subroutine uniform enumeration with the following) To determine the set of active subroutines and subroutines used by a particular shader stage of a program, applications can query the properties and active resources of the interfaces for the shader type, as listed in Tables X.5 and X.6. Interface Shader Type ------------------------------ ------------------------------ VERTEX_SUBROUTINE VERTEX_SHADER TESS_CONTROL_SUBROUTINE TESS_CONTROL_SHADER TESS_EVALUATION_SUBROUTINE TESS_EVALUATION_SHADER GEOMETRY_SUBROUTINE GEOMETRY_SHADER FRAGMENT_SUBROUTINE FRAGMENT_SHADER COMPUTE_SUBROUTINE COMPUTE_SHADER Table X.5, Interfaces for active subroutines for a particular shader type in a program. Interface Shader Type ------------------------------ ------------------------------ VERTEX_SUBROUTINE_UNIFORM VERTEX_SHADER TESS_CONTROL_SUBROUTINE_ TESS_CONTROL_SHADER UNIFORM TESS_EVALUATION_SUBROUTINE TESS_EVALUATION_SHADER UNIFORM GEOMETRY_SUBROUTINE_UNIFORM GEOMETRY_SHADER FRAGMENT_SUBROUTINE_UNIFORM FRAGMENT_SHADER COMPUTE_SUBROUTINE_UNIFORM COMPUTE_SHADER Table X.6, Interfaces for active subroutine uniforms for a particular shader type in a program. Dedicated commands are provided to determine properties of active subroutines and active subroutine uniforms. The commands uint GetSubroutineIndex(uint program, enum shadertype, const char *name); void GetActiveSubroutineName(uint program, enum shadertype, uint index, sizei bufsize, sizei *length, char *name); are equivalent to GetProgramResourceIndex(program, programInterface, name); GetProgramResourceName(program, programInterface, index, bufsize, length, name); where is taken from Table X.5 according to the value of . The commands void GetSubroutineUniformLocation(uint program, enum shadertype, const char *name); void GetActiveSubroutineUniformName(uint program, enum shadertype, uint index, sizei bufsize, sizei *length, char *name); void GetActiveSubroutineUniformiv(uint program, enum shadertype, uint index, enum pname, int *values); are equivalent to GetProgramResourceLocation(program, programInterface, name); GetProgramResourceName(program, programInterface, index, bufsize, length, name); GetProgramResourceiv(program, programInterface, index, 1, &pname, maxSize, NULL, values); where is taken from Table X.6 according to the value of . For GetActiveSubroutineUniformiv, must be one of NUM_COMPATIBLE_SUBROUTINES or COMPATIBLE_SUBROUTINES, and is taken to specify a sufficiently large buffer to receive all values that would be written to . Modify Section 2.14.11, Output Variables, p. 140 (replace last paragraph, p. 143 through next-to-last paragraph, p. 144 with the following) To determine the set of output variables in a linked program object that will be captured in transform feedback mode, applications can query the properties and active resources of the TRANSFORM_FEEDBACK_VARYING interface. Additionally, the dedicated command void GetTransformFeedbackVarying(uint program, uint index, sizei bufSize, sizei *length, sizei *size, enum *type, char *name); can be used to enumerate properties of a single output variable captured in transform feedback mode, and is equivalent to const enum props[] = { ARRAY_SIZE, TYPE }; GetProgramResourceName(program, TRANSFORM_FEEDBACK_VARYING, index, bufSize, length, name); GetProgramResourceiv(program, TRANSFORM_FEEDBACK_VARYING, index, 1, &props[0], 1, NULL, size); GetProgramResourceiv(program, TRANSFORM_FEEDBACK_VARYING, index, 1, &props[1], 1, NULL, (int *) type); GetTransformFeedbackVarying may be used to query any transform feedback varying variable, not just those specified with TransformFeedbackVarying. Additions to Chapter 3 of the OpenGL 4.2 (Compatibility Profile) Specification (Rasterization) Modify Section 3.13.2, Shader Execution, p. 371 (replace next-to-last paragraph, p. 378 through the first paragraph, p. 379 with the following) To determine the set of fragment shader output attribute variables used by a program, applications can query the properties and active resources of the PROGRAM_OUTPUT interface of a program including a fragment shader. Additionally, dedicated commands are provided to query the location and fragment color index assigned to a fragment shader output variable. For the commands int GetFragDataLocation(uint program, const char *name); int GetFragDataIndex(uint program, const char *name); the error INVALID_OPERATION is generated and -1 is returned if has not been linked or was last linked unsuccessfully. If has been successfully linked but contains no fragment shader, no error will be generated but -1 will be returned. Otherwise, the commands are equivalent to calling: GetProgramResourceLocation(program, PROGRAM_OUTPUT, name); or GetProgramResourceLocationIndex(program, PROGRAM_OUTPUT, name); Additions to Chapter 4 of the OpenGL 4.2 (Compatibility Profile) Specification (Per-Fragment Operations and the Frame Buffer) None. Additions to Chapter 5 of the OpenGL 4.2 (Compatibility Profile) Specification (Special Functions) None. Note that all the commands added here are not included in display lists, but no specification edits are required since existing blanket language covers all Get* commands. Additions to Chapter 6 of the OpenGL 4.2 (Compatibility Profile) Specification (State and State Requests) None. Additions to Appendix A of the OpenGL 4.2 (Compatibility Profile) Specification (Invariance) None. Additions to Appendix D of the OpenGL 4.2 (Compatibility Profile) Specification (Shared Objects and Multiple Contexts) None. Additions to the AGL/EGL/GLX/WGL Specifications None GLX Protocol TBD Dependencies on OpenGL 3.0, ARB_transform_feedback, and EXT_transform_feedback If OpenGL 3.0, ARB_transform_feedback, and EXT_transform_feedback are not supported, references to the TRANSFORM_FEEDBACK_VARYING interface should be removed. Dependencies on OpenGL 3.1 and ARB_uniform_buffer_object If OpenGL 3.1 and ARB_uniform_buffer_object are not supported, references to the UNIFORM_BLOCK interface should be removed. Dependencies on OpenGL 4.0 and ARB_shader_subroutine If OpenGL 4.0 and ARB_shader_subroutine are not supported, references to the VERTEX_SUBROUTINE, TESS_CONTROL_SUBROUTINE, TESS_EVALUATION_SUBROUTINE, GEOMETRY_SUBROUTINE, FRAGMENT_SUBROUTINE, COMPUTE_SUBROUTINE, VERTEX_SUBROUTINE_UNIFORM, TESS_CONTROL_SUBROUTINE_UNIFORM, TESS_EVALUATION_SUBROUTINE_UNIFORM, GEOMETRY_SUBROUTINE_UNIFORM, FRAGMENT_SUBROUTINE_UNIFORM, and COMPUTE_SUBROUTINE_UNIFORM interfaces should be removed. Dependencies on OpenGL 4.2 and ARB_shader_atomic_counters If OpenGL 4.2 and ARB_shader_atomic_counters are not supported, references to the ATOMIC_COUNTER_BUFFER interfaces should be removed. Dependencies on OpenGL 4.3 and ARB_shader_storage_buffer_object If OpenGL 4.3 and ARB_shader_storage_buffer_object are not supported, references to the BUFFER_VARIABLE and SHADER_STORAGE_BLOCK interfaces should be removed. Dependencies on OpenGL 4.3 and ARB_arrays_of_arrays If OpenGL 4.3 and ARB_arrays_of_arrays are not supported, language describing the enumeration of multi-dimensional arrays (i.e., arrays of arrays) should be removed. Dependencies on OpenGL 4.3 and ARB_compute_shader If OpenGL 4.3 and ARB_compute_shader are not supported, references to the COMPUTE_SUBROUTINE and COMPUTE_SUBROUTINE_UNIFORM interfaces should be removed. Dependencies on OpenGL 4.3 and ARB_explicit_uniform_location If OpenGL 4.3 and ARB_explicit_uniform_location are not supported, references to uniform variables being declared with a layout qualifier should be removed. Errors An INVALID_VALUE error is generated by GetProgramInterfaceiv, GetProgramResourceIndex, GetProgramResourceName, GetProgramResourceiv, GetProgramResourceLocation, and GetProgramResourceLocationIndex if is not the name of either a shader or program object. An INVALID_OPERATION error is generated by GetProgramInterfaceiv, GetProgramResourceIndex, GetProgramResourceName, GetProgramResourceiv, GetProgramResourceLocation, and GetProgramResourceLocationIndex if is the name of a shader object. INVALID_OPERATION is generated by GetProgramInterfaceiv if the parameter is not supported for the interface . INVALID_ENUM is generated by GetProgramResourceIndex if is ATOMIC_COUNTER_BUFFER. INVALID_VALUE is generated by GetProgramResourceName if is greater than or equal to the number of entries in the active resource list for . INVALID_ENUM is generated by GetProgramResourceName if is ATOMIC_COUNTER_BUFFER. INVALID_VALUE is generated by GetProgramResourceiv if is zero. INVALID_ENUM is generated by GetProgramResourceiv if any value in is not a property name supported by the command. INVALID_OPERATION is generated by GetProgramResourceiv if any value in is not supported for the interface . INVALID_OPERATION is generated by GetProgramResourceLocation and GetProgramResourceLocationIndex if has not been linked or was last linked unsuccessfully. New State Insert new tables after Table 6.53, Program Object State (cont.), p. 557: Add table, labeled "Program Interface State" Initial Get Value Type Get Command Value Description Sec. ----------------------- ---- ----------- ------- ------------------------ ----- ACTIVE_RESOURCES nxZ+ GetProgramInterfaceiv 0 number of active resources 2.14.3 on an interface MAX_NAME_LENGTH nxZ+ GetProgramInterfaceiv 0 maximum name length for 2.14.3 active resources MAX_NUM_ACTIVE_VARIABLES nxZ+ GetProgramInterfaceiv 0 maximum number of active 2.14.3 variables for active resources MAX_NUM_COMPATIBLE_SUBROUTINES nxZ+ GetProgramInterfaceiv 0 maximum number of compat- 2.14.3 ible subroutines for subroutine uniforms Add table, labeled "Program Object Resource State" Initial Get Value Type Get Command Value Description Sec. ----------------------- ---- ----------- ------- ------------------------ ----- NAME_LENGTH Z+ GetProgram- - length of active resource 2.14.3 Resourceiv name TYPE Z+ GetProgram- - active resource data type 2.14.3 Resourceiv ARRAY_SIZE Z+ GetProgram- - active resource array size 2.14.3 Resourceiv OFFSET Z+ GetProgram- - active resource offset in 2.14.3 Resourceiv memory BLOCK_INDEX Z+ GetProgram- - index of interface block 2.14.3 Resourceiv owning resource ARRAY_STRIDE Z+ GetProgram- - active resource array 2.14.3 Resourceiv stride in memory MATRIX_STRIDE Z+ GetProgram- - active resource matrix 2.14.3 Resourceiv stride in memory IS_ROW_MAJOR Z+ GetProgram- - active resource stored as 2.14.3 Resourceiv a row major matrix? ATOMIC_COUNTER_BUFFER_INDEX Z+ GetProgram- - index of atomic counter 2.14.3 Resourceiv buffer owning resource BUFFER_BINDING Z+ GetProgram- - buffer binding assigned 2.14.3 Resourceiv to active resource BUFFER_DATA_SIZE Z+ GetProgram- - minimum buffer data size 2.14.3 Resourceiv required for resource NUM_ACTIVE_VARIABLES Z+ GetProgram- - number of active variables 2.14.3 Resourceiv owned by active resource ACTIVE_VARIABLES Z+ GetProgram- - list of active variables 2.14.3 Resourceiv owned by active resource REFERENCED_BY_VERTEX_SHADER Z+ GetProgram- - active resource used by 2.14.3 Resourceiv vertex shader? REFERENCED_BY_TESS_CONTROL_ Z+ GetProgram- - active resource used by 2.14.3 SHADER Resourceiv tess. control shader? REFERENCED_BY_TESS_EVALUATION_ Z+ GetProgram- - active resource used by 2.14.3 SHADER Resourceiv tess evaluation shader? REFERENCED_BY_GEOMETRY_SHADER Z+ GetProgram- - active resource used by 2.14.3 Resourceiv geometry shader? REFERENCED_BY_FRAGMENT_SHADER Z+ GetProgram- - active resource used by 2.14.3 Resourceiv fragment shader? REFERENCED_BY_COMPUTE_SHADER Z+ GetProgram- - active resource used by 2.14.3 Resourceiv compute shader? TOP_LEVEL_ARRAY_SIZE Z+ GetProgram- - array size of top level 2.14.3 Resourceiv shd. storage block member TOP_LEVEL_ARRAY_STRIDE Z+ GetProgram- - array stride of top level 2.14.3 Resourceiv shd. storage block member LOCATION Z+ GetProgram- - location assigned to 2.14.3 Resourceiv active resource LOCATION_INDEX Z+ GetProgram- - location index assigned 2.14.3 Resourceiv to active resource IS_PER_PATCH Z+ GetProgram- - is active input/output 2.14.3 Resourceiv a per-patch attribute? NUM_COMPATIBLE_SUBROUTINES Z+ GetProgram- - number of compatible 2.14.3 Resourceiv subroutines for active subroutine uniform COMPATIBLE_SUBROUTINES Z+ GetProgram- - list of compatible 2.14.3 Resourceiv subroutines for active subroutine uniform New Implementation Dependent State None. Sample Code !!! TBD !!! Conformance Tests !!! TBD !!! Issues (1) Does the list of active resources in a program include built-ins where applicable? RESOLVED: Yes; built-ins should be enumerated when present. (2) Should this extension fully support all program interfaces and resources, even those that have limited or no query capabilities today? In particular, there is very little enumeration support for fragment outputs and transform feedback varyings. OpenGL 4.1 added ARB_separate_shader_objects that allowed two independent programs to form an interface, but provided no mechanism for querying the active variables on either side of that interface. RESOLVED: Let's support as much as we can with a single set of functions. (3) How should we support enumeration of variables and interface blocks provided by the ARB_shader_storage_buffer_object extension? RESOLVED: The enumeration mechanisms provided by this extension will be the only way to enumerate buffer variables and shader storage blocks. ARB_shader_storage_buffer_object will require this extension. (4) The commands provided this extension are intended to supersede existing enumeration APIs (e.g., GetActiveUniform, GetActiveAttrib). The old APIs can eventually be deprecated. Both new and old APIs generate a list of active resources and assign indices to each entry in the list. Should assigned indices match between the new and old APIs? RESOLVED: Yes. While there is no strong reason why the new APIs couldn't adopt new enumeration rules for existing resource types, it's easier to enumerate the same way that we've done for the older API calls, for several reasons: * Minimizes changes for existing applications using the old enumeration APIs or for applications needing to support both the new and old APIs. All they need to do is map their existing API usage to the new APIs without having to reconsider whether any other assumption of their old logic is still valid. * Minimizes complexity for implementations needing to support both new and old APIs, at least until the old APIs are deprecated/removed. * Makes it easier to redefine the existing functions in terms of the new ones. (5) Existing enumeration APIs handle entities like arrays of structures by unrolling them. For example, a uniform array of structures with 8 elements and 3 structure members will result in 24 entries enumerated by GetActiveUniform. Should we re-work the API to enumerate fewer entries? RESOLVED: For existing resources, no, for the reasons discussed above. The main problem with that approach is if a shader uses a uniform block with a large array of structures. For newer resource types, we can and will adopt new rules. (6) How should enumeration rules work for complex arrays/structures in shader storage blocks (ARB_shader_storage_buffer_object)? RESOLVED: One of the intended use cases is to allow for shader storage blocks consisting of little more than a large (or unsized) array of structures. For example, we might have shader code like: struct VertexInfo { float position[3]; float normal[3]; }; buffer VertexCollection { VertexInfo v[10000]; }; If existing uniform enumeration API rules were applied, this would enumerate 20000 separate active resources (10000 array elements with two members each). That seems crazy. This specification optimizes for this case by flattening arrays at the top of the block. For that shader, we would enumerate only the first element of each array ("v[0].position[0]" and "v[0].normal[0]"). The properties TOP_LEVEL_ARRAY_SIZE and TOP_LEVEL_ARRAY_STRIDE allow applications to determine the size (if declared) and stride in buffer object memory. For more complex hierarchies, we chose to continue unrolling arrays in the middle of the hierarchy to avoid the need to specify a more complex API. For example, in this code struct VertexInfo { float position[3]; float normal[3]; }; struct TriangleInfo { VertexInfo v[3]; }; buffer VertexCollection { TriangleInfo t[10000]; }; we would unroll "TriangleInfo" and enumerate six resources: t[0].v[0].position[0] t[0].v[0].normal[0] t[0].v[1].position[0] t[0].v[1].normal[0] t[0].v[2].position[0] t[0].v[2].normal[0] Flattening "v[]" to a single entry would require either some sort of recursive enumeration (e.g., enumerate "t" as a structure and provide "pointers" to a collection of members), or some sort of new property that returns a variable-length array of strides. (7) The ARB_array_of_arrays extension allows shaders to declare multi-dimensional arrays that could be enumerated by this API? How should arrays of arrays be enumerated? RESOLVED: We define rules consistent with our enumeration rules for other complex types. For existing one-dimensional arrays, we enumerate a single entry if the array is an array of basic types, or separate entries for each array element if the array is an array of structures. We follow similar rules here. For a uniform array such as: uniform vec4 a[5][4][3]; we enumerate twenty different entries ("a[0][0][0]" through "a[4][3][0]"), each of which is treated as an array with three elements. This is morally equivalent to what you'd get if you worked around the limitation in current GLSL via: struct ArrayBottom { vec4 c[3]; }; struct ArrayMid { ArrayBottom b[3]; }; uniform ArrayMid a[5]; which would enumerate "a[0].b[0].c[0]" through "a[4].b[3].c[0]". We also apply the top-level array flattening for shader storage block members. For example: buffer Block { vec4 a[5][4][3]; }; would enumerate only four entries -- "a[0][0][0]" through "a[0][3][0]", where each enumerated entry corresponds to an array of size 3, has a top-level size of 5, and has a top-level stride appropriate for its layout in memory. (8) For GetProgramResourceIndex, what sort of strings can be used to match the resource names for arrays of arrays? For example, let's say a shader declares a uniform such as: uniform vec4 a[3][4][5]; Which one of the following names are accepted? "a[2][1][0]" to identify the base of the bottom-level array? "a[2][1]", to identify the same without the final "[0]"? "a[2]", equivalent to "a[2][0][0]"? Just "a", equivalent to "a[0][0][0]"? RESOLVED: We only accept entries of the form "a[2][1][0]" or "a[2][1]", which is consistent with the existing rules that only allow applications to omit the last index of a bottom-level array that has been rolled up. (9) Should be consolidate the commands GetAttribLocation, GetUniformLocation, GetSubroutineUniformLocation, GetFragDataLocation (and GetFragDataIndex) into a single generic API? RESOLVED: Yes. This spec provides GetProgramResourceLocation and GetProgramResourceLocationIndex commands to consolidate the existing set of commands. Additionally, GetProgramResourceiv can be used to query locations via the LOCATION and LOCATION_INDEX properties. There are a number of irregularities in the assignment of locations as compared to other uniform types: * Atomic counter uniforms, uniforms in blocks are not assigned locations. * Built in inputs and outputs are not assigned locations. * The locations of inputs other than vertex shader inputs and fragment shader outputs don't interact with any other GL state; they are used only for interfacing with other programs. For such variables, we choose the return the specified location number if a variable is declared with a layout qualifier, and -1 (no valid location) otherwise. Variables declared without location layout qualifiers will be assigned an internal location by the compiler/linker, but those locations do not necessarily correspond to the canonical integer locations supported in layout qualifiers. * For fragment shader outputs, not only do we have a location, but we also have an associated index that can be queried with GetFragDataIndex. (10) What should we do about tokens like ACTIVE_UNIFORMS and ACTIVE_UNIFORM_MAX_LENGTH that are specific to an interface, but are queried today by GetProgramiv? RESOLVED: We provide a new GetProgramInterfaceiv query to return properties of an interface. The value returned today by ACTIVE_UNIFORMS can be determined by calling GetProgramInterfaceiv with a of UNIFORM and a of ACTIVE_RESOURCES. ACTIVE_RESOURCES can also be used for other interfaces to get values returned today with other query tokens (e.g., ACTIVE_ATTRIBUTES). (11) What sort of interface should we use for querying properties of active resources? We have two different styles of query today. Functions like GetActiveUniform() allow applications to query multiple (fixed) properties of a single active uniform. Functions like GetActiveUniforms() allow applications to query a single property of multiple active uniforms? RESOLVED: GetProgramResourceiv allows applications to query multiple properties of a single resource in a single call; applications pass in an array of properties to query. We considered providing a command GetProgramResourcesiv that would have allowed an application to query multiple properties of multiple resources in a single call, by passing in an array of resource indices. We decided not to include this for simplicity. Also note that the most common use case we envisioned would be to query all properties of all active resources, with code like the following: struct VariableInfo { GLenum type; GLint location; }; GLenum inputProps[] = { GL_TYPE, GL_LOCATION }; GLuint nInputProps = sizeof(inputProps) / sizeof(GLenum); GLint nActive; glGetProgramInterface(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &nActive); VariableInfo *varInfo = malloc(nActive*sizeof(VariableInfo)); GLuint *indices = malloc(nActive*sizeof(GLuint)); for (GLuint i = 0; i < nActive; i++) { indices[i] = i; } glGetProgramResourcesiv(program, GL_PROGRAM_INPUT, nActive, indices, nInputProps, inputProps, nActive*nInputProps, NULL, (GLint*)varInfo); Such an API would require applications to fill in a dummy array of indices to express "all indices". With the simplified API, more GL calls are required, but the code is overall simpler: glGetProgramInterface(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &nActive); VariableInfo *varInfo = malloc(nActive*sizeof(VariableInfo)); for (GLuint i = 0; i < nActive; i++) { glGetProgramResourceiv(program, GL_PROGRAM_INPUT, i, nInputProps, inputProps, nActive*nInputProps, NULL, (GLint*) (&varInfo[i])); } (12) For GetProgramResourceiv, how should we handle queries of properties that return a variable number of values (e.g., COMPATIBLE_SUBROUTINES)? Should we support these queries in the general "multiple properties of multiple resources" query, or provide a separate "single property of single resource query"? Should we just write out a variable number of values to ? If we allow for a variable number of values to be written to , should we provide some sort of parameter to guard against overflows? RESOLVED: We will support these properties in the general "multiple properties of a single resource" query and write out the variable number of values to consecutive locations in the array. If an application wants to query such properties for multiple resources at once, it can parse the values returned by the GL. If NUM_COMPATIBLE_SUBROUTINES is immediately before COMPATIBLE_SUBROUTINES in the property list, the number of compatible subroutines written to the buffer (N) will be found immediately immediately prior to the N compatible subroutine numbers. We will provide a parameter to guard against overflow. Applications can ensure they have an adequately-sized buffer by calling GetProgramInterfaceiv with a of MAX_NUM_COMPATIBLE_SUBROUTINES to determine the maximum number of subroutines that will be written to any one buffer. It's not clear how valuable the variable-length enumeration queries actually are. Unextended OpenGL 4.2 has two such queries today: COMPATIBLE_SUBROUTINES and UNIFORM_BLOCK_ACTIVE_UNIFORMS. UNIFORM_BLOCK_ACTIVE_UNIFORMS isn't strictly needed; an application can determine this list themselves by querying the UNIFORM_BLOCK_INDEX property of each active uniform. We could do something similar for compatible subroutines. (13) Should we add a mechanism for enumerating subroutine types supported by a program and querying the subroutine type for subroutines and subroutine uniforms? RESOLVED: No. Such a mechanism could have been used to reduce the need for variable-length return values for GetProgramResourcesiv in some cases. Instead of supporting COMPATIBLE_SUBROUTINES (list all subroutines compatible with a uniform type), we could have allowed applications to query the subroutine type for both subroutines and subroutine uniforms and match them in application code. The problem with that approach is that subroutines can have multiple associated subroutine types, so a variable-length return value would still be needed to query subroutine types. (14) Should we support "REFERENCED_BY_*" for uniforms and buffer variables? RESOLVED: Yes. It isn't supported in unextended OpenGL 4.2, but the functionality seems to make sense. (15) Since this extension is being developed at the same time as compute shaders, should we add compute shader-specific enums for the old queries that would be superseded by the the queries added here? Or should we rely solely on the new queries? For example, should we add a new token "UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER"? RESOLVED: Yes, we will add old-style enums for the compute shader stage for all previously existing APIs. (16) How are inputs and outputs in the built-in interface block "gl_PerVertex" enumerated? RESOLVED: We will follow the default rule for enumerating block members in the OpenGL API, which is: * If a variable is a member of an interface block without an instance name, it is enumerated using just the variable name. * If a variable is a member of an interface block with an instance name, it is enumerated as "BlockName.Member", where "BlockName" is the name of the interface block (not the instance name) and "Member" is the name of the variable. For example, in the following code: uniform Block1 { int member1; }; uniform Block2 { int member2; } instance2; uniform Block3 { int member3; } instance3[2]; // uses two separate buffer bindings the three uniforms (if active) are enumerated as "member1", "Block2.member2", and "Block3.member3". For tessellation control, tessellation evaluation, and geometry shaders, per-vertex built-in inputs like gl_Position are in a block with an instance name of "gl_in[]". Additionally, for tessellation control shaders, per-vertex built-in outputs like gl_Position are in a block with an instance name of "gl_out[]". In these cases, applying the standard rules would result in an enumerated name of "gl_PerVertex.gl_Position". (17) Should we add support for enumerating per-patch shader inputs/outputs? If so, how to distinguish between per-vertex and per-patch? RESOLVED: Yes. When program inputs or outputs include per-patch attributes, those variables will be enumerated along with per-vertex attributes. To determine if an input or output is per-patch, use the resource property IS_PER_PATCH. (18) Do we enumerate the special "marker" variables for transform feedback varyings (gl_NextBuffer, gl_SkipComponents[1234])? If so, what are their properties? RESOLVED: Yes, we should definitely enumerate them so applications can determine programmatically what would be written to transform feedback buffers. This capability is already supported by the existing GetTransformFeedback query. We follow the existing behavior -- all of these entries are enumerated with a type of NONE. gl_NextBuffer returns an array size of 0; gl_SkipComponents[1234] returns an array size equal to the specified number of components. (19) Should we support a arguments to prevent buffer overflows on the GetProgramInterfaceiv query? RESOLVED: Yes, to provide a "safe" mechanism since the query might return an unpredictable and program-dependent amount of data. We also provide a parameter that can be used to return the number of words written by the query to be consistent with other similar APIs. (20) Are "old" token names (e.g., UNIFORM_TYPE) accepted by "new" commmands (GetProgramResourceiv)? Are "new" token names (TYPE) accepted by "old" commands (GetActiveUniforms)? RESOLVED: No. New queries support only the new enums; old queries support only the old ones. (21) While programs may include shader code for multiple stages, shader subroutines and subroutine uniforms are specific to a single stage in the program. This means that there is a separate interface for each program stage. Should we specify tokens for a cross-product of interfaces and stages (e.g., VERTEX_SUBROUTINE, FRAGMENT_SUBROUTINE_UNIFORM)? Or should we provide generic tokens (SUBROUTINE, SUBROUTINE_UNIFORM) and accept a second parameter? RESOLVED: Use concatenated tokens to avoid creating adding a separate set of per-stage APIs. With this solution, we have means 12 concatenated tokens (6 stages crossed with SUBROUTINE and SUBROUTINE_UNIFORM); we don't expect a massive number of new tokens in the future. (22) What data type should be used for the (return data) argument to GetProgramResourceiv()? RESOLVED: Use an "int *" to be consistent with all the other "*iv"-style queries. We considered using a "void *" so applications could avoid manual casts for cases where the API would be used to fill a structure with properties of a resource, as in code like the following: struct VariableInfo { GLenum type; GLint location; } varInfo; GLenum inputProps[] = { GL_TYPE, GL_LOCATION }; GLuint nInputProps = sizeof(inputProps) / sizeof(GLenum); ... glGetProgramResourceiv(program, GL_PROGRAM_INPUT, index, nInputProps, inputProps, nInputProps, NULL, (GLint*)varInfo); (23) The special "marker" names "gl_NextBuffer" and "gl_SkipComponents*" may appear multiple times in the array of strings passed to TransformFeedbackVaryings. How is this condition handled in the new enumeration APIs? RESOLVED: For the purposes of enumerating active resources in the TRANSFORM_FEEDBACK_VARYINGS interface, each instance of the marker is assigned its own index, and the name and properties associated with that index can be queried. [See also issue (18).] This is consistent with how GetTransformFeedbackVaryings works in unextended OpenGL 4.2. The problem is that since a marker name can have multiple associated indices, it's not clear what value should be returned when passing such a string to GetProgramResourceIndex(). We specify that passing any of these marker strings should return the value INVALID_INDEX, regardless of the number of times the marker appears in the inputs to TransformFeedbackVaryings. Unextended OpenGL 4.2 does not provide the ability to query the index associated with an active transform feedback varying name, so this is a new issue in this extension. (24) The PROGRAM_INPUT and PROGRAM_OUTPUT interfaces are provided to allow applications to query active inputs and outputs in a program. Do we enumerate all variables qualified with "in" and "out", or should special "system" built-ins such as gl_VertexID, gl_InstanceID, and gl_FrontFacing be excluded? RESOLVED: We enumerate all active variables qualified with "in" or "out" in the PROGRAM_INPUT and PROGRAM_OUTPUT interfaces, including special variables. Additionally, because we redefine the function glGetActiveAttrib in terms of this in terms of the PROGRAM_INPUT interface, we should enumerate the specials gl_VertexID and gl_InstanceID there as well. Previously, there was no explicit spec language whether these variables should be enumerated by GetActiveAttrib, and various OpenGL implementations behaved differently. This approach allows applications to enumerate all inputs used by a vertex shader, whether or not they correspond to attributes in conventional or generic vertex attribute arrays. (25) What should the value of ARRAY_SIZE be for non-array and unsized array variables? RESOLVED: For compatibility with GetActiveUniform, ARRAY_SIZE of a non-array variable is one (initially this was specified as zero, an unintentional incompatibility). For unsized array variables, the size is zero. Revision History Revision 21, January 10, 2019 (Jon Leech) - Add the property COMPATIBLE_SUBROUTINES to those queriable by GetProgramResourceiv (github OpenGL-Registry issue #11) Revision 20, August 19, 2013 (Jon Leech) - Change ARRAY_SIZE query to return one for active variables not corresponding to an array of basic types, rather than zero, for compatibility with GetActiveUniform (Bug 10647). Return zero for explicitly unsized arrays (Bug 10641). Add extra 'const' qualifier for GetUniformIndices argument (Bug 10703). Revision 19, July 11, 2013 (Jon Leech) - Clarify that GetTransformFeedbackVarying can be used to query any transform feedback varying variable (Bug 10472). Revision 18, July 10, 2012 (pbrown) - Specify an INVALID_ENUM error when ATOMIC_COUNTER_BUFFER is passed to GetProgramResourceIndex or GetProgramResourceName. Clarify that the array element portion of a string passed to GetProgramResourceLocation or GetProgramResourceLocationIndex must not have, a "+" sign, extra leading zeroes, or whitespace (bug 9254). Revision 17, July 7, 2012 (pbrown) - Specify that "special" built-ins inputs and outputs such as "gl_VertexID" should be enumerated in the PROGRAM_INPUT and PROGRAM_OUTPUT interfaces, as well as the legacy function GetActiveAttrib. Add spec language counting the built-ins gl_VertexID and gl_InstanceID against the active attribute limit (bug 9201). Revision 16, July 2, 2012 (pbrown) - Fix typos in the language mapping OpenGL 4.2 active subroutine and subroutine uniform enumeration functions to the new interfaces. Revision 15, June 21, 2012 (Jon Leech) - Update errors to match the generic errors for all commands taking names (INVALID_VALUE if neither a shader nor program object name, and INVALID_OPERATION if a shader object name) (Bug 9145). Revision 14, June 14, 2012 (Jon Leech) - Add INVALID_VALUE error if is not the name of a valid program object (Bug 9145). Revision 13, May 31, 2012 (pbrown) - Specify that passing the special "marker" strings "gl_NextBuffer" and "gl_SkipComponents*" to GetProgramResourceIndex() will always return INVALID_INDEX (bug 9071). Revision 12, May 31, 2012 (pbrown) - Allow the BUFFER_VARIABLE, PROGRAM_INPUT, and PROGRAM_OUTPUT interfaces to be used by the REFERENCED_BY_*_SHADER property in GetProgramResourceiv (bug 9007). - Remove duplicate reference to BUFFER_VARIABLE in the list of interfaces supported by the ARRAY_SIZE property in GetProgramResourceiv. Revision 11, May 18, 2012 (pbrown) - Clarify that the LOCATION_INDEX property is only supported for the PROGRAM_OUTPUT interface and not for PROGRAM_INPUT. Revision 10, May 10, 2012 (pbrown) - Rename the formal parameter used by the functions in this extension to . Certain versions of the Microsoft C/C++ compiler and/or its headers cause "interface" to be treated as a reserved keyword. Revision 9, May 10, 2012 (pbrown) - Fix incorrect enumerant assignments. ATOMIC_COUNTER_BUFFER has already been assigned for ARB_shader_atomic_counters. Fix cut-and-paste error assigning a duplicate value to TESS_CONTROL_SUBROUTINE. Reassign value for IS_PER_PATCH to fill the ATOMIC_COUNTER_BUFFER hole. Revision 8, May 2, 2012 (pbrown) - Reserve enumerants. - Add state table entries. - Mark issues as resolved per the Khronos F2F. - Add issue (22), where we decided to keep the "int *" argument to GetProgramResourceiv(). Revision 7, April 25, 2012 - Rename IS_PATCH_ATTRIB to IS_PER_PATCH (bug 8752). Revision 6, April 12, 2012 - Add explicit language indicating that per-patch attributes can be enumerated in the PROGRAM_INPUT and PROGRAM_OUTPUT interfaces, plus the IS_PATCH_ATTRIB property. - Take a first cut at redefining all the existing enumeration APIs in terms of the new APIs. - Add missing OFFSET token to new token list. - Rename BUFFER_SIZE to BUFFER_DATA_SIZE to be consistent with older token names. - Mark various issues as resolved. Revision 5, April 12, 2012 - Remove support for querying properties of multiple resources in a single call; rename GetProgramResourcesiv to GetProgramResourceiv since only a single resource is queried at a time. - Fold issue (22) into issue (11). Revision 4, April 5, 2012 - Add issue (22) about the need to allocate/fill an array of indices even if you want to query properties of all active resources at once. Revision 3, April 5, 2012 - Checkpoint with various edits/cleanups. Add an introduction; clean up new procedures, tokens, errors, and issues sections. - Rename APIs to GetProgramInterface and GetProgramResource*. - Add GetProgramResourceLocation API as a generic location query. - Add interactions with ARB_compute_shader. - Add interactions with ARB_explicit_uniform_location. - Add discussion of enumeration of built-in variables and special transform feedback markers. - Add general discussion of locations assigned to active variables. - Add interface properties MAX_NUM_ACTIVE_VARIABLES and MAX_NUM_COMPATIBLE_SUBROUTINES. - Add resource properties LOCATION and LOCATION_INDEX. - Add and parameters to GetProgramResourcesiv. Revision 2, March 22, 2012 - Added new function prototypes for review purposes. Revision 1, March 14, 2012 - Initial revision.