/** * 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 && 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)); }