* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
#include "main/enums.h"
#include "main/hash.h"
#include "main/macros.h"
-#include "main/mfeatures.h"
#include "main/mtypes.h"
#include "main/samplerobj.h"
-static struct gl_sampler_object *
+struct gl_sampler_object *
_mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name)
{
if (name == 0)
* Handle reference counting.
*/
void
-_mesa_reference_sampler_object(struct gl_context *ctx,
- struct gl_sampler_object **ptr,
- struct gl_sampler_object *samp)
+_mesa_reference_sampler_object_(struct gl_context *ctx,
+ struct gl_sampler_object **ptr,
+ struct gl_sampler_object *samp)
{
- if (*ptr == samp)
- return;
+ assert(*ptr != samp); /* The inline wrapper should prevent no-op calls */
if (*ptr) {
/* Unreference the old sampler */
GLboolean deleteFlag = GL_FALSE;
struct gl_sampler_object *oldSamp = *ptr;
- /*_glthread_LOCK_MUTEX(oldSamp->Mutex);*/
+ /*mtx_lock(&oldSamp->Mutex);*/
ASSERT(oldSamp->RefCount > 0);
oldSamp->RefCount--;
#if 0
(void *) oldSamp, oldSamp->Name, oldSamp->RefCount);
#endif
deleteFlag = (oldSamp->RefCount == 0);
- /*_glthread_UNLOCK_MUTEX(oldSamp->Mutex);*/
+ /*mtx_unlock(&oldSamp->Mutex);*/
if (deleteFlag) {
ASSERT(ctx->Driver.DeleteSamplerObject);
if (samp) {
/* reference new sampler */
- /*_glthread_LOCK_MUTEX(samp->Mutex);*/
+ /*mtx_lock(&samp->Mutex);*/
if (samp->RefCount == 0) {
/* this sampler's being deleted (look just above) */
/* Not sure this can every really happen. Warn if it does. */
#endif
*ptr = samp;
}
- /*_glthread_UNLOCK_MUTEX(samp->Mutex);*/
+ /*mtx_unlock(&samp->Mutex);*/
}
}
/**
* Initialize the fields of the given sampler object.
*/
-void
+static void
_mesa_init_sampler_object(struct gl_sampler_object *sampObj, GLuint name)
{
sampObj->Name = name;
sampObj->MaxAnisotropy = 1.0F;
sampObj->CompareMode = GL_NONE;
sampObj->CompareFunc = GL_LEQUAL;
- sampObj->CompareFailValue = 0.0;
sampObj->sRGBDecode = GL_DECODE_EXT;
sampObj->CubeMapSeamless = GL_FALSE;
- sampObj->DepthMode = 0;
}
-
/**
* Fallback for ctx->Driver.NewSamplerObject();
*/
/**
* Fallback for ctx->Driver.DeleteSamplerObject();
*/
-void
+static void
_mesa_delete_sampler_object(struct gl_context *ctx,
struct gl_sampler_object *sampObj)
{
- FREE(sampObj);
+ free(sampObj->Label);
+ free(sampObj);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GenSamplers(GLsizei count, GLuint *samplers)
{
GET_CURRENT_CONTEXT(ctx);
GLuint first;
GLint i;
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glGenSamplers(%d)\n", count);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_DeleteSamplers(GLsizei count, const GLuint *samplers)
{
GET_CURRENT_CONTEXT(ctx);
GLsizei i;
- ASSERT_OUTSIDE_BEGIN_END(ctx);
FLUSH_VERTICES(ctx, 0);
if (count < 0) {
return;
}
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_lock(&ctx->Shared->Mutex);
for (i = 0; i < count; i++) {
if (samplers[i]) {
+ GLuint j;
struct gl_sampler_object *sampObj =
_mesa_lookup_samplerobj(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);
+ _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[j].Sampler, NULL);
+ }
+ }
+
/* The ID is immediately freed for re-use */
_mesa_HashRemove(ctx->Shared->SamplerObjects, samplers[i]);
/* But the object exists until its reference count goes to zero */
}
}
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
}
-static GLboolean GLAPIENTRY
+GLboolean GLAPIENTRY
_mesa_IsSampler(GLuint sampler)
{
struct gl_sampler_object *sampObj;
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_BindSampler(GLuint unit, GLuint sampler)
{
struct gl_sampler_object *sampObj;
case GL_MIRROR_CLAMP_EXT:
return e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp;
case GL_MIRROR_CLAMP_TO_EDGE_EXT:
- return e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp;
+ return e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp || e->ARB_texture_mirror_clamp_to_edge;
case GL_MIRROR_CLAMP_TO_BORDER_EXT:
return e->EXT_texture_mirror_clamp;
default:
/**
* This is called just prior to changing any sampler object state.
*/
-static INLINE void
+static inline void
flush(struct gl_context *ctx)
{
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
switch (param) {
case GL_LEQUAL:
case GL_GEQUAL:
- flush(ctx);
- samp->CompareFunc = param;
- return GL_TRUE;
case GL_EQUAL:
case GL_NOTEQUAL:
case GL_LESS:
case GL_GREATER:
case GL_ALWAYS:
case GL_NEVER:
- if (ctx->Extensions.EXT_shadow_funcs) {
- flush(ctx);
- samp->CompareFunc = param;
- return GL_TRUE;
- }
- /* fall-through */
+ flush(ctx);
+ samp->CompareFunc = param;
+ return GL_TRUE;
default:
return INVALID_PARAM;
}
set_sampler_cube_map_seamless(struct gl_context *ctx,
struct gl_sampler_object *samp, GLboolean param)
{
- if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
+ if (!_mesa_is_desktop_gl(ctx)
+ || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
return INVALID_PNAME;
if (samp->CubeMapSeamless == param)
return GL_TRUE;
}
+static GLuint
+set_sampler_srgb_decode(struct gl_context *ctx,
+ struct gl_sampler_object *samp, GLenum param)
+{
+ if (!ctx->Extensions.EXT_texture_sRGB_decode)
+ return INVALID_PNAME;
+
+ if (samp->sRGBDecode == param)
+ return GL_FALSE;
+
+ if (param != GL_DECODE_EXT && param != GL_SKIP_DECODE_EXT)
+ return INVALID_VALUE;
-static void GLAPIENTRY
+ flush(ctx);
+ samp->sRGBDecode = param;
+ return GL_TRUE;
+}
+
+void GLAPIENTRY
_mesa_SamplerParameteri(GLuint sampler, GLenum pname, GLint param)
{
struct gl_sampler_object *sampObj;
case GL_TEXTURE_CUBE_MAP_SEAMLESS:
res = set_sampler_cube_map_seamless(ctx, sampObj, param);
break;
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ res = set_sampler_srgb_decode(ctx, sampObj, param);
+ break;
case GL_TEXTURE_BORDER_COLOR:
/* fall-through */
default:
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
{
struct gl_sampler_object *sampObj;
GLuint res;
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
sampObj = _mesa_lookup_samplerobj(ctx, sampler);
if (!sampObj) {
_mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterf(sampler %u)",
case GL_TEXTURE_CUBE_MAP_SEAMLESS:
res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) param);
break;
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) param);
+ break;
case GL_TEXTURE_BORDER_COLOR:
/* fall-through */
default:
}
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params)
{
struct gl_sampler_object *sampObj;
case GL_TEXTURE_CUBE_MAP_SEAMLESS:
res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]);
break;
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ res = set_sampler_srgb_decode(ctx, sampObj, params[0]);
+ break;
case GL_TEXTURE_BORDER_COLOR:
{
GLfloat c[4];
}
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params)
{
struct gl_sampler_object *sampObj;
GLuint res;
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
sampObj = _mesa_lookup_samplerobj(ctx, sampler);
if (!sampObj) {
_mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterfv(sampler %u)",
case GL_TEXTURE_CUBE_MAP_SEAMLESS:
res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) params[0]);
break;
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]);
+ break;
case GL_TEXTURE_BORDER_COLOR:
res = set_sampler_border_colorf(ctx, sampObj, params);
break;
}
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params)
{
struct gl_sampler_object *sampObj;
case GL_TEXTURE_CUBE_MAP_SEAMLESS:
res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]);
break;
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]);
+ break;
case GL_TEXTURE_BORDER_COLOR:
res = set_sampler_border_colori(ctx, sampObj, params);
break;
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params)
{
struct gl_sampler_object *sampObj;
case GL_TEXTURE_CUBE_MAP_SEAMLESS:
res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]);
break;
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]);
+ break;
case GL_TEXTURE_BORDER_COLOR:
res = set_sampler_border_colorui(ctx, sampObj, params);
break;
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
{
struct gl_sampler_object *sampObj;
goto invalid_pname;
*params = sampObj->CubeMapSeamless;
break;
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ if (!ctx->Extensions.EXT_texture_sRGB_decode)
+ goto invalid_pname;
+ *params = (GLenum) sampObj->sRGBDecode;
+ break;
default:
goto invalid_pname;
}
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
{
struct gl_sampler_object *sampObj;
goto invalid_pname;
*params = (GLfloat) sampObj->CubeMapSeamless;
break;
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ if (!ctx->Extensions.EXT_texture_sRGB_decode)
+ goto invalid_pname;
+ *params = (GLfloat) sampObj->sRGBDecode;
+ break;
default:
goto invalid_pname;
}
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params)
{
struct gl_sampler_object *sampObj;
goto invalid_pname;
*params = sampObj->CubeMapSeamless;
break;
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ if (!ctx->Extensions.EXT_texture_sRGB_decode)
+ goto invalid_pname;
+ *params = (GLenum) sampObj->sRGBDecode;
+ break;
default:
goto invalid_pname;
}
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params)
{
struct gl_sampler_object *sampObj;
goto invalid_pname;
*params = sampObj->CubeMapSeamless;
break;
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ if (!ctx->Extensions.EXT_texture_sRGB_decode)
+ goto invalid_pname;
+ *params = (GLenum) sampObj->sRGBDecode;
+ break;
default:
goto invalid_pname;
}
driver->NewSamplerObject = _mesa_new_sampler_object;
driver->DeleteSamplerObject = _mesa_delete_sampler_object;
}
-
-
-void
-_mesa_init_sampler_object_dispatch(struct _glapi_table *disp)
-{
- SET_GenSamplers(disp, _mesa_GenSamplers);
- SET_DeleteSamplers(disp, _mesa_DeleteSamplers);
- SET_IsSampler(disp, _mesa_IsSampler);
- SET_BindSampler(disp, _mesa_BindSampler);
- SET_SamplerParameteri(disp, _mesa_SamplerParameteri);
- SET_SamplerParameterf(disp, _mesa_SamplerParameterf);
- SET_SamplerParameteriv(disp, _mesa_SamplerParameteriv);
- SET_SamplerParameterfv(disp, _mesa_SamplerParameterfv);
- SET_SamplerParameterIiv(disp, _mesa_SamplerParameterIiv);
- SET_SamplerParameterIuiv(disp, _mesa_SamplerParameterIuiv);
- SET_GetSamplerParameteriv(disp, _mesa_GetSamplerParameteriv);
- SET_GetSamplerParameterfv(disp, _mesa_GetSamplerParameterfv);
- SET_GetSamplerParameterIiv(disp, _mesa_GetSamplerParameterIiv);
- SET_GetSamplerParameterIuiv(disp, _mesa_GetSamplerParameterIuiv);
-}