mesa: only verify that enabled arrays have backing buffers
[mesa.git] / src / mesa / main / samplerobj.c
index c7b96664c21e7c12b94745d24109bb3f3f0fbeac..2118f0ecb8733cdb903bde0ce2141c27dc56cc7e 100644 (file)
@@ -50,6 +50,15 @@ _mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name)
          _mesa_HashLookup(ctx->Shared->SamplerObjects, name);
 }
 
+static struct gl_sampler_object *
+_mesa_lookup_samplerobj_locked(struct gl_context *ctx, GLuint name)
+{
+   if (name == 0)
+      return NULL;
+   else
+      return (struct gl_sampler_object *)
+         _mesa_HashLookupLocked(ctx->Shared->SamplerObjects, name);
+}
 
 static inline void
 begin_samplerobj_lookups(struct gl_context *ctx)
@@ -72,6 +81,14 @@ lookup_samplerobj_locked(struct gl_context *ctx, GLuint name)
          _mesa_HashLookupLocked(ctx->Shared->SamplerObjects, name);
 }
 
+static void
+delete_sampler_object(struct gl_context *ctx,
+                      struct gl_sampler_object *sampObj)
+{
+   mtx_destroy(&sampObj->Mutex);
+   free(sampObj->Label);
+   free(sampObj);
+}
 
 /**
  * Handle reference counting.
@@ -94,10 +111,8 @@ _mesa_reference_sampler_object_(struct gl_context *ctx,
       deleteFlag = (oldSamp->RefCount == 0);
       mtx_unlock(&oldSamp->Mutex);
 
-      if (deleteFlag) {
-        assert(ctx->Driver.DeleteSamplerObject);
-         ctx->Driver.DeleteSamplerObject(ctx, oldSamp);
-      }
+      if (deleteFlag)
+         delete_sampler_object(ctx, oldSamp);
 
       *ptr = NULL;
    }
@@ -162,19 +177,6 @@ _mesa_new_sampler_object(struct gl_context *ctx, GLuint name)
    return sampObj;
 }
 
-
-/**
- * Fallback for ctx->Driver.DeleteSamplerObject();
- */
-static void
-_mesa_delete_sampler_object(struct gl_context *ctx,
-                            struct gl_sampler_object *sampObj)
-{
-   mtx_destroy(&sampObj->Mutex);
-   free(sampObj->Label);
-   free(sampObj);
-}
-
 static void
 create_samplers(struct gl_context *ctx, GLsizei count, GLuint *samplers,
                 const char *caller)
@@ -193,15 +195,19 @@ create_samplers(struct gl_context *ctx, GLsizei count, GLuint *samplers,
    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 =
          ctx->Driver.NewSamplerObject(ctx, first + i);
-      _mesa_HashInsert(ctx->Shared->SamplerObjects, first + i, sampObj);
+      _mesa_HashInsertLocked(ctx->Shared->SamplerObjects, first + i, sampObj);
       samplers[i] = first + i;
    }
+
+   _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects);
 }
 
 void GLAPIENTRY
@@ -232,13 +238,13 @@ _mesa_DeleteSamplers(GLsizei count, const GLuint *samplers)
       return;
    }
 
-   mtx_lock(&ctx->Shared->Mutex);
+   _mesa_HashLockMutex(ctx->Shared->SamplerObjects);
 
    for (i = 0; i < count; i++) {
       if (samplers[i]) {
          GLuint j;
          struct gl_sampler_object *sampObj =
-            _mesa_lookup_samplerobj(ctx, samplers[i]);
+            _mesa_lookup_samplerobj_locked(ctx, samplers[i]);
    
          if (sampObj) {
             /* If the sampler is currently bound, unbind it. */
@@ -250,14 +256,14 @@ _mesa_DeleteSamplers(GLsizei count, const GLuint *samplers)
             }
 
             /* The ID is immediately freed for re-use */
-            _mesa_HashRemove(ctx->Shared->SamplerObjects, samplers[i]);
+            _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);
          }
       }
    }
 
-   mtx_unlock(&ctx->Shared->Mutex);
+   _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects);
 }
 
 
@@ -277,6 +283,17 @@ _mesa_IsSampler(GLuint sampler)
    return sampObj != NULL;
 }
 
+void
+_mesa_bind_sampler(struct gl_context *ctx, GLuint unit,
+                   struct gl_sampler_object *sampObj)
+{
+   if (ctx->Texture.Unit[unit].Sampler != sampObj) {
+      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+   }
+
+   _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[unit].Sampler,
+                                  sampObj);
+}
 
 void GLAPIENTRY
 _mesa_BindSampler(GLuint unit, GLuint sampler)
@@ -304,13 +321,8 @@ _mesa_BindSampler(GLuint unit, GLuint sampler)
       }
    }
    
-   if (ctx->Texture.Unit[unit].Sampler != sampObj) {
-      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-   }
-
    /* bind new sampler */
-   _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[unit].Sampler,
-                                  sampObj);
+   _mesa_bind_sampler(ctx, unit, sampObj);
 }
 
 
@@ -451,6 +463,22 @@ flush(struct gl_context *ctx)
    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 }
 
+void
+_mesa_set_sampler_wrap(struct gl_context *ctx, struct gl_sampler_object *samp,
+                       GLenum s, GLenum t, GLenum r)
+{
+   assert(validate_texture_wrap_mode(ctx, s));
+   assert(validate_texture_wrap_mode(ctx, t));
+   assert(validate_texture_wrap_mode(ctx, r));
+
+   if (samp->WrapS == s && samp->WrapT == t && samp->WrapR == r)
+      return;
+
+   flush(ctx);
+   samp->WrapS = s;
+   samp->WrapT = t;
+   samp->WrapR = r;
+}
 
 #define INVALID_PARAM 0x100
 #define INVALID_PNAME 0x101
@@ -500,6 +528,27 @@ set_sampler_wrap_r(struct gl_context *ctx, struct gl_sampler_object *samp,
    return INVALID_PARAM;
 }
 
+void
+_mesa_set_sampler_filters(struct gl_context *ctx,
+                          struct gl_sampler_object *samp,
+                          GLenum min_filter, GLenum mag_filter)
+{
+   assert(min_filter == GL_NEAREST ||
+          min_filter == GL_LINEAR ||
+          min_filter == GL_NEAREST_MIPMAP_NEAREST ||
+          min_filter == GL_LINEAR_MIPMAP_NEAREST ||
+          min_filter == GL_NEAREST_MIPMAP_LINEAR ||
+          min_filter == GL_LINEAR_MIPMAP_LINEAR);
+   assert(mag_filter == GL_NEAREST ||
+          mag_filter == GL_LINEAR);
+
+   if (samp->MinFilter == min_filter && samp->MagFilter == mag_filter)
+      return;
+
+   flush(ctx);
+   samp->MinFilter = min_filter;
+   samp->MagFilter = mag_filter;
+}
 
 static GLuint
 set_sampler_min_filter(struct gl_context *ctx, struct gl_sampler_object *samp,
@@ -628,8 +677,12 @@ static GLuint
 set_sampler_compare_mode(struct gl_context *ctx,
                          struct gl_sampler_object *samp, GLint param)
 {
+    /* If GL_ARB_shadow is not supported, don't report an error.  The
+     * sampler object extension spec isn't clear on this extension interaction.
+     * Silences errors with Wine on older GPUs such as R200.
+     */
    if (!ctx->Extensions.ARB_shadow)
-      return INVALID_PNAME;
+      return GL_FALSE;
 
    if (samp->CompareMode == param)
       return GL_FALSE;
@@ -649,8 +702,12 @@ static GLuint
 set_sampler_compare_func(struct gl_context *ctx,
                          struct gl_sampler_object *samp, GLint param)
 {
+    /* If GL_ARB_shadow is not supported, don't report an error.  The
+     * sampler object extension spec isn't clear on this extension interaction.
+     * Silences errors with Wine on older GPUs such as R200.
+     */
    if (!ctx->Extensions.ARB_shadow)
-      return INVALID_PNAME;
+      return GL_FALSE;
 
    if (samp->CompareFunc == param)
       return GL_FALSE;
@@ -712,6 +769,16 @@ set_sampler_cube_map_seamless(struct gl_context *ctx,
    return GL_TRUE;
 }
 
+void
+_mesa_set_sampler_srgb_decode(struct gl_context *ctx,
+                              struct gl_sampler_object *samp, GLenum param)
+{
+   assert(param == GL_DECODE_EXT || param == GL_SKIP_DECODE_EXT);
+
+   flush(ctx);
+   samp->sRGBDecode = param;
+}
+
 static GLuint
 set_sampler_srgb_decode(struct gl_context *ctx,
                               struct gl_sampler_object *samp, GLenum param)
@@ -744,10 +811,8 @@ _mesa_SamplerParameteri(GLuint sampler, GLenum pname, GLint param)
        *     "An INVALID_OPERATION error is generated if sampler is not the name
        *     of a sampler object previously returned from a call to GenSamplers."
        *
-       * In desktop GL, an GL_INVALID_VALUE is returned instead.
        */
-      _mesa_error(ctx, (_mesa_is_gles(ctx) ?
-                        GL_INVALID_OPERATION : GL_INVALID_VALUE),
+      _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glSamplerParameteri(sampler %u)", sampler);
       return;
    }
@@ -837,10 +902,8 @@ _mesa_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
        *     "An INVALID_OPERATION error is generated if sampler is not the name
        *     of a sampler object previously returned from a call to GenSamplers."
        *
-       * In desktop GL, an GL_INVALID_VALUE is returned instead.
        */
-      _mesa_error(ctx, (_mesa_is_gles(ctx) ?
-                        GL_INVALID_OPERATION : GL_INVALID_VALUE),
+      _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glSamplerParameterf(sampler %u)", sampler);
       return;
    }
@@ -928,11 +991,8 @@ _mesa_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params)
        *
        *     "An INVALID_OPERATION error is generated if sampler is not the name
        *     of a sampler object previously returned from a call to GenSamplers."
-       *
-       * In desktop GL, an GL_INVALID_VALUE is returned instead.
        */
-      _mesa_error(ctx, (_mesa_is_gles(ctx) ?
-                        GL_INVALID_OPERATION : GL_INVALID_VALUE),
+      _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glSamplerParameteriv(sampler %u)", sampler);
       return;
    }
@@ -1029,10 +1089,8 @@ _mesa_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params)
        *     "An INVALID_OPERATION error is generated if sampler is not the name
        *     of a sampler object previously returned from a call to GenSamplers."
        *
-       * In desktop GL, an GL_INVALID_VALUE is returned instead.
        */
-      _mesa_error(ctx, (_mesa_is_gles(ctx) ?
-                        GL_INVALID_OPERATION : GL_INVALID_VALUE),
+      _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glSamplerParameterfv(sampler %u)", sampler);
       return;
    }
@@ -1117,8 +1175,8 @@ _mesa_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params)
 
    sampObj = _mesa_lookup_samplerobj(ctx, sampler);
    if (!sampObj) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIiv(sampler %u)",
-                  sampler);
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glSamplerParameterIiv(sampler %u)", sampler);
       return;
    }
 
@@ -1203,8 +1261,8 @@ _mesa_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params)
 
    sampObj = _mesa_lookup_samplerobj(ctx, sampler);
    if (!sampObj) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIuiv(sampler %u)",
-                  sampler);
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glSamplerParameterIuiv(sampler %u)", sampler);
       return;
    }
 
@@ -1293,10 +1351,8 @@ _mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
        *     "An INVALID_OPERATION error is generated if sampler is not the name
        *     of a sampler object previously returned from a call to GenSamplers."
        *
-       * In desktop GL, an GL_INVALID_VALUE is returned instead.
        */
-      _mesa_error(ctx, (_mesa_is_gles(ctx) ?
-                        GL_INVALID_OPERATION : GL_INVALID_VALUE),
+      _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glGetSamplerParameteriv(sampler %u)", sampler);
       return;
    }
@@ -1336,13 +1392,9 @@ _mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
       *params = IROUND(sampObj->LodBias);
       break;
    case GL_TEXTURE_COMPARE_MODE:
-      if (!ctx->Extensions.ARB_shadow)
-         goto invalid_pname;
       *params = sampObj->CompareMode;
       break;
    case GL_TEXTURE_COMPARE_FUNC:
-      if (!ctx->Extensions.ARB_shadow)
-         goto invalid_pname;
       *params = sampObj->CompareFunc;
       break;
    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
@@ -1391,10 +1443,8 @@ _mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
        *     "An INVALID_OPERATION error is generated if sampler is not the name
        *     of a sampler object previously returned from a call to GenSamplers."
        *
-       * In desktop GL, an GL_INVALID_VALUE is returned instead.
        */
-      _mesa_error(ctx, (_mesa_is_gles(ctx) ?
-                        GL_INVALID_OPERATION : GL_INVALID_VALUE),
+      _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glGetSamplerParameterfv(sampler %u)", sampler);
       return;
    }
@@ -1425,13 +1475,9 @@ _mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
       *params = sampObj->LodBias;
       break;
    case GL_TEXTURE_COMPARE_MODE:
-      if (!ctx->Extensions.ARB_shadow)
-         goto invalid_pname;
       *params = (GLfloat) sampObj->CompareMode;
       break;
    case GL_TEXTURE_COMPARE_FUNC:
-      if (!ctx->Extensions.ARB_shadow)
-         goto invalid_pname;
       *params = (GLfloat) sampObj->CompareFunc;
       break;
    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
@@ -1472,7 +1518,7 @@ _mesa_GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params)
 
    sampObj = _mesa_lookup_samplerobj(ctx, sampler);
    if (!sampObj) {
-      _mesa_error(ctx, GL_INVALID_VALUE,
+      _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glGetSamplerParameterIiv(sampler %u)",
                   sampler);
       return;
@@ -1504,13 +1550,9 @@ _mesa_GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params)
       *params = (GLint) sampObj->LodBias;
       break;
    case GL_TEXTURE_COMPARE_MODE:
-      if (!ctx->Extensions.ARB_shadow)
-         goto invalid_pname;
       *params = sampObj->CompareMode;
       break;
    case GL_TEXTURE_COMPARE_FUNC:
-      if (!ctx->Extensions.ARB_shadow)
-         goto invalid_pname;
       *params = sampObj->CompareFunc;
       break;
    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
@@ -1551,7 +1593,7 @@ _mesa_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params)
 
    sampObj = _mesa_lookup_samplerobj(ctx, sampler);
    if (!sampObj) {
-      _mesa_error(ctx, GL_INVALID_VALUE,
+      _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glGetSamplerParameterIuiv(sampler %u)",
                   sampler);
       return;
@@ -1583,13 +1625,9 @@ _mesa_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params)
       *params = (GLuint) sampObj->LodBias;
       break;
    case GL_TEXTURE_COMPARE_MODE:
-      if (!ctx->Extensions.ARB_shadow)
-         goto invalid_pname;
       *params = sampObj->CompareMode;
       break;
    case GL_TEXTURE_COMPARE_FUNC:
-      if (!ctx->Extensions.ARB_shadow)
-         goto invalid_pname;
       *params = sampObj->CompareFunc;
       break;
    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
@@ -1626,5 +1664,4 @@ void
 _mesa_init_sampler_object_functions(struct dd_function_table *driver)
 {
    driver->NewSamplerObject = _mesa_new_sampler_object;
-   driver->DeleteSamplerObject = _mesa_delete_sampler_object;
 }