Example #1
0
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;
}
Example #2
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;
}
Example #3
0
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)");
}
Example #5
0
/**
 * 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);
}
Example #6
0
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);
}
Example #7
0
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);
}
Example #8
0
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");
}
Example #9
0
/* 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;
}
Example #10
0
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);
   }
}
Example #11
0
/**
 * 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");
}
Example #12
0
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;
   }
}
Example #13
0
/**
 * 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;
   }
}
Example #14
0
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");
}
Example #15
0
/* 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;
}