Exemplo n.º 1
0
void GLAPIENTRY
_mesa_GetUniformIndices(GLuint program,
			GLsizei uniformCount,
			const GLchar * const *uniformNames,
			GLuint *uniformIndices)
{
   GET_CURRENT_CONTEXT(ctx);
   GLsizei i;
   struct gl_shader_program *shProg;

   if (!ctx->Extensions.ARB_uniform_buffer_object) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformIndices");
      return;
   }

   shProg = _mesa_lookup_shader_program_err(ctx, program,
					    "glGetUniformIndices");
   if (!shProg)
      return;

   if (uniformCount < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE,
		  "glGetUniformIndices(uniformCount < 0)");
      return;
   }

   for (i = 0; i < uniformCount; i++) {
      unsigned offset;
      uniformIndices[i] = _mesa_get_uniform_location(ctx, shProg,
						     uniformNames[i], &offset);
   }
}
Exemplo n.º 2
0
GLuint GLAPIENTRY
_mesa_GetUniformBlockIndex(GLuint program,
			   const GLchar *uniformBlockName)
{
   GET_CURRENT_CONTEXT(ctx);
   GLuint i;
   struct gl_shader_program *shProg;

   if (!ctx->Extensions.ARB_uniform_buffer_object) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformBlockIndex");
      return GL_INVALID_INDEX;
   }

   shProg = _mesa_lookup_shader_program_err(ctx, program,
					    "glGetUniformBlockIndex");
   if (!shProg)
      return GL_INVALID_INDEX;

   for (i = 0; i < shProg->NumUniformBlocks; i++) {
      if (!strcmp(shProg->UniformBlocks[i].Name, uniformBlockName))
	 return i;
   }

   return GL_INVALID_INDEX;
}
Exemplo n.º 3
0
/**
 * For GL_EXT_separate_shader_objects
 */
void GLAPIENTRY
_mesa_UseShaderProgramEXT(GLenum type, GLuint program)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader_program *shProg = NULL;

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (!validate_shader_target(ctx, type)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glUseShaderProgramEXT(type)");
      return;
   }

   if (ctx->TransformFeedback.CurrentObject->Active &&
       !ctx->TransformFeedback.CurrentObject->Paused) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glUseShaderProgramEXT(transform feedback is active)");
      return;
   }

   if (program) {
      shProg = _mesa_lookup_shader_program_err(ctx, program,
					       "glUseShaderProgramEXT");
      if (shProg == NULL)
	 return;

      if (!shProg->LinkStatus) {
	 _mesa_error(ctx, GL_INVALID_OPERATION,
		     "glUseShaderProgramEXT(program not linked)");
	 return;
      }
   }

   _mesa_use_shader_program(ctx, type, shProg);
}
Exemplo n.º 4
0
void GLAPIENTRY
_mesa_GetActiveUniformName(GLuint program, GLuint uniformIndex,
			   GLsizei bufSize, GLsizei *length,
			   GLchar *uniformName)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader_program *shProg;

   if (!ctx->Extensions.ARB_uniform_buffer_object) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv");
      return;
   }

   if (bufSize < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE,
		  "glGetActiveUniformName(bufSize %d < 0)",
		  bufSize);
      return;
   }

   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniformName");

   if (!shProg)
      return;

   if (uniformIndex >= shProg->NumUserUniformStorage) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
      return;
   }

   if (uniformName) {
      _mesa_get_uniform_name(& shProg->UniformStorage[uniformIndex],
                             bufSize, length, uniformName);
   }
}
Exemplo n.º 5
0
void GLAPIENTRY
_mesa_ProgramParameteriARB(GLuint program, GLenum pname, GLint value)
{
   struct gl_shader_program *shProg;
   GET_CURRENT_CONTEXT(ctx);

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   shProg = _mesa_lookup_shader_program_err(ctx, program,
                                            "glProgramParameteri");
   if (!shProg)
      return;

   switch (pname) {
   case GL_GEOMETRY_VERTICES_OUT_ARB:
      if (value < 1 ||
          (unsigned) value > ctx->Const.MaxGeometryOutputVertices) {
         _mesa_error(ctx, GL_INVALID_VALUE,
                     "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d",
                     value);
         return;
      }
      shProg->Geom.VerticesOut = value;
      break;
   case GL_GEOMETRY_INPUT_TYPE_ARB:
      switch (value) {
      case GL_POINTS:
      case GL_LINES:
      case GL_LINES_ADJACENCY_ARB:
      case GL_TRIANGLES:
      case GL_TRIANGLES_ADJACENCY_ARB:
         shProg->Geom.InputType = value;
         break;
      default:
         _mesa_error(ctx, GL_INVALID_VALUE,
                     "glProgramParameteri(geometry input type = %s",
                     _mesa_lookup_enum_by_nr(value));
         return;
      }
      break;
   case GL_GEOMETRY_OUTPUT_TYPE_ARB:
      switch (value) {
      case GL_POINTS:
      case GL_LINE_STRIP:
      case GL_TRIANGLE_STRIP:
         shProg->Geom.OutputType = value;
         break;
      default:
         _mesa_error(ctx, GL_INVALID_VALUE,
                     "glProgramParameteri(geometry output type = %s",
                     _mesa_lookup_enum_by_nr(value));
         return;
      }
      break;
   default:
      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteriARB(pname=%s)",
                  _mesa_lookup_enum_by_nr(pname));
      break;
   }
}
Exemplo n.º 6
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;
   }
}
Exemplo n.º 7
0
/**
 * Use the named shader program for subsequent glUniform calls (if pipeline
 * bound)
 */
void GLAPIENTRY
_mesa_ActiveShaderProgram(GLuint pipeline, GLuint program)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader_program *shProg = NULL;
   struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline);

   if (program != 0) {
      shProg = _mesa_lookup_shader_program_err(ctx, program,
                                               "glActiveShaderProgram(program)");
      if (shProg == NULL)
         return;
   }

   if (!pipe) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glActiveShaderProgram(pipeline)");
      return;
   }

   /* Object is created by any Pipeline call but glGenProgramPipelines,
    * glIsProgramPipeline and GetProgramPipelineInfoLog
    */
   pipe->EverBound = GL_TRUE;

   if ((shProg != NULL) && !shProg->LinkStatus) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
            "glActiveShaderProgram(program %u not linked)", shProg->Name);
      return;
   }

   _mesa_reference_shader_program(ctx, &pipe->ActiveProgram, shProg);
}
Exemplo n.º 8
0
GLint GLAPIENTRY
_mesa_GetFragDataIndex(GLuint program, const GLchar *name)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader_program *const shProg =
      _mesa_lookup_shader_program_err(ctx, program, "glGetFragDataIndex");

   if (!shProg) {
      return -1;
   }

   if (!shProg->LinkStatus) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glGetFragDataIndex(program not linked)");
      return -1;
   }

   if (!name)
      return -1;

   if (strncmp(name, "gl_", 3) == 0) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glGetFragDataIndex(illegal name)");
      return -1;
   }

   /* Not having a fragment shader is not an error.
    */
   if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)
      return -1;

   return _mesa_program_resource_location_index(shProg, GL_PROGRAM_OUTPUT,
                                                name);
}
Exemplo n.º 9
0
void GLAPIENTRY
_mesa_GetProgramResourceiv(GLuint program, GLenum programInterface,
                           GLuint index, GLsizei propCount,
                           const GLenum *props, GLsizei bufSize,
                           GLsizei *length, GLint *params)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader_program *shProg =
      _mesa_lookup_shader_program_err(ctx, program, "glGetProgramResourceiv");

   if (!shProg || !params)
      return;

   /* The error INVALID_VALUE is generated if <propCount> is zero.
    * Note that we check < 0 here because it makes sense to bail early.
    */
   if (propCount <= 0) {
      _mesa_error(ctx, GL_INVALID_VALUE,
                  "glGetProgramResourceiv(propCount <= 0)");
      return;
   }

   /* No need to write any properties, user requested none. */
   if (bufSize == 0)
      return;

   _mesa_get_program_resourceiv(shProg, programInterface, index,
                                propCount, props, bufSize, length, params);
}
Exemplo n.º 10
0
void GLAPIENTRY
_mesa_GetProgramResourceName(GLuint program, GLenum programInterface,
                             GLuint index, GLsizei bufSize, GLsizei *length,
                             GLchar *name)
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API) {
      _mesa_debug(ctx, "glGetProgramResourceName(%u, %s, %u, %d, %p, %p)\n",
                  program, _mesa_enum_to_string(programInterface), index,
                  bufSize, length, name);
   }

   struct gl_shader_program *shProg =
      _mesa_lookup_shader_program_err(ctx, program,
                                      "glGetProgramResourceName");

   if (!shProg || !name)
      return;

   if (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
       !supported_interface_enum(ctx, programInterface)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceName(%s)",
                  _mesa_enum_to_string(programInterface));
      return;
   }

   _mesa_get_program_resource_name(shProg, programInterface, index, bufSize,
                                   length, name, "glGetProgramResourceName");
}
Exemplo n.º 11
0
void GLAPIENTRY
_mesa_GetProgramResourceName(GLuint program, GLenum programInterface,
                             GLuint index, GLsizei bufSize, GLsizei *length,
                             GLchar *name)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader_program *shProg =
      _mesa_lookup_shader_program_err(ctx, program,
                                      "glGetProgramResourceName");

   /* Set user friendly return values in case of errors. */
   if (name)
      *name = '\0';
   if (length)
      *length = 0;

   if (!shProg || !name)
      return;

   if (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
       !supported_interface_enum(programInterface)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceName(%s)",
                  _mesa_lookup_enum_by_nr(programInterface));
      return;
   }

   _mesa_get_program_resource_name(shProg, programInterface, index, bufSize,
                                   length, name, "glGetProgramResourceName");
}
Exemplo n.º 12
0
/**
 * For GL_EXT_separate_shader_objects
 */
void GLAPIENTRY
_mesa_UseShaderProgramEXT(GLenum type, GLuint program)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader_program *shProg = NULL;

   if (!validate_shader_target(ctx, type)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glUseShaderProgramEXT(type)");
      return;
   }

   if (_mesa_is_xfb_active_and_unpaused(ctx)) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glUseShaderProgramEXT(transform feedback is active)");
      return;
   }

   if (program) {
      shProg = _mesa_lookup_shader_program_err(ctx, program,
					       "glUseShaderProgramEXT");
      if (shProg == NULL)
	 return;

      if (!shProg->LinkStatus) {
	 _mesa_error(ctx, GL_INVALID_OPERATION,
		     "glUseShaderProgramEXT(program not linked)");
	 return;
      }
   }

   _mesa_use_shader_program(ctx, type, shProg);
}
Exemplo n.º 13
0
void GLAPIENTRY
_mesa_GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length,
                       GLenum *binaryFormat, GLvoid *binary)
{
   struct gl_shader_program *shProg;
   GET_CURRENT_CONTEXT(ctx);

   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramBinary");
   if (!shProg)
      return;

   if (!shProg->LinkStatus) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glGetProgramBinary(program %u not linked)",
                  shProg->Name);
      return;
   }

   if (bufSize < 0){
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramBinary(bufSize < 0)");
      return;
   }

   /* The ARB_get_program_binary spec says:
    *
    *     "If <length> is NULL, then no length is returned."
    */
   if (length != NULL)
      *length = 0;

   (void) binaryFormat;
   (void) binary;
}
Exemplo n.º 14
0
void GLAPIENTRY
_mesa_UseProgram(GLhandleARB program)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader_program *shProg;

   if (_mesa_is_xfb_active_and_unpaused(ctx)) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glUseProgram(transform feedback active)");
      return;
   }

   if (program) {
      shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
      if (!shProg) {
         return;
      }
      if (!shProg->LinkStatus) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glUseProgram(program %u not linked)", program);
         return;
      }

      /* debug code */
      if (ctx->Shader.Flags & GLSL_USE_PROG) {
         print_shader_info(shProg);
      }
   }
   else {
      shProg = NULL;
   }

   _mesa_use_program(ctx, shProg);
}
Exemplo n.º 15
0
/**
 * Attach shader to a shader program.
 */
static void
attach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
{
   struct gl_shader_program *shProg;
   struct gl_shader *sh;
   GLuint i, n;

   const bool same_type_disallowed = _mesa_is_gles(ctx);

   shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
   if (!shProg)
      return;

   sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
   if (!sh) {
      return;
   }

   n = shProg->NumShaders;
   for (i = 0; i < n; i++) {
      if (shProg->Shaders[i] == sh) {
         /* The shader is already attched to this program.  The
          * GL_ARB_shader_objects spec says:
          *
          *     "The error INVALID_OPERATION is generated by AttachObjectARB
          *     if <obj> is already attached to <containerObj>."
          */
         _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
         return;
      } else if (same_type_disallowed &&
                 shProg->Shaders[i]->Type == sh->Type) {
        /* Shader with the same type is already attached to this program,
         * OpenGL ES 2.0 and 3.0 specs say:
         *
         *      "Multiple shader objects of the same type may not be attached
         *      to a single program object. [...] The error INVALID_OPERATION
         *      is generated if [...] another shader object of the same type
         *      as shader is already attached to program."
         */
         _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
         return;
      }
   }

   /* grow list */
   shProg->Shaders = (struct gl_shader **)
      _mesa_realloc(shProg->Shaders,
                    n * sizeof(struct gl_shader *),
                    (n + 1) * sizeof(struct gl_shader *));
   if (!shProg->Shaders) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
      return;
   }

   /* append */
   shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
   _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
   shProg->NumShaders++;
}
Exemplo n.º 16
0
void GLAPIENTRY
_mesa_ProgramUniform1ui(GLuint program, GLint location, GLuint v0)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader_program *shProg =
      _mesa_lookup_shader_program_err(ctx, program,
            "glProgramUniform1ui");
   _mesa_uniform(ctx, shProg, location, 1, &v0, GL_UNSIGNED_INT);
}
Exemplo n.º 17
0
void GLAPIENTRY
_mesa_ProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count,
                                GLboolean transpose, const GLfloat * value)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader_program *shProg =
      _mesa_lookup_shader_program_err(ctx, program,
            "glProgramUniformMatrix4x3fv");
   _mesa_uniform_matrix(ctx, shProg, 4, 3, location, count, transpose, value);
}
Exemplo n.º 18
0
void GLAPIENTRY
_mesa_ProgramUniform4uiv(GLuint program, GLint location, GLsizei count,
                         const GLuint *value)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader_program *shProg =
      _mesa_lookup_shader_program_err(ctx, program,
            "glProgramUniform4uiv");
   _mesa_uniform(ctx, shProg, location, count, value, GL_UNSIGNED_INT_VEC4);
}
GLint GLAPIENTRY
_mesa_GetFragDataLocation(GLuint program, const GLchar *name)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader_program *const shProg =
      _mesa_lookup_shader_program_err(ctx, program, "glGetFragDataLocation");

   if (!shProg) {
      return -1;
   }

   if (!shProg->LinkStatus) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glGetFragDataLocation(program not linked)");
      return -1;
   }

   if (!name)
      return -1;

   if (strncmp(name, "gl_", 3) == 0) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glGetFragDataLocation(illegal name)");
      return -1;
   }

   /* Not having a fragment shader is not an error.
    */
   if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)
      return -1;

   exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir;
   foreach_list(node, ir) {
      const ir_variable *const var = ((ir_instruction *) node)->as_variable();

      /* The extra check against FRAG_RESULT_DATA0 is because
       * glGetFragDataLocation cannot be used on "conventional" attributes.
       *
       * From page 95 of the OpenGL 3.0 spec:
       *
       *     "If name is not an active attribute, if name is a conventional
       *     attribute, or if an error occurs, -1 will be returned."
       */
      if (var == NULL
	  || var->mode != ir_var_out
	  || var->location == -1
	  || var->location < FRAG_RESULT_DATA0)
	 continue;

      if (strcmp(var->name, name) == 0)
	 return var->location - FRAG_RESULT_DATA0;
   }

   return -1;
}
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)");
}
Exemplo n.º 21
0
/**
 * For GL_EXT_separate_shader_objects
 */
void GLAPIENTRY
_mesa_ActiveProgramEXT(GLuint program)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader_program *shProg = (program != 0)
      ? _mesa_lookup_shader_program_err(ctx, program, "glActiveProgramEXT")
      : NULL;

   _mesa_active_program(ctx, shProg, "glActiveProgramEXT");
   return;
}
Exemplo n.º 22
0
void GLAPIENTRY
_mesa_ProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1)
{
   GET_CURRENT_CONTEXT(ctx);
   GLint v[2];
   struct gl_shader_program *shProg;
   v[0] = v0;
   v[1] = v1;
   shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform2i");
   _mesa_uniform(ctx, shProg, location, 1, v, GL_INT_VEC2);
}
Exemplo n.º 23
0
GLint GLAPIENTRY
_mesa_GetFragDataLocation(GLuint program, const GLchar *name)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader_program *const shProg =
      _mesa_lookup_shader_program_err(ctx, program, "glGetFragDataLocation");

   if (!shProg) {
      return -1;
   }

   if (!shProg->LinkStatus) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glGetFragDataLocation(program not linked)");
      return -1;
   }

   if (!name)
      return -1;

   if (strncmp(name, "gl_", 3) == 0) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glGetFragDataLocation(illegal name)");
      return -1;
   }

   /* Not having a fragment shader is not an error.
    */
   if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)
      return -1;

   unsigned array_index = 0;
   struct gl_program_resource *res =
      _mesa_program_resource_find_name(shProg, GL_PROGRAM_OUTPUT, name,
                                       &array_index);

   if (!res)
      return -1;

   GLint loc = program_resource_location(shProg, res, name, array_index);

   /* The extra check against against 0 is made because of builtin-attribute
    * locations that have offset applied. Function program_resource_location
    * can return built-in attribute locations < 0 and glGetFragDataLocation
    * cannot be used on "conventional" attributes.
    *
    * From page 95 of the OpenGL 3.0 spec:
    *
    *     "If name is not an active attribute, if name is a conventional
    *     attribute, or if an error occurs, -1 will be returned."
    */
   return (loc >= 0) ? loc : -1;
}
Exemplo n.º 24
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");
}
Exemplo n.º 25
0
void GLAPIENTRY
_mesa_ProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1,
                       GLfloat v2)
{
   GET_CURRENT_CONTEXT(ctx);
   GLfloat v[3];
   struct gl_shader_program *shProg;
   v[0] = v0;
   v[1] = v1;
   v[2] = v2;
   shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform3f");
   _mesa_uniform(ctx, shProg, location, 1, v, GL_FLOAT_VEC3);
}
Exemplo n.º 26
0
void GLAPIENTRY
_mesa_UniformBlockBinding(GLuint program,
			  GLuint uniformBlockIndex,
			  GLuint uniformBlockBinding)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader_program *shProg;

   if (!ctx->Extensions.ARB_uniform_buffer_object) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformBlockBinding");
      return;
   }

   shProg = _mesa_lookup_shader_program_err(ctx, program,
					    "glUniformBlockBinding");
   if (!shProg)
      return;

   if (uniformBlockIndex >= shProg->NumUniformBlocks) {
      _mesa_error(ctx, GL_INVALID_VALUE,
		  "glUniformBlockBinding(block index %u >= %u)",
		  uniformBlockIndex, shProg->NumUniformBlocks);
      return;
   }

   if (uniformBlockBinding >= ctx->Const.MaxUniformBufferBindings) {
      _mesa_error(ctx, GL_INVALID_VALUE,
		  "glUniformBlockBinding(block binding %u >= %u)",
		  uniformBlockBinding, ctx->Const.MaxUniformBufferBindings);
      return;
   }

   if (shProg->UniformBlocks[uniformBlockIndex].Binding !=
       uniformBlockBinding) {
      int i;

      FLUSH_VERTICES(ctx, 0);
      ctx->NewDriverState |= ctx->DriverFlags.NewUniformBuffer;

      shProg->UniformBlocks[uniformBlockIndex].Binding = uniformBlockBinding;

      for (i = 0; i < MESA_SHADER_STAGES; i++) {
	 int stage_index = shProg->UniformBlockStageIndex[i][uniformBlockIndex];

	 if (stage_index != -1) {
	    struct gl_shader *sh = shProg->_LinkedShaders[i];
	    sh->UniformBlocks[stage_index].Binding = uniformBlockBinding;
	 }
      }
   }
}
Exemplo n.º 27
0
extern "C" void GLAPIENTRY
_mesa_GetActiveUniformsiv(GLuint program,
			  GLsizei uniformCount,
			  const GLuint *uniformIndices,
			  GLenum pname,
			  GLint *params)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader_program *shProg;
   struct gl_program_resource *res;
   GLenum res_prop;

   if (uniformCount < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE,
		  "glGetActiveUniformsiv(uniformCount < 0)");
      return;
   }

   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
   if (!shProg)
      return;

   res_prop = resource_prop_from_uniform_prop(pname);

   /* We need to first verify that each entry exists as active uniform. If
    * not, generate error and do not cause any other side effects.
    *
    * In the case of and error condition, Page 16 (section 2.3.1 Errors)
    * of the OpenGL 4.5 spec says:
    *
    *     "If the generating command modifies values through a pointer argu-
    *     ment, no change is made to these values."
    */
   for (int i = 0; i < uniformCount; i++) {
      if (!_mesa_program_resource_find_index(shProg, GL_UNIFORM,
                                              uniformIndices[i])) {
         _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)");
         return;
      }
   }

   for (int i = 0; i < uniformCount; i++) {
      res = _mesa_program_resource_find_index(shProg, GL_UNIFORM,
                                              uniformIndices[i]);
      if (!_mesa_program_resource_prop(shProg, res, uniformIndices[i],
                                       res_prop, &params[i],
                                       "glGetActiveUniformsiv"))
         break;
   }
}
Exemplo n.º 28
0
GLint GLAPIENTRY
_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
{
   struct gl_shader_program *shProg;

   GET_CURRENT_CONTEXT(ctx);

   shProg = _mesa_lookup_shader_program_err(ctx, programObj,
					    "glGetUniformLocation");
   if (!shProg)
      return -1;

   return _mesa_get_uniform_location(ctx, shProg, name);
}
Exemplo n.º 29
0
void GLAPIENTRY
_mesa_ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1,
                        GLuint v2, GLuint v3)
{
   GET_CURRENT_CONTEXT(ctx);
   GLuint v[4];
   struct gl_shader_program *shProg;
   v[0] = v0;
   v[1] = v1;
   v[2] = v2;
   v[3] = v3;
   shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform4ui");
   _mesa_uniform(ctx, shProg, location, 1, v, GL_UNSIGNED_INT_VEC4);
}
GLint GLAPIENTRY
_mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader_program *const shProg =
      _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation");

   if (!shProg) {
      return -1;
   }

   if (!shProg->LinkStatus) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glGetAttribLocation(program not linked)");
      return -1;
   }

   if (!name)
      return -1;

   /* Not having a vertex shader is not an error.
    */
   if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL)
      return -1;

   exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir;
   foreach_list(node, ir) {
      const ir_variable *const var = ((ir_instruction *) node)->as_variable();

      /* The extra check against VERT_ATTRIB_GENERIC0 is because
       * glGetAttribLocation cannot be used on "conventional" attributes.
       *
       * From page 95 of the OpenGL 3.0 spec:
       *
       *     "If name is not an active attribute, if name is a conventional
       *     attribute, or if an error occurs, -1 will be returned."
       */
      if (var == NULL
	  || var->mode != ir_var_in
	  || var->location == -1
	  || var->location < VERT_ATTRIB_GENERIC0)
	 continue;

      if (strcmp(var->name, name) == 0)
	 return var->location - VERT_ATTRIB_GENERIC0;
   }

   return -1;
}