/** * glGetProgramiv() - get shader program state. * Note that this is for GLSL shader programs, not ARB vertex/fragment * programs (see glGetProgramivARB). */ static void get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *params) { struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); /* Is transform feedback available in this context? */ const bool has_xfb = (ctx->API == API_OPENGL && ctx->Extensions.EXT_transform_feedback) || ctx->API == API_OPENGL_CORE || _mesa_is_gles3(ctx); /* Are geometry shaders available in this context? */ const bool has_gs = _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4; /* Are uniform buffer objects available in this context? */ const bool has_ubo = (ctx->API == API_OPENGL && ctx->Extensions.ARB_uniform_buffer_object) || ctx->API == API_OPENGL_CORE || _mesa_is_gles3(ctx); if (!shProg) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)"); return; } switch (pname) { case GL_DELETE_STATUS: *params = shProg->DeletePending; return; case GL_LINK_STATUS: *params = shProg->LinkStatus; return; case GL_VALIDATE_STATUS: *params = shProg->Validated; return; case GL_INFO_LOG_LENGTH: *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0; return; case GL_ATTACHED_SHADERS: *params = shProg->NumShaders; return; case GL_ACTIVE_ATTRIBUTES: *params = _mesa_count_active_attribs(shProg); return; case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: *params = _mesa_longest_attribute_name_length(shProg); return; case GL_ACTIVE_UNIFORMS: *params = shProg->NumUserUniformStorage; return; case GL_ACTIVE_UNIFORM_MAX_LENGTH: { unsigned i; GLint max_len = 0; for (i = 0; i < shProg->NumUserUniformStorage; i++) { /* Add one for the terminating NUL character. */ const GLint len = strlen(shProg->UniformStorage[i].name) + 1; if (len > max_len) max_len = len; } *params = max_len; return; } case GL_TRANSFORM_FEEDBACK_VARYINGS: if (!has_xfb) break; *params = shProg->TransformFeedback.NumVarying; return; case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: if (!has_xfb) break; *params = longest_feedback_varying_name(shProg) + 1; return; case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: if (!has_xfb) break; *params = shProg->TransformFeedback.BufferMode; return; case GL_GEOMETRY_VERTICES_OUT_ARB: if (!has_gs) break; *params = shProg->Geom.VerticesOut; return; case GL_GEOMETRY_INPUT_TYPE_ARB: if (!has_gs) break; *params = shProg->Geom.InputType; return; case GL_GEOMETRY_OUTPUT_TYPE_ARB: if (!has_gs) break; *params = shProg->Geom.OutputType; return; case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: { unsigned i; GLint max_len = 0; if (!has_ubo) break; for (i = 0; i < shProg->NumUniformBlocks; i++) { /* Add one for the terminating NUL character. */ const GLint len = strlen(shProg->UniformBlocks[i].Name) + 1; if (len > max_len) max_len = len; } *params = max_len; return; } case GL_ACTIVE_UNIFORM_BLOCKS: if (!has_ubo) break; *params = shProg->NumUniformBlocks; return; default: break; } _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname=%s)", _mesa_lookup_enum_by_nr(pname)); }
/** * glGetProgramiv() - get shader program state. * Note that this is for GLSL shader programs, not ARB vertex/fragment * programs (see glGetProgramivARB). */ static void get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *params) { struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); if (!shProg) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)"); return; } switch (pname) { case GL_DELETE_STATUS: *params = shProg->DeletePending; break; case GL_LINK_STATUS: *params = shProg->LinkStatus; break; case GL_VALIDATE_STATUS: *params = shProg->Validated; break; case GL_INFO_LOG_LENGTH: *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0; break; case GL_ATTACHED_SHADERS: *params = shProg->NumShaders; break; case GL_ACTIVE_ATTRIBUTES: *params = _mesa_count_active_attribs(shProg); break; case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: *params = _mesa_longest_attribute_name_length(shProg); break; case GL_ACTIVE_UNIFORMS: *params = shProg->NumUserUniformStorage; break; case GL_ACTIVE_UNIFORM_MAX_LENGTH: { unsigned i; GLint max_len = 0; for (i = 0; i < shProg->NumUserUniformStorage; i++) { /* Add one for the terminating NUL character. */ const GLint len = strlen(shProg->UniformStorage[i].name) + 1; if (len > max_len) max_len = len; } *params = max_len; break; } case GL_PROGRAM_BINARY_LENGTH_OES: *params = 0; break; #if FEATURE_EXT_transform_feedback case GL_TRANSFORM_FEEDBACK_VARYINGS: *params = shProg->TransformFeedback.NumVarying; break; case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: *params = longest_feedback_varying_name(shProg) + 1; break; case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: *params = shProg->TransformFeedback.BufferMode; break; #endif #if FEATURE_ARB_geometry_shader4 case GL_GEOMETRY_VERTICES_OUT_ARB: *params = shProg->Geom.VerticesOut; break; case GL_GEOMETRY_INPUT_TYPE_ARB: *params = shProg->Geom.InputType; break; case GL_GEOMETRY_OUTPUT_TYPE_ARB: *params = shProg->Geom.OutputType; break; #endif default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)"); return; } }
/** * glGetProgramiv() - get shader program state. * Note that this is for GLSL shader programs, not ARB vertex/fragment * programs (see glGetProgramivARB). */ static void get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *params) { struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); /* Is transform feedback available in this context? */ const bool has_xfb = (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.EXT_transform_feedback) || ctx->API == API_OPENGL_CORE || _mesa_is_gles3(ctx); /* True if geometry shaders (of the form that was adopted into GLSL 1.50 * and GL 3.2) are available in this context */ const bool has_core_gs = _mesa_is_desktop_gl(ctx) && ctx->Version >= 32; /* Are uniform buffer objects available in this context? */ const bool has_ubo = (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_uniform_buffer_object) || ctx->API == API_OPENGL_CORE || _mesa_is_gles3(ctx); if (!shProg) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)"); return; } switch (pname) { case GL_DELETE_STATUS: *params = shProg->DeletePending; return; case GL_LINK_STATUS: *params = shProg->LinkStatus; return; case GL_VALIDATE_STATUS: *params = shProg->Validated; return; case GL_INFO_LOG_LENGTH: *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0; return; case GL_ATTACHED_SHADERS: *params = shProg->NumShaders; return; case GL_ACTIVE_ATTRIBUTES: *params = _mesa_count_active_attribs(shProg); return; case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: *params = _mesa_longest_attribute_name_length(shProg); return; case GL_ACTIVE_UNIFORMS: *params = shProg->NumUserUniformStorage; return; case GL_ACTIVE_UNIFORM_MAX_LENGTH: { unsigned i; GLint max_len = 0; for (i = 0; i < shProg->NumUserUniformStorage; i++) { /* Add one for the terminating NUL character for a non-array, and * 4 for the "[0]" and the NUL for an array. */ const GLint len = strlen(shProg->UniformStorage[i].name) + 1 + ((shProg->UniformStorage[i].array_elements != 0) ? 3 : 0); if (len > max_len) max_len = len; } *params = max_len; return; } case GL_TRANSFORM_FEEDBACK_VARYINGS: if (!has_xfb) break; *params = shProg->TransformFeedback.NumVarying; return; case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: { unsigned i; GLint max_len = 0; if (!has_xfb) break; for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) { /* Add one for the terminating NUL character. */ const GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]) + 1; if (len > max_len) max_len = len; } *params = max_len; return; } case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: if (!has_xfb) break; *params = shProg->TransformFeedback.BufferMode; return; case GL_GEOMETRY_VERTICES_OUT: if (!has_core_gs) break; if (check_gs_query(ctx, shProg)) *params = shProg->Geom.VerticesOut; return; case GL_GEOMETRY_INPUT_TYPE: if (!has_core_gs) break; if (check_gs_query(ctx, shProg)) *params = shProg->Geom.InputType; return; case GL_GEOMETRY_OUTPUT_TYPE: if (!has_core_gs) break; if (check_gs_query(ctx, shProg)) *params = shProg->Geom.OutputType; return; case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: { unsigned i; GLint max_len = 0; if (!has_ubo) break; for (i = 0; i < shProg->NumUniformBlocks; i++) { /* Add one for the terminating NUL character. */ const GLint len = strlen(shProg->UniformBlocks[i].Name) + 1; if (len > max_len) max_len = len; } *params = max_len; return; } case GL_ACTIVE_UNIFORM_BLOCKS: if (!has_ubo) break; *params = shProg->NumUniformBlocks; return; case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: /* This enum isn't part of the OES extension for OpenGL ES 2.0. It is * only available with desktop OpenGL 3.0+ with the * GL_ARB_get_program_binary extension or OpenGL ES 3.0. * * On desktop, we ignore the 3.0+ requirement because it is silly. */ if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) break; *params = shProg->BinaryRetreivableHint; return; case GL_PROGRAM_BINARY_LENGTH: *params = 0; return; case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS: if (!ctx->Extensions.ARB_shader_atomic_counters) break; *params = shProg->NumAtomicBuffers; return; default: break; } _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname=%s)", _mesa_lookup_enum_by_nr(pname)); }