Exemplo n.º 1
0
/**
 * Load/parse/compile a program.
 * \note Called from the GL API dispatcher.
 */
void GLAPIENTRY
_mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len,
                    const GLubyte *program)
{
   struct gl_program *prog;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (id == 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(id)");
      return;
   }

   if (len < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(len)");
      return;
   }

   FLUSH_VERTICES(ctx, _NEW_PROGRAM);

   prog = _mesa_lookup_program(ctx, id);

   if (prog && prog->Target != 0 && prog->Target != target) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(target)");
      return;
   }

   if ((target == GL_VERTEX_PROGRAM_NV ||
        target == GL_VERTEX_STATE_PROGRAM_NV)
       && ctx->Extensions.NV_vertex_program) {
      struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog;
      if (!vprog || prog == &_mesa_DummyProgram) {
         vprog = (struct gl_vertex_program *)
            ctx->Driver.NewProgram(ctx, target, id);
         if (!vprog) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
            return;
         }
         _mesa_HashInsert(ctx->Shared->Programs, id, vprog);
      }
      _mesa_parse_nv_vertex_program(ctx, target, program, len, vprog);
   }
   else if (target == GL_FRAGMENT_PROGRAM_NV
            && ctx->Extensions.NV_fragment_program) {
      struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog;
      if (!fprog || prog == &_mesa_DummyProgram) {
         fprog = (struct gl_fragment_program *)
            ctx->Driver.NewProgram(ctx, target, id);
         if (!fprog) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
            return;
         }
         _mesa_HashInsert(ctx->Shared->Programs, id, fprog);
      }
      _mesa_parse_nv_fragment_program(ctx, target, program, len, fprog);
   }
   else {
      _mesa_error(ctx, GL_INVALID_ENUM, "glLoadProgramNV(target)");
   }
}
Exemplo n.º 2
0
/**
 * Create new transform feedback objects.   Transform feedback objects
 * encapsulate the state related to transform feedback to allow quickly
 * switching state (and drawing the results, below).
 * Part of GL_ARB_transform_feedback2.
 */
void GLAPIENTRY
_mesa_GenTransformFeedbacks(GLsizei n, GLuint *names)
{
   GLuint first;
   GET_CURRENT_CONTEXT(ctx);

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (n < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGenTransformFeedbacks(n < 0)");
      return;
   }

   if (!names)
      return;

   /* we don't need contiguous IDs, but this might be faster */
   first = _mesa_HashFindFreeKeyBlock(ctx->TransformFeedback.Objects, n);
   if (first) {
      GLsizei i;
      for (i = 0; i < n; i++) {
         struct gl_transform_feedback_object *obj
            = ctx->Driver.NewTransformFeedback(ctx, first + i);
         if (!obj) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTransformFeedbacks");
            return;
         }
         names[i] = first + i;
         _mesa_HashInsert(ctx->TransformFeedback.Objects, first + i, obj);
      }
   }
   else {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTransformFeedbacks");
   }
}
Exemplo n.º 3
0
static void
create_samplers(struct gl_context *ctx, GLsizei count, GLuint *samplers,
                const char *caller)
{
   GLuint first;
   GLint i;

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "%s(%d)\n", caller, count);

   if (count < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(n<0)", caller);
      return;
   }

   if (!samplers)
      return;

   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->SamplerObjects, count);

   /* Insert the ID and pointer to new sampler object into hash table */
   for (i = 0; i < count; i++) {
      struct gl_sampler_object *sampObj =
         ctx->Driver.NewSamplerObject(ctx, first + i);
      _mesa_HashInsert(ctx->Shared->SamplerObjects, first + i, sampObj);
      samplers[i] = first + i;
   }
}
Exemplo n.º 4
0
/**
 * Add the given pipeline object to the pipeline object pool.
 */
static void
save_pipeline_object(struct gl_context *ctx, struct gl_pipeline_object *obj)
{
   if (obj->Name > 0) {
      _mesa_HashInsert(ctx->Pipeline.Objects, obj->Name, obj);
   }
}
Exemplo n.º 5
0
void GLAPIENTRY
_mesa_GenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers)
{
   GET_CURRENT_CONTEXT(ctx);
   GLuint first;
   GLint i;

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (n < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGenRenderbuffersEXT(n)");
      return;
   }

   if (!renderbuffers)
      return;

   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->RenderBuffers, n);

   for (i = 0; i < n; i++) {
      GLuint name = first + i;
      renderbuffers[i] = name;
      /* insert dummy placeholder into hash table */
      _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
      _mesa_HashInsert(ctx->Shared->RenderBuffers, name, &DummyRenderbuffer);
      _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
   }
}
Exemplo n.º 6
0
/**
 * Generate a list of new program identifiers.
 * \note Not compiled into display lists.
 * \note Called by both glGenProgramsNV and glGenProgramsARB.
 */
void GLAPIENTRY
_mesa_GenPrograms(GLsizei n, GLuint *ids)
{
   GLuint first;
   GLuint i;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (n < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGenPrograms");
      return;
   }

   if (!ids)
      return;

   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->Programs, n);

   /* Insert pointer to dummy program as placeholder */
   for (i = 0; i < (GLuint) n; i++) {
      _mesa_HashInsert(ctx->Shared->Programs, first + i, &_mesa_DummyProgram);
   }

   /* Return the program names */
   for (i = 0; i < (GLuint) n; i++) {
      ids[i] = first + i;
   }
}
Exemplo n.º 7
0
void GLAPIENTRY
_mesa_GenQueriesARB(GLsizei n, GLuint *ids)
{
   GLuint first;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (n < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGenQueriesARB(n < 0)");
      return;
   }

   /* No query objects can be active at this time! */
   if (ctx->Query.CurrentOcclusionObject ||
       ctx->Query.CurrentTimerObject) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGenQueriesARB");
      return;
   }

   first = _mesa_HashFindFreeKeyBlock(ctx->Query.QueryObjects, n);
   if (first) {
      GLsizei i;
      for (i = 0; i < n; i++) {
         struct gl_query_object *q
            = ctx->Driver.NewQueryObject(ctx, first + i);
         if (!q) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenQueriesARB");
            return;
         }
         ids[i] = first + i;
         _mesa_HashInsert(ctx->Query.QueryObjects, first + i, q);
      }
   }
}
Exemplo n.º 8
0
void GLAPIENTRY
_mesa_GenSamplers(GLsizei count, GLuint *samplers)
{
   GET_CURRENT_CONTEXT(ctx);
   GLuint first;
   GLint i;

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glGenSamplers(%d)\n", count);

   if (count < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGenSamplers");
      return;
   }

   if (!samplers)
      return;

   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->SamplerObjects, count);

   /* Insert the ID and pointer to new sampler object into hash table */
   for (i = 0; i < count; i++) {
      struct gl_sampler_object *sampObj =
         ctx->Driver.NewSamplerObject(ctx, first + i);
      _mesa_HashInsert(ctx->Shared->SamplerObjects, first + i, sampObj);
      samplers[i] = first + i;
   }
}
Exemplo n.º 9
0
Arquivo: vpstate.c Projeto: aosm/X11
/**
 * Generate a list of new program identifiers.
 * \note Not compiled into display lists.
 * \note Called from the GL API dispatcher.
 */
void _mesa_GenProgramsNV(GLsizei n, GLuint *ids)
{
   GLuint first;
   GLuint i;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (n < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGenProgramsNV");
      return;
   }

   if (!ids)
      return;

   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->VertexPrograms, n);

   for (i = 0; i < (GLuint) n; i++) {
      struct vp_program *vprog = CALLOC_STRUCT(vp_program);
      if (!vprog) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenProgramsNV");
         return;
      }
      vprog->RefCount = 1;
      _mesa_HashInsert(ctx->Shared->VertexPrograms, first + i, vprog);
   }

   /* Return the program names */
   for (i = 0; i < (GLuint) n; i++) {
      ids[i] = first + i;
   }
}
Exemplo n.º 10
0
void GLAPIENTRY
_mesa_QueryCounter(GLuint id, GLenum target)
{
   struct gl_query_object *q;
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glQueryCounter(%u, %s)\n", id,
                  _mesa_lookup_enum_by_nr(target));

   /* error checking */
   if (target != GL_TIMESTAMP) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glQueryCounter(target)");
      return;
   }

   if (id == 0) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glQueryCounter(id==0)");
      return;
   }

   q = _mesa_lookup_query_object(ctx, id);
   if (!q) {
      /* XXX the Core profile should throw INVALID_OPERATION here */

      /* create new object */
      q = ctx->Driver.NewQueryObject(ctx, id);
      if (!q) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glQueryCounter");
         return;
      }
      _mesa_HashInsert(ctx->Query.QueryObjects, id, q);
   }
   else {
      if (q->Target && q->Target != GL_TIMESTAMP) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glQueryCounter(id has an invalid target)");
         return;
      }
   }

   if (q->Active) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glQueryCounter(id is active)");
      return;
   }

   q->Target = target;
   q->Result = 0;
   q->Ready = GL_FALSE;

   if (ctx->Driver.QueryCounter) {
      ctx->Driver.QueryCounter(ctx, q);
   } else {
      /* QueryCounter is implemented using EndQuery without BeginQuery
       * in drivers. This is actually Direct3D and Gallium convention.
       */
      ctx->Driver.EndQuery(ctx, q);
   }
}
Exemplo n.º 11
0
/**
 * Add the given array object to the array object pool.
 */
static void
save_array_object( struct gl_context *ctx, struct gl_array_object *obj )
{
   if (obj->Name > 0) {
      /* insert into hash table */
      _mesa_HashInsert(ctx->Array.Objects, obj->Name, obj);
   }
}
Exemplo n.º 12
0
/**
 * Add the given buffer object to the buffer object pool.
 */
void
_mesa_save_buffer_object( GLcontext *ctx, struct gl_buffer_object *obj )
{
   if (obj->Name > 0) {
      /* insert into hash table */
      _mesa_HashInsert(ctx->Shared->BufferObjects, obj->Name, obj);
   }
}
Exemplo n.º 13
0
void
_mesa_test_hash_functions(void)
{
   int a, b, c;
   struct _mesa_HashTable *t;

   t = _mesa_NewHashTable();
   _mesa_HashInsert(t, 501, &a);
   _mesa_HashInsert(t, 10, &c);
   _mesa_HashInsert(t, 0xfffffff8, &b);
   /*_mesa_HashPrint(t);*/

   assert(_mesa_HashLookup(t,501));
   assert(!_mesa_HashLookup(t,1313));
   assert(_mesa_HashFindFreeKeyBlock(t, 100));

   _mesa_DeleteHashTable(t);

   test_hash_walking();
}
Exemplo n.º 14
0
Arquivo: vpstate.c Projeto: aosm/X11
/**
 * Load a vertex program.
 * \note Called from the GL API dispatcher.
 */
void _mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len,
                         const GLubyte *program)
{
   struct vp_program *vprog;
   GLboolean newProgram = GL_FALSE;
   GLubyte *programCopy;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (id == 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(id)");
      return;
   }

   vprog = (struct vp_program *)
      _mesa_HashLookup(ctx->Shared->VertexPrograms, id);

   if (vprog && vprog->Target != 0 && vprog->Target != target) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(target)");
      return;
   }

   /* make a copy of the program string so that we can null-terminate it */
   /* if we change the parser to stop after <len> characters, instead of */
   /* looking for '\0' we can eliminate this. */
   programCopy = (GLubyte *) MALLOC(len + 1);
   if (!programCopy) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
      return;
   }
   MEMCPY(programCopy, program, len);
   programCopy[len] = 0;

   if (!vprog) {
      newProgram = GL_TRUE;
      vprog = CALLOC_STRUCT(vp_program);
      if (!vprog) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
         return;
      }
   }

   _mesa_parse_program(ctx, target, programCopy, vprog);
   if (ctx->VertexProgram.ErrorPos == -1) {
      /* loaded and parsed w/out errors */
      if (newProgram) {
         _mesa_HashInsert(ctx->Shared->VertexPrograms, id, vprog);
      }
      vprog->RefCount = 1;
      vprog->Resident = GL_TRUE;
   }

   FREE(programCopy);
}
Exemplo n.º 15
0
Arquivo: vpstate.c Projeto: aosm/X11
/**
 * Bind a program (make it current)
 * \note Called from the GL API dispatcher.
 */
void _mesa_BindProgramNV(GLenum target, GLuint id)
{
   struct vp_program *vprog;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (target != GL_VERTEX_PROGRAM_NV) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBindProgramNV");
      return;
   }

   if (id == ctx->VertexProgram.CurrentID)
      return;

   /* decrement refcount on previously bound vertex program */
   if (ctx->VertexProgram.Current) {
      ctx->VertexProgram.Current->RefCount--;
      /* and delete if refcount goes below one */
      if (ctx->VertexProgram.Current->RefCount <= 0)
         _mesa_delete_program(ctx, ctx->VertexProgram.CurrentID);
   }

   /* NOTE: binding to a non-existant program is not an error.
    * That's supposed to be caught in glBegin.
    */
   if (id == 0) {
      /* OK, the null program object */
      vprog = NULL;
   }
   else {
      vprog = (struct vp_program *)
         _mesa_HashLookup(ctx->Shared->VertexPrograms, id);

      if (!vprog && id > 0){
         /* new program ID */
         vprog = CALLOC_STRUCT(vp_program);
         if (!vprog) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindProgramNV");
            return;
         }
         vprog->Target = target;
         vprog->Resident = GL_TRUE;
         vprog->RefCount = 1;
         _mesa_HashInsert(ctx->Shared->VertexPrograms, id, vprog);
      }
   }

   ctx->VertexProgram.CurrentID = id;
   ctx->VertexProgram.Current = vprog;
   if (vprog)
      vprog->RefCount++;
}
Exemplo n.º 16
0
Arquivo: hash.c Projeto: aosm/X11
int main(int argc, char *argv[])
{
   int a, b, c;
   struct HashTable *t;

   _mesa_printf("&a = %p\n", &a);
   _mesa_printf("&b = %p\n", &b);

   t = _mesa_NewHashTable();
   _mesa_HashInsert(t, 501, &a);
   _mesa_HashInsert(t, 10, &c);
   _mesa_HashInsert(t, 0xfffffff8, &b);
   _mesa_HashPrint(t);

   _mesa_printf("Find 501: %p\n", _mesa_HashLookup(t,501));
   _mesa_printf("Find 1313: %p\n", _mesa_HashLookup(t,1313));
   _mesa_printf("Find block of 100: %d\n", _mesa_HashFindFreeKeyBlock(t, 100));

   _mesa_DeleteHashTable(t);

   return 0;
}
Exemplo n.º 17
0
/**
 * Bind the specified target to buffer for the specified context.
 * Called by glBindBuffer() and other functions.
 */
static void
bind_buffer_object(struct gl_context *ctx, GLenum target, GLuint buffer)
{
   struct gl_buffer_object *oldBufObj;
   struct gl_buffer_object *newBufObj = NULL;
   struct gl_buffer_object **bindTarget = NULL;

   bindTarget = get_buffer_target(ctx, target);
   if (!bindTarget) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferARB(target 0x%x)", target);
      return;
   }

   /* Get pointer to old buffer object (to be unbound) */
   oldBufObj = *bindTarget;
   if (oldBufObj && oldBufObj->Name == buffer && !oldBufObj->DeletePending)
      return;   /* rebinding the same buffer object- no change */

   /*
    * Get pointer to new buffer object (newBufObj)
    */
   if (buffer == 0) {
      /* The spec says there's not a buffer object named 0, but we use
       * one internally because it simplifies things.
       */
      newBufObj = ctx->Shared->NullBufferObj;
   }
   else {
      /* non-default buffer object */
      newBufObj = _mesa_lookup_bufferobj(ctx, buffer);
      if (!newBufObj || newBufObj == &DummyBufferObject) {
         /* If this is a new buffer object id, or one which was generated but
          * never used before, allocate a buffer object now.
          */
         ASSERT(ctx->Driver.NewBufferObject);
         newBufObj = ctx->Driver.NewBufferObject(ctx, buffer, target);
         if (!newBufObj) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindBufferARB");
            return;
         }
         _mesa_HashInsert(ctx->Shared->BufferObjects, buffer, newBufObj);
      }
   }
   
   /* bind new buffer */
   _mesa_reference_buffer_object(ctx, bindTarget, newBufObj);

   /* Pass BindBuffer call to device driver */
   if (ctx->Driver.BindBuffer)
      ctx->Driver.BindBuffer( ctx, target, newBufObj );
}
Exemplo n.º 18
0
/**
 * Add the given texture object to the texture object pool.
 */
void
_mesa_save_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
{
   /* insert into linked list */
   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
   texObj->Next = ctx->Shared->TexObjectList;
   ctx->Shared->TexObjectList = texObj;
   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);

   if (texObj->Name > 0) {
      /* insert into hash table */
      _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj);
   }
}
Exemplo n.º 19
0
GLuint 
_mesa_create_program(GLcontext *ctx)
{
   GLuint name;
   struct gl_shader_program *shProg;

   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
   shProg = _mesa_new_shader_program(ctx, name);

   _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);

   assert(shProg->RefCount == 1);

   return name;
}
Exemplo n.º 20
0
void GLAPIENTRY
_mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
{
   struct gl_renderbuffer *newRb;
   GET_CURRENT_CONTEXT(ctx);

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (target != GL_RENDERBUFFER_EXT) {
         _mesa_error(ctx, GL_INVALID_ENUM,
                  "glBindRenderbufferEXT(target)");
      return;
   }

   FLUSH_VERTICES(ctx, _NEW_BUFFERS);
   /* The above doesn't fully flush the drivers in the way that a
    * glFlush does, but that is required here:
    */
   if (ctx->Driver.Flush)
      ctx->Driver.Flush(ctx);


   if (renderbuffer) {
      newRb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
      if (newRb == &DummyRenderbuffer) {
         /* ID was reserved, but no real renderbuffer object made yet */
         newRb = NULL;
      }
      if (!newRb) {
	 /* create new renderbuffer object */
	 newRb = ctx->Driver.NewRenderbuffer(ctx, renderbuffer);
	 if (!newRb) {
	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindRenderbufferEXT");
	    return;
	 }
         ASSERT(newRb->AllocStorage);
         _mesa_HashInsert(ctx->Shared->RenderBuffers, renderbuffer, newRb);
         newRb->RefCount = 1; /* referenced by hash table */
      }
   }
   else {
      newRb = NULL;
   }

   ASSERT(newRb != &DummyRenderbuffer);

   _mesa_reference_renderbuffer(&ctx->CurrentRenderbuffer, newRb);
}
Exemplo n.º 21
0
static GLuint 
create_shader_program(struct gl_context *ctx)
{
   GLuint name;
   struct gl_shader_program *shProg;

   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);

   shProg = ctx->Driver.NewShaderProgram(ctx, name);

   _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);

   assert(shProg->RefCount == 1);

   return name;
}
Exemplo n.º 22
0
static GLuint
create_shader(struct gl_context *ctx, GLenum type)
{
   struct gl_shader *sh;
   GLuint name;

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

   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
   sh = ctx->Driver.NewShader(ctx, name, type);
   _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);

   return name;
}
Exemplo n.º 23
0
/**
 * Generate texture names.
 *
 * \param n number of texture names to be generated.
 * \param textures an array in which will hold the generated texture names.
 *
 * \sa glGenTextures().
 *
 * While holding the GenTexturesLock lock, calls _mesa_HashFindFreeKeyBlock()
 * to find a block of free texture IDs which are stored in \p textures.
 * Corresponding empty texture objects are also generated.
 */ 
void GLAPIENTRY
_mesa_GenTextures( GLsizei n, GLuint *textures )
{
   GET_CURRENT_CONTEXT(ctx);
   GLuint first;
   GLint i;
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (n < 0) {
      _mesa_error( ctx, GL_INVALID_VALUE, "glGenTextures" );
      return;
   }

   if (!textures)
      return;

   /*
    * This must be atomic (generation and allocation of texture IDs)
    */
   _glthread_LOCK_MUTEX(GenTexturesLock);

   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->TexObjects, n);

   /* Allocate new, empty texture objects */
   for (i = 0; i < n; i++) {
      struct gl_texture_object *texObj;
      GLuint name = first + i;
      GLenum target = 0;
      texObj = (*ctx->Driver.NewTextureObject)( ctx, name, target);
      if (!texObj) {
         _glthread_UNLOCK_MUTEX(GenTexturesLock);
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTextures");
         return;
      }

      /* insert into hash table */
      _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
      _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj);
      _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);

      textures[i] = name;
   }

   _glthread_UNLOCK_MUTEX(GenTexturesLock);
}
Exemplo n.º 24
0
static void
create_transform_feedbacks(struct gl_context *ctx, GLsizei n, GLuint *ids,
                           bool dsa)
{
   GLuint first;
   const char* func;

   if (dsa)
      func = "glCreateTransformFeedbacks";
   else
      func = "glGenTransformFeedbacks";

   if (n < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
      return;
   }

   if (!ids)
      return;

   /* we don't need contiguous IDs, but this might be faster */
   first = _mesa_HashFindFreeKeyBlock(ctx->TransformFeedback.Objects, n);
   if (first) {
      GLsizei i;
      for (i = 0; i < n; i++) {
         struct gl_transform_feedback_object *obj
            = ctx->Driver.NewTransformFeedback(ctx, first + i);
         if (!obj) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
            return;
         }
         ids[i] = first + i;
         _mesa_HashInsert(ctx->TransformFeedback.Objects, first + i, obj);
         if (dsa) {
            /* this is normally done at bind time in the non-dsa case */
            obj->EverBound = GL_TRUE;
         }
      }
   }
   else {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
   }
}
Exemplo n.º 25
0
void
bmGenBuffers(struct bufmgr *bm, unsigned n, unsigned *buffers, unsigned flags)
{
   LOCK(bm);
   {
      unsigned i;
      unsigned bFlags =
	    (flags) ? flags : DRM_MM_TT | DRM_MM_VRAM | DRM_MM_SYSTEM;

      for (i = 0; i < n; i++) {
	 drmMMBuf *buf = calloc(sizeof(*buf), 1);

	 BM_CKFATAL(drmMMInitBuffer(bm->driFd, bFlags, 12, buf));
	 buf->client_priv = ++bm->buf_nr;
	 buffers[i] = buf->client_priv;
	 _mesa_HashInsert(bm->hash, buffers[i], buf);
      }
   }
   UNLOCK(bm);
}
Exemplo n.º 26
0
/**
 * Generate a set of unique buffer object IDs and store them in \c buffer.
 * 
 * \param n       Number of IDs to generate.
 * \param buffer  Array of \c n locations to store the IDs.
 */
void GLAPIENTRY
_mesa_GenBuffersARB(GLsizei n, GLuint *buffer)
{
   GET_CURRENT_CONTEXT(ctx);
   GLuint first;
   GLint i;
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (n < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGenBuffersARB");
      return;
   }

   if (!buffer) {
      return;
   }

   /*
    * This must be atomic (generation and allocation of buffer object IDs)
    */
   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);

   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->BufferObjects, n);

   /* Allocate new, empty buffer objects and return identifiers */
   for (i = 0; i < n; i++) {
      struct gl_buffer_object *bufObj;
      GLuint name = first + i;
      GLenum target = 0;
      bufObj = ctx->Driver.NewBufferObject( ctx, name, target );
      if (!bufObj) {
         _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenBuffersARB");
         return;
      }
      _mesa_HashInsert(ctx->Shared->BufferObjects, first + i, bufObj);
      buffer[i] = first + i;
   }

   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
}
Exemplo n.º 27
0
GLuint
_mesa_create_shader(GLcontext *ctx, GLenum type)
{
   struct gl_shader *sh;
   GLuint name;

   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);

   switch (type) {
   case GL_FRAGMENT_SHADER:
   case GL_VERTEX_SHADER:
      sh = _mesa_new_shader(ctx, name, type);
      break;
   default:
      _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
      return 0;
   }

   _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);

   return name;
}
Exemplo n.º 28
0
/**
 * Generate a set of unique buffer object IDs and store them in \c buffer.
 * 
 * \param n       Number of IDs to generate.
 * \param buffer  Array of \c n locations to store the IDs.
 */
void GLAPIENTRY
_mesa_GenBuffersARB(GLsizei n, GLuint *buffer)
{
   GET_CURRENT_CONTEXT(ctx);
   GLuint first;
   GLint i;
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glGenBuffers(%d)\n", n);

   if (n < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGenBuffersARB");
      return;
   }

   if (!buffer) {
      return;
   }

   /*
    * This must be atomic (generation and allocation of buffer object IDs)
    */
   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);

   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->BufferObjects, n);

   /* Insert the ID and pointer to dummy buffer object into hash table */
   for (i = 0; i < n; i++) {
      _mesa_HashInsert(ctx->Shared->BufferObjects, first + i,
                       &DummyBufferObject);
      buffer[i] = first + i;
   }

   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
}
Exemplo n.º 29
0
/**
 * Generate a list of new program identifiers.
 * \note Not compiled into display lists.
 * \note Called by both glGenProgramsNV and glGenProgramsARB.
 */
void GLAPIENTRY
_mesa_GenPrograms(GLsizei n, GLuint *ids)
{
   GLuint first;
   GLuint i;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (n < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGenPrograms");
      return;
   }

   if (!ids)
      return;

   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->Programs, n);

   for (i = 0; i < (GLuint) n; i++) {
      const int bytes = MAX2(sizeof(struct vertex_program),
                             sizeof(struct fragment_program));
      struct program *prog = (struct program *) _mesa_calloc(bytes);
      if (!prog) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenPrograms");
         return;
      }
      prog->RefCount = 1;
      prog->Id = first + i;
      _mesa_HashInsert(ctx->Shared->Programs, first + i, prog);
   }

   /* Return the program names */
   for (i = 0; i < (GLuint) n; i++) {
      ids[i] = first + i;
   }
}
Exemplo n.º 30
0
/**
 * Test walking over all the entries in a hash table.
 */
static void
test_hash_walking(void)
{
   struct _mesa_HashTable *t = _mesa_NewHashTable();
   const GLuint limit = 50000;
   GLuint i;

   /* create some entries */
   for (i = 0; i < limit; i++) {
      GLuint dummy;
      GLuint k = (rand() % (limit * 10)) + 1;
      while (_mesa_HashLookup(t, k)) {
         /* id already in use, try another */
         k = (rand() % (limit * 10)) + 1;
      }
      _mesa_HashInsert(t, k, &dummy);
   }

   /* walk over all entries */
   {
      GLuint k = _mesa_HashFirstEntry(t);
      GLuint count = 0;
      while (k) {
         GLuint knext = _mesa_HashNextEntry(t, k);
         assert(knext != k);
         _mesa_HashRemove(t, k);
         count++;
         k = knext;
      }
      assert(count == limit);
      k = _mesa_HashFirstEntry(t);
      assert(k==0);
   }

   _mesa_DeleteHashTable(t);
}