void GLAPIENTRY _mesa_GetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog) { GET_CURRENT_CONTEXT(ctx); struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline); if (!pipe) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramPipelineInfoLog(pipeline)"); return; } if (bufSize < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramPipelineInfoLog(bufSize)"); return; } if (pipe->InfoLog) _mesa_copy_string(infoLog, bufSize, length, pipe->InfoLog); else *length = 0; }
/** * Get info about the vertex shader's outputs which are to be written * to the feedback buffer(s). */ void GLAPIENTRY _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) { const struct gl_shader_program *shProg; const struct gl_transform_feedback_info *linked_xfb_info; GET_CURRENT_CONTEXT(ctx); shProg = _mesa_lookup_shader_program(ctx, program); if (!shProg) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetTransformFeedbackVarying(program=%u)", program); return; } linked_xfb_info = &shProg->LinkedTransformFeedback; if (index >= (GLuint) linked_xfb_info->NumVarying) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetTransformFeedbackVarying(index=%u)", index); return; } /* return the varying's name and length */ _mesa_copy_string(name, bufSize, length, linked_xfb_info->Varyings[index].Name); /* return the datatype and value's size (in datatype units) */ if (type) *type = linked_xfb_info->Varyings[index].Type; if (size) *size = linked_xfb_info->Varyings[index].Size; }
extern "C" void GLAPIENTRY _mesa_GetActiveUniformARB(GLhandleARB program, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *nameOut) { GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); if (!shProg) return; if (index >= shProg->NumUserUniformStorage) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); return; } const struct gl_uniform_storage *const uni = &shProg->UniformStorage[index]; if (nameOut) { _mesa_copy_string(nameOut, maxLength, length, uni->name); } if (size) { /* array_elements is zero for non-arrays, but the API requires that 1 be * returned. */ *size = MAX2(1, uni->array_elements); } if (type) { *type = uni->type->gl_type; } }
void GLAPIENTRY _mesa_GetActiveAttribARB(GLhandleARB program, GLuint desired_index, GLsizei maxLength, GLsizei * length, GLint * size, GLenum * type, GLcharARB * name) { GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *shProg; shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib"); if (!shProg) return; if (!shProg->LinkStatus) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(program not linked)"); return; } if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(no vertex shader)"); return; } exec_list *const ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir; unsigned current_index = 0; foreach_list(node, ir) { const ir_variable *const var = ((ir_instruction *) node)->as_variable(); if (var == NULL || var->mode != ir_var_in || var->location == -1) continue; if (current_index == desired_index) { _mesa_copy_string(name, maxLength, length, var->name); if (size) *size = (var->type->is_array()) ? var->type->length : 1; if (type) *type = var->type->gl_type; return; } current_index++; } /* If the loop did not return early, the caller must have asked for * an index that did not exit. Set an error. */ _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)"); }
/** * Return shader source code. */ static void get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength, GLsizei *length, GLchar *sourceOut) { struct gl_shader *sh; sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource"); if (!sh) { return; } _mesa_copy_string(sourceOut, maxLength, length, sh->Source); }
static void get_shader_info_log(struct gl_context *ctx, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) { struct gl_shader *sh = _mesa_lookup_shader(ctx, shader); if (!sh) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)"); return; } _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog); }
static void get_program_info_log(struct gl_context *ctx, GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) { struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); if (!shProg) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)"); return; } _mesa_copy_string(infoLog, bufSize, length, shProg->InfoLog); }
void GLAPIENTRY _mesa_GetActiveAttrib(GLuint program, GLuint desired_index, GLsizei maxLength, GLsizei * length, GLint * size, GLenum * type, GLchar * name) { GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *shProg; if (maxLength < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(maxLength < 0)"); return; } shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib"); if (!shProg) return; if (!shProg->LinkStatus) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(program not linked)"); return; } if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(no vertex shader)"); return; } struct gl_program_resource *res = _mesa_program_resource_find_index(shProg, GL_PROGRAM_INPUT, desired_index); /* User asked for index that does not exist. */ if (!res) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)"); return; } const gl_shader_variable *const var = RESOURCE_VAR(res); const char *var_name = var->name; _mesa_copy_string(name, maxLength, length, var_name); if (size) _mesa_program_resource_prop(shProg, res, desired_index, GL_ARRAY_SIZE, size, "glGetActiveAttrib"); if (type) _mesa_program_resource_prop(shProg, res, desired_index, GL_TYPE, (GLint *) type, "glGetActiveAttrib"); }
/* Get full name of a program resource. */ bool _mesa_get_program_resource_name(struct gl_shader_program *shProg, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name, const char *caller) { GET_CURRENT_CONTEXT(ctx); /* Find resource with given interface and index. */ struct gl_program_resource *res = _mesa_program_resource_find_index(shProg, programInterface, index); /* The error INVALID_VALUE is generated if <index> is greater than * or equal to the number of entries in the active resource list for * <programInterface>. */ if (!res) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(index %u)", caller, index); return false; } if (bufSize < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufSize %d)", caller, bufSize); return false; } GLsizei localLength; if (length == NULL) length = &localLength; _mesa_copy_string(name, bufSize, length, _mesa_program_resource_name(res)); if (_mesa_program_resource_array_size(res) && add_index_to_name(res)) { int i; /* The comparison is strange because *length does *NOT* include the * terminating NUL, but maxLength does. */ for (i = 0; i < 3 && (*length + i + 1) < bufSize; i++) name[*length + i] = "[0]"[i]; name[*length + i] = '\0'; *length += i; } return true; }
void GLAPIENTRY _mesa_GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) { GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *shProg; struct gl_uniform_block *block; if (!ctx->Extensions.ARB_uniform_buffer_object) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv"); return; } if (bufSize < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformBlockName(bufSize %d < 0)", bufSize); return; } shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniformBlockiv"); if (!shProg) return; if (uniformBlockIndex >= shProg->NumUniformBlocks) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformBlockiv(block index %u >= %u)", uniformBlockIndex, shProg->NumUniformBlocks); return; } block = &shProg->UniformBlocks[uniformBlockIndex]; if (uniformBlockName) { _mesa_copy_string(uniformBlockName, bufSize, length, block->Name); } }
/** * Get info about the transform feedback outputs which are to be written * to the feedback buffer(s). */ void GLAPIENTRY _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) { const struct gl_shader_program *shProg; struct gl_program_resource *res; GET_CURRENT_CONTEXT(ctx); shProg = _mesa_lookup_shader_program(ctx, program); if (!shProg) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetTransformFeedbackVarying(program=%u)", program); return; } res = _mesa_program_resource_find_index((struct gl_shader_program *) shProg, GL_TRANSFORM_FEEDBACK_VARYING, index); if (!res) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetTransformFeedbackVarying(index=%u)", index); return; } /* return the varying's name and length */ _mesa_copy_string(name, bufSize, length, _mesa_program_resource_name(res)); /* return the datatype and value's size (in datatype units) */ if (type) _mesa_program_resource_prop((struct gl_shader_program *) shProg, res, index, GL_TYPE, (GLint*) type, "glGetTransformFeedbackVarying"); if (size) _mesa_program_resource_prop((struct gl_shader_program *) shProg, res, index, GL_ARRAY_SIZE, (GLint*) size, "glGetTransformFeedbackVarying"); }
void _mesa_get_uniform_name(const struct gl_uniform_storage *uni, GLsizei maxLength, GLsizei *length, GLchar *nameOut) { GLsizei localLength; if (length == NULL) length = &localLength; _mesa_copy_string(nameOut, maxLength, length, uni->name); /* Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0 * spec says: * * "If the active uniform is an array, the uniform name returned in * name will always be the name of the uniform array appended with * "[0]"." * * The same text also appears in the OpenGL 4.2 spec. It does not, * however, appear in any previous spec. Previous specifications are * ambiguous in this regard. However, either name can later be passed * to glGetUniformLocation (and related APIs), so there shouldn't be any * harm in always appending "[0]" to uniform array names. */ if (uni->array_elements != 0) { int i; /* The comparison is strange because *length does *NOT* include the * terminating NUL, but maxLength does. */ for (i = 0; i < 3 && (*length + i + 1) < maxLength; i++) nameOut[*length + i] = "[0]"[i]; nameOut[*length + i] = '\0'; *length += i; } }
/** * Called by glGetActiveUniform(). */ static void _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLchar *nameOut) { const struct gl_shader_program *shProg; const struct gl_program *prog = NULL; const struct gl_program_parameter *param; GLint progPos; shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); if (!shProg) return; if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); return; } progPos = shProg->Uniforms->Uniforms[index].VertPos; if (progPos >= 0) { prog = &shProg->VertexProgram->Base; } else { progPos = shProg->Uniforms->Uniforms[index].FragPos; if (progPos >= 0) { prog = &shProg->FragmentProgram->Base; } else { progPos = shProg->Uniforms->Uniforms[index].GeomPos; if (progPos >= 0) { prog = &shProg->GeometryProgram->Base; } } } if (!prog || progPos < 0) return; /* should never happen */ ASSERT(progPos < prog->Parameters->NumParameters); param = &prog->Parameters->Parameters[progPos]; if (nameOut) { _mesa_copy_string(nameOut, maxLength, length, param->Name); } if (size) { GLint typeSize = _mesa_sizeof_glsl_type(param->DataType); if ((GLint) param->Size > typeSize) { /* This is an array. * Array elements are placed on vector[4] boundaries so they're * a multiple of four floats. We round typeSize up to next multiple * of four to get the right size below. */ typeSize = (typeSize + 3) & ~3; } /* Note that the returned size is in units of the <type>, not bytes */ *size = param->Size / typeSize; } if (type) { *type = param->DataType; } }
void GLAPIENTRY _mesa_GetActiveAttrib(GLhandleARB program, GLuint desired_index, GLsizei maxLength, GLsizei * length, GLint * size, GLenum * type, GLcharARB * name) { GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *shProg; if (maxLength < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(maxLength < 0)"); return; } shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib"); if (!shProg) return; if (!shProg->LinkStatus) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(program not linked)"); return; } if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(no vertex shader)"); return; } struct gl_program_resource *res = _mesa_program_resource_find_index(shProg, GL_PROGRAM_INPUT, desired_index); /* User asked for index that does not exist. */ if (!res) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)"); return; } const ir_variable *const var = RESOURCE_VAR(res); if (!is_active_attrib(var)) return; const char *var_name = var->name; /* Since gl_VertexID may be lowered to gl_VertexIDMESA, we need to * consider gl_VertexIDMESA as gl_VertexID for purposes of checking * active attributes. */ if (var->data.mode == ir_var_system_value && var->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) { var_name = "gl_VertexID"; } _mesa_copy_string(name, maxLength, length, var_name); if (size) _mesa_program_resource_prop(shProg, res, desired_index, GL_ARRAY_SIZE, size, "glGetActiveAttrib"); if (type) _mesa_program_resource_prop(shProg, res, desired_index, GL_TYPE, (GLint *) type, "glGetActiveAttrib"); }
/* Get full name of a program resource. */ bool _mesa_get_program_resource_name(struct gl_shader_program *shProg, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name, const char *caller) { GET_CURRENT_CONTEXT(ctx); /* Find resource with given interface and index. */ struct gl_program_resource *res = _mesa_program_resource_find_index(shProg, programInterface, index); /* The error INVALID_VALUE is generated if <index> is greater than * or equal to the number of entries in the active resource list for * <programInterface>. */ if (!res) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(index %u)", caller, index); return false; } if (bufSize < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufSize %d)", caller, bufSize); return false; } GLsizei localLength; if (length == NULL) length = &localLength; _mesa_copy_string(name, bufSize, length, _mesa_program_resource_name(res)); /* Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0 * spec says: * * "If the active uniform is an array, the uniform name returned in * name will always be the name of the uniform array appended with * "[0]"." * * The same text also appears in the OpenGL 4.2 spec. It does not, * however, appear in any previous spec. Previous specifications are * ambiguous in this regard. However, either name can later be passed * to glGetUniformLocation (and related APIs), so there shouldn't be any * harm in always appending "[0]" to uniform array names. * * Geometry shader stage has different naming convention where the 'normal' * condition is an array, therefore for variables referenced in geometry * stage we do not add '[0]'. * * Note, that TCS outputs and TES inputs should not have index appended * either. */ bool add_index = !(((programInterface == GL_PROGRAM_INPUT) && res->StageReferences & (1 << MESA_SHADER_GEOMETRY))); if (add_index && _mesa_program_resource_array_size(res)) { int i; /* The comparison is strange because *length does *NOT* include the * terminating NUL, but maxLength does. */ for (i = 0; i < 3 && (*length + i + 1) < bufSize; i++) name[*length + i] = "[0]"[i]; name[*length + i] = '\0'; *length += i; } return true; }