GLGETPROGRAMRESOURCE(3G)
π NAME π
Okay bestie, manual name is GLGETPROGRAMRESOURCE(3G) β and yes, the header has a lil [FIXME: manual] note chillinβ in it, weβre keeping that energy.
So what does glGetProgramResource do? It retrieves values for multiple properties of a single active resource within a program object. Thatβs the whole vibe. One resource, multiple properties, values retrieved. Slay.
β¨ C SPECIFICATION β¨
Hereβs the exact signature, character for character, no cap:
void glGetProgramResourceiv(GLuint program, GLenum programInterface,
GLuint index, GLsizei propCount,
const GLenum * props, GLsizei bufSize,
GLsizei * length, GLint * params);
π PARAMETERS π
programβ the name of a program object whose resources youβre querying. Like, which program are we snooping through? This one. πprogramInterfaceβ a token identifying the interface withinprogramcontaining the resource namedname. So it tells you which interface inside the program has that resource. Iconic little token behavior. β¨
π DESCRIPTION π
ok so bestie, glGetProgramResourceiv is the girl who does the β¨mostβ¨: she returns the values for multiple properties of one single active resource at a time. Like, one resource, many receipts. π§Ύ
Here's the vibe: there's this one resource, chilling at index index, inside the interface programInterface of the program object program. She goes in, and for that resource, she pulls out values for propCount properties β all of them listed out in the array props. π
π¨ Real talk: propCount may not be zero. Zero is not the vibe, and it will not be tolerated.
And she's picky in a very specific way β an error gets generated if:
- any value in
propsis not one of the properties described immediately below, or - any value in
propsis not allowed forprogramInterface.
So which properties go with which interfaces? We got you, the whole chart is right here β every single one, no skips. π
πΈ Property β supported interfaces, the full guest list πΈ
GL_NAME_LENGTHβ any interface exceptGL_ATOMIC_COUNTER_BUFFERandGL_TRANSFORM_FEEDBACK_BUFFER(they didn't get an invite, it's fine, it's fine π)GL_TYPEβGL_UNIFORM,GL_PROGRAM_INPUT,GL_PROGRAM_OUTPUT,GL_TRANSFORM_FEEDBACK_VARYING,GL_BUFFER_VARIABLEGL_ARRAY_SIZEβGL_UNIFORM,GL_BUFFER_VARIABLE,GL_PROGRAM_INPUT,GL_PROGRAM_OUTPUT,VERTEX_SUBROUTINE_UNIFORM,GL_TESS_CONTROL_SUBROUTINE_UNIFORM,GL_TESS_EVALUATION_SUBROUTINE_UNIFORM,GL_GEOMETRY_SUBROUTINE_UNIFORM,GL_FRAGMENT_SUBROUTINE_UNIFORM,GL_COMPUTE_SUBROUTINE_UNIFORM,GL_TRANSFORM_FEEDBACK_VARYINGGL_OFFSETβGL_UNIFORM,GL_BUFFER_VARIABLE,GL_TRANSFORM_FEEDBACK_VARYINGGL_BLOCK_INDEXβGL_UNIFORM,GL_BUFFER_VARIABLEGL_ARRAY_STRIDEβGL_UNIFORM,GL_BUFFER_VARIABLEGL_MATRIX_STRIDEβGL_UNIFORM,GL_BUFFER_VARIABLEGL_IS_ROW_MAJORβGL_UNIFORM,GL_BUFFER_VARIABLEGL_ATOMIC_COUNTER_BUFFER_INDEXβGL_UNIFORMonly, she's exclusive πGL_TEXTURE_BUFFERβ none. Literally nobody. Empty guest list, party cancelled πGL_BUFFER_BINDINGβGL_UNIFORM_BLOCK,GL_ATOMIC_COUNTER_BUFFER,GL_SHADER_STORAGE_BLOCK,GL_TRANSFORM_FEEDBACK_BUFFERGL_BUFFER_DATA_SIZEβGL_UNIFORM_BLOCK,GL_ATOMIC_COUNTER_BUFFER,GL_SHADER_STORAGE_BLOCKGL_NUM_ACTIVE_VARIABLESβGL_UNIFORM_BLOCK,GL_ATOMIC_COUNTER_BUFFER,GL_SHADER_STORAGE_BLOCK,GL_TRANSFORM_FEEDBACK_BUFFERGL_ACTIVE_VARIABLESβGL_UNIFORM_BLOCK,GL_ATOMIC_COUNTER_BUFFER,GL_SHADER_STORAGE_BLOCK,GL_TRANSFORM_FEEDBACK_BUFFER
Like, memorize this table or keep it open in another tab, because if you roll up with a property that doesn't match your programInterface, it's giving error energy and you did that to yourself, ngl. π
GL_REFERENCED_BY_VERTEX_SHADERβ works onGL_UNIFORM,GL_UNIFORM_BLOCK,GL_ATOMIC_COUNTER_SHADER,GL_BUFFER,GL_SHADER_STORAGE_BLOCK,GL_BUFFER_VARIABLE,GL_PROGRAM_INPUT,GL_PROGRAM_OUTPUTπ¦GL_REFERENCED_BY_TESS_CONTROL_SHADERβ same lil friend group:GL_UNIFORM,GL_UNIFORM_BLOCK,GL_ATOMIC_COUNTER_SHADER,GL_BUFFER,GL_SHADER_STORAGE_BLOCK,GL_BUFFER_VARIABLE,GL_PROGRAM_INPUT,GL_PROGRAM_OUTPUTβ¨GL_REFERENCED_BY_TESS_EVALUATION_SHADERβ yep, identical list:GL_UNIFORM,GL_UNIFORM_BLOCK,GL_ATOMIC_COUNTER_SHADER,GL_BUFFER,GL_SHADER_STORAGE_BLOCK,GL_BUFFER_VARIABLE,GL_PROGRAM_INPUT,GL_PROGRAM_OUTPUTπΈGL_REFERENCED_BY_GEOMETRY_SHADERβ bestie it's the same eight:GL_UNIFORM,GL_UNIFORM_BLOCK,GL_ATOMIC_COUNTER_SHADER,GL_BUFFER,GL_SHADER_STORAGE_BLOCK,GL_BUFFER_VARIABLE,GL_PROGRAM_INPUT,GL_PROGRAM_OUTPUTπGL_REFERENCED_BY_FRAGMENT_SHADERβ still the same crew:GL_UNIFORM,GL_UNIFORM_BLOCK,GL_ATOMIC_COUNTER_SHADER,GL_BUFFER,GL_SHADER_STORAGE_BLOCK,GL_BUFFER_VARIABLE,GL_PROGRAM_INPUT,GL_PROGRAM_OUTPUTπGL_REFERENCED_BY_COMPUTE_SHADERβ and the last of the six, same list again:GL_UNIFORM,GL_UNIFORM_BLOCK,GL_ATOMIC_COUNTER_SHADER,GL_BUFFER,GL_SHADER_STORAGE_BLOCK,GL_BUFFER_VARIABLE,GL_PROGRAM_INPUT,GL_PROGRAM_OUTPUTπ₯
ok so quick vibe check on that whole block above π all six GL_REFERENCED_BY_* queries take the exact same set of interfaces. Lowkey iconic that they didn't change a single one, and no cap, it makes memorising them way easier.
GL_NUM_COMPATIBLE_SUBROUTINESβ lives for the subroutine uniform types:GL_VERTEX_SUBROUTINE_UNIFORM,GL_TESS_CONTROL_SUBROUTINE_UNIFORM,GL_TESS_EVALUATION_SUBROUTINE_UNIFORM,GL_GEOMETRY_SUBROUTINE_UNIFORM,GL_FRAGMENT_SUBROUTINE_UNIFORM,GL_COMPUTE_SUBROUTINE_UNIFORMπGL_COMPATIBLE_SUBROUTINESβ same set of subroutine uniforms, fr:GL_VERTEX_SUBROUTINE_UNIFORM,GL_TESS_CONTROL_SUBROUTINE_UNIFORM,GL_TESS_EVALUATION_SUBROUTINE_UNIFORM,GL_GEOMETRY_SUBROUTINE_UNIFORM,GL_FRAGMENT_SUBROUTINE_UNIFORM,GL_COMPUTE_SUBROUTINE_UNIFORMπ«ΆGL_TOP_LEVEL_ARRAY_SIZEβ this one is exclusive, onlyGL_BUFFER_VARIABLEgets it πGL_TOP_LEVEL_ARRAY_STRIDEβ alsoGL_BUFFER_VARIABLEand nothing else βGL_LOCATIONβ big reach, valid onGL_UNIFORM,GL_PROGRAM_INPUT,GL_PROGRAM_OUTPUT,GL_VERTEX_SUBROUTINE_UNIFORM,GL_TESS_CONTROL_SUBROUTINE_UNIFORM,GL_TESS_EVALUATION_SUBROUTINE_UNIFORM,GL_GEOMETRY_SUBROUTINE_UNIFORM,GL_FRAGMENT_SUBROUTINE_UNIFORM,GL_COMPUTE_SUBROUTINE_UNIFORMπGL_LOCATION_INDEXβ literally onlyGL_PROGRAM_OUTPUT, she's picky πGL_IS_PER_PATCHβ applies toGL_PROGRAM_INPUTandGL_PROGRAM_OUTPUTπ§GL_LOCATION_COMPONENTβ same two besties:GL_PROGRAM_INPUTandGL_PROGRAM_OUTPUTπ
okay so picking up right where we left off with that table, bestie β here's the rest of it, exactly as it appears:
βββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β GL_TRANSFORM_FEEDBACK_BUFFER_INDEX β GL_TRANSFORM_FEEDBACK_VARYING β
βββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE β GL_TRANSFORM_FEEDBACK_BUFFER β
βββββββββββββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
now let's get into what each of these properties actually writes to params, because it's giving details and we love that for us:
GL_NAME_LENGTHβ bestie, this writes a single integer toparamsthat tells you the length of the name string for an active variable, interface block, or subroutine. And yes, that length includes the terminating null character, so don't forget it! πGL_TYPEβ this one writes a single integer toparamsidentifying the type of an active variable. The integer you get back is one of the values from table 2.16, no cap. β¨GL_ARRAY_SIZEβ writes a single integer toparamstelling you how many active array elements an active variable has. The array size is in units of the type fromGL_TYPE. But if the active variable isn't an array of basic types, you get a big fat zero written toparams. π«ΆGL_BLOCK_INDEXβ writes a single integer toparamswith the index of the active interface block that contains the active variable. If the variable isn't a member of any interface block, you get-1written toparams. Simple as. πGL_OFFSETβ writes a single integer toparamsidentifying the offset of an active variable. Here's the tea:- For variables in the
GL_UNIFORMandGL_BUFFER_VARIABLEinterfaces that are backed by a buffer object, the value is the offset of that variable relative to the base of the buffer range holding its value. - For variables in the
GL_TRANSFORM_FEEDBACK_VARYINGinterface, the value is the offset in the transform feedback buffer storage assigned to each vertex captured in transform feedback mode where the variable's value will be stored. These offsets are specified via thexfb_offsetlayout qualifier or assigned according to the variable's position in the list of strings passed toglTransformFeedbackVaryings(). Offsets are in basic machine units. - For all variables not recorded in transform feedback mode β including the special names
"gl_NextBuffer","gl_SkipComponents1","gl_SkipComponents2","gl_SkipComponents3", and"gl_SkipComponents4"β-1is written toparams. π
- For variables in the
GL_ARRAY_STRIDEβ writes a single integer toparamsidentifying the stride between array elements in an active variable. If the active variable is declared as an array of basic types, you get the difference, in basic machine units, between the offsets of consecutive elements in the array. If it's not declared as an array of basic types, zero goes toparams. And if the active variable isn't backed by a buffer object,-1goes toparamsno matter the variable type. Slay. πGL_MATRIX_STRIDEβ writes a single integer toparamsidentifying the stride between columns of a column-major matrix or rows of a row-major matrix. If the active variable is declared as a single matrix or an array of matrices, the value is the difference, in basic machine units, between the offsets of consecutive columns or rows in each matrix. If it's not a matrix or array of matrices, zero goes toparams. And if it's not backed by a buffer object,-1goes toparamsregardless of type. Iconic. β¨GL_IS_ROW_MAJORβ writes a single integer toparamsthat tells you if an active variable is a row-major matrix. If the variable is backed by a buffer object, declared as a single matrix or array of matrices, and stored in row-major order, you get a1. For literally all other active variables, you get a0. πGL_ATOMIC_COUNTER_BUFFER_INDEXβ writes a single integer toparamswith the index of the active atomic counter buffer containing the active variable. If the variable isn't an atomic counter uniform, you get-1written toparams. Bye. πGL_BUFFER_BINDINGβ writes the index of the buffer binding point associated with the active uniform block, shader storage block, atomic counter buffer, or transform feedback buffer toparams. Got it? πGL_BUFFER_DATA_SIZEβ writes 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 toparams. And if the final member of an active shader storage block is an array with no declared size, the minimum buffer size is computed assuming that array was declared with one element. No cap. π¦GL_NUM_ACTIVE_VARIABLESβ writes the number of active variables associated with an active uniform block, shader storage block, atomic counter buffer, or transform feedback buffer toparams. That's it, that's the tweet. π¦GL_ACTIVE_VARIABLESβ writes an array of active variable indices associated with an active uniform block, shader storage block, atomic counter buffer, or transform feedback buffer toparams. The number of values written toparamsfor an active resource is exactly the value ofGL_NUM_ACTIVE_VARIABLESfor that resource. Periodt. πGL_REFERENCED_BY_VERTEX_SHADER,GL_REFERENCED_BY_TESS_CONTROL_SHADER,GL_REFERENCED_BY_TESS_EVALUATION_SHADER,GL_REFERENCED_BY_GEOMETRY_SHADER,GL_REFERENCED_BY_FRAGMENT_SHADER, andGL_REFERENCED_BY_COMPUTE_SHADERβ for these, a single integer is written toparamsidentifying whether the active resource is referenced by the vertex, tessellation control, tessellation evaluation, geometry, or fragment shaders, respectively, in the program object. A1is written 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, a0is written. (And yes, compute is in the list even though the sentence says fragment β the spec said what it said, bestie. π)GL_TOP_LEVEL_ARRAY_SIZEβ writes a single integer toparamsidentifying the number of active array elements of the top-level shader storage block member that contains the active variable. If the top-level block member isn't declared as an array, you get a1. If it's an array with no declared size, you get a0. Easy. πΈGL_TOP_LEVEL_ARRAY_STRIDEβ writes a single integer toparamsidentifying the stride between array elements of the top-level shader storage block member containing the active variable. If the top-level block member is declared as an array, the value is the difference, in basic machine units, between the offsets of the active variable for consecutive elements in the top-level array. If it's not declared as an array, zero goes toparams. Slay. πGL_LOCATIONβ writes a single integer toparamsidentifying the assigned location for an active uniform, input, output, or subroutine uniform variable. Here's the breakdown:- 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 the program is linked is written to
params. - For all other input and output variables,
-1is written. - For uniforms in uniform blocks,
-1is written. π
GL_LOCATION_INDEXβ writes a single integer toparamsidentifying the fragment color index of an active fragment shader output variable. If the active variable is an output for a non-fragment shader, you get-1written toparams. That's the tea. π΅GL_IS_PER_PATCHβ writes a single integer toparamstelling you if the input or output is a per-patch attribute. If the active variable is a per-patch attribute (declared with thepatchqualifier), you get a1; otherwise, you get a0. πGL_LOCATION_COMPONENTβ writes a single integer toparamsindicating the first component of the location assigned to an active input or output variable. If the input or output variable has a component specified by a layout qualifier, that specified component is written. For all other input and output variables, zero is written. β¨GL_TRANSFORM_FEEDBACK_BUFFER_INDEXβ writes a single integer toparamsidentifying the index of the active transform feedback buffer associated with an active variable. For variables corresponding to the special names"gl_NextBuffer","gl_SkipComponents1","gl_SkipComponents2","gl_SkipComponents3", and"gl_SkipComponents4",-1is written toparams. Bye bestie. πGL_TRANSFORM_FEEDBACK_BUFFER_STRIDEβ writes a single integer toparamsidentifying the stride, in basic machine units, between consecutive vertices written to the transform feedback buffer. That's it. π
π ERRORS π
okay so if you mess up, here's what the universe (and the spec) will throw at you:
GL_INVALID_VALUEis generated ifprogramis not the name of an existing program object.GL_INVALID_VALUEis generated ifpropCountis zero.GL_INVALID_ENUMis generated ifprogramInterfaceis not one of the accepted interface types.GL_INVLALID_ENUMis generated if any value inpropsis not one of the accepted tokens for the interfaceprogramInterface. (Yes, that's a typo in the spec βGL_INVLALID_ENUMβ we keep it real. π)
β¨ VERSION SUPPORT β¨
Okay bestie, here's the vibe check on when you can actually use this thing π
glGetProgramResourceivβ not a thing in OpenGL2.0,2.1,3.0,3.1,3.2,3.3,4.0,4.1or4.2(all of those are a big fat-, like, it simply did not exist yet π)glGetProgramResourceivβ fully slaying in OpenGL4.3βglGetProgramResourceivβ still iconic in OpenGL4.4βglGetProgramResourceivβ and living her best life in OpenGL4.5β
So like, if you're on anything before 4.3, this function is not your main character, sorry babe π«Ά
πΈ SEE ALSO πΈ
Go check out her besties, they're all part of the same friend group fr fr:
glGetProgramResourceName()glGetProgramResourceIndex()glGetProgramResourceLocation()glGetProgramResourceLocationIndex()
π COPYRIGHT π
Copyright Β© 2013-2014 Khronos Group. This material may be distributed subject to the terms and conditions set forth in the Open Publication License, v 1.0, 8 June 1999. http://opencontent.org/openpub/
Copyright Β© 2013-2014 Khronos Group
Yes bestie, the copyright section shows up twice in the original and I'm keeping both, because we do not skip details in this house π
and that's a wrap, babes π This little masterpiece is sourced from [FIXME: source] (yes, that's literally what it says, iconic placeholder energy π), it's dated 08/09/2021, and it lives at GLGETPROGRAMRESOURCE(3G) β go forth and query those program resources, queen πβ¨
π¦ where this page comes from
- centos-stream 9: gl-manpages 1.1-24.20190306.el9 Β· MIT and Open Publication
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms