static void
create_samplers(struct gl_context *ctx, GLsizei count, GLuint *samplers,
                const char *caller)
{
   GLuint first;
   GLint i;

   if (!samplers)
      return;

   _mesa_HashLockMutex(ctx->Shared->SamplerObjects);

   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;
      GLuint name = first + i;

      sampObj = ctx->Driver.NewSamplerObject(ctx, name);
      if (!sampObj) {
         _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects);
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
         return;
      }

      _mesa_HashInsertLocked(ctx->Shared->SamplerObjects, name, sampObj);
      samplers[i] = name;
   }

   _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects);
}
static void
delete_samplers(struct gl_context *ctx, GLsizei count, const GLuint *samplers)
{
   FLUSH_VERTICES(ctx, 0);

   _mesa_HashLockMutex(ctx->Shared->SamplerObjects);

   for (GLsizei i = 0; i < count; i++) {
      if (samplers[i]) {
         GLuint j;
         struct gl_sampler_object *sampObj =
            lookup_samplerobj_locked(ctx, samplers[i]);
   
         if (sampObj) {
            /* If the sampler is currently bound, unbind it. */
            for (j = 0; j < ctx->Const.MaxCombinedTextureImageUnits; j++) {
               if (ctx->Texture.Unit[j].Sampler == sampObj) {
                  FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT);
                  _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[j].Sampler, NULL);
               }
            }

            /* The ID is immediately freed for re-use */
            _mesa_HashRemoveLocked(ctx->Shared->SamplerObjects, samplers[i]);
            /* But the object exists until its reference count goes to zero */
            _mesa_reference_sampler_object(ctx, &sampObj, NULL);
         }
      }
   }

   _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects);
}
Beispiel #3
0
/**
 * Generate a list of new program identifiers.
 * \note Not compiled into display lists.
 * \note Called by both glGenProgramsNV and glGenProgramsARB.
 */
void GLAPIENTRY
_mesa_GenProgramsARB(GLsizei n, GLuint *ids)
{
   GLuint first;
   GLuint i;
   GET_CURRENT_CONTEXT(ctx);

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

   if (!ids)
      return;

   _mesa_HashLockMutex(ctx->Shared->Programs);

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

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

   _mesa_HashUnlockMutex(ctx->Shared->Programs);

   /* Return the program names */
   for (i = 0; i < (GLuint) n; i++) {
      ids[i] = first + i;
   }
}
static ALWAYS_INLINE void
bind_samplers(struct gl_context *ctx, GLuint first, GLsizei count,
              const GLuint *samplers, bool no_error)
{
   GLsizei i;

   FLUSH_VERTICES(ctx, 0);

   if (samplers) {
      /* Note that the error semantics for multi-bind commands differ from
       * those of other GL commands.
       *
       * The Issues section in the ARB_multi_bind spec says:
       *
       *    "(11) Typically, OpenGL specifies that if an error is generated by
       *          a command, that command has no effect.  This is somewhat
       *          unfortunate for multi-bind commands, because it would require
       *          a first pass to scan the entire list of bound objects for
       *          errors and then a second pass to actually perform the
       *          bindings.  Should we have different error semantics?
       *
       *       RESOLVED:  Yes.  In this specification, when the parameters for
       *       one of the <count> binding points are invalid, that binding
       *       point is not updated and an error will be generated.  However,
       *       other binding points in the same command will be updated if
       *       their parameters are valid and no other error occurs."
       */

      _mesa_HashLockMutex(ctx->Shared->SamplerObjects);

      for (i = 0; i < count; i++) {
         const GLuint unit = first + i;
         struct gl_sampler_object * const currentSampler =
             ctx->Texture.Unit[unit].Sampler;
         struct gl_sampler_object *sampObj;

         if (samplers[i] != 0) {
            if (currentSampler && currentSampler->Name == samplers[i])
               sampObj = currentSampler;
            else
               sampObj = lookup_samplerobj_locked(ctx, samplers[i]);

            /* The ARB_multi_bind spec says:
             *
             *    "An INVALID_OPERATION error is generated if any value
             *     in <samplers> is not zero or the name of an existing
             *     sampler object (per binding)."
             */
            if (!no_error && !sampObj) {
               _mesa_error(ctx, GL_INVALID_OPERATION,
                           "glBindSamplers(samplers[%d]=%u is not zero or "
                           "the name of an existing sampler object)",
                           i, samplers[i]);
               continue;
            }
         } else {
            sampObj = NULL;
         }

         /* Bind the new sampler */
         if (sampObj != currentSampler) {
            _mesa_reference_sampler_object(ctx,
                                           &ctx->Texture.Unit[unit].Sampler,
                                           sampObj);
            ctx->NewState |= _NEW_TEXTURE_OBJECT;
         }
      }

      _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects);
   } else {
      /* Unbind all samplers in the range <first> through <first>+<count>-1 */
      for (i = 0; i < count; i++) {
         const GLuint unit = first + i;

         if (ctx->Texture.Unit[unit].Sampler) {
            _mesa_reference_sampler_object(ctx,
                                           &ctx->Texture.Unit[unit].Sampler,
                                           NULL);
            ctx->NewState |= _NEW_TEXTURE_OBJECT;
         }
      }
   }
}
Beispiel #5
0
static inline void
end_samplerobj_lookups(struct gl_context *ctx)
{
   _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects);
}