/*
* Mesa 3-D graphics library
- * Version: 7.5
*
* Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
* Copyright (C) 2009 VMware, Inc. All Rights Reserved.
* 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.
*/
-/**
+/**
* \file texparam.c
*
* glTexParameter-related functions
* Check if a coordinate wrap mode is supported for the texture target.
* \return GL_TRUE if legal, GL_FALSE otherwise
*/
-static GLboolean
+static GLboolean
validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap)
{
const struct gl_extensions * const e = & ctx->Extensions;
break;
case GL_MIRROR_CLAMP_EXT:
- case GL_MIRROR_CLAMP_TO_EDGE_EXT:
- supported = is_desktop_gl
+ supported = is_desktop_gl
&& (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)
- && (target != GL_TEXTURE_RECTANGLE_NV)
+ && (target != GL_TEXTURE_RECTANGLE_NV)
+ && (target != GL_TEXTURE_EXTERNAL_OES);
+ break;
+
+ case GL_MIRROR_CLAMP_TO_EDGE_EXT:
+ supported = is_desktop_gl
+ && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp || e->ARB_texture_mirror_clamp_to_edge)
+ && (target != GL_TEXTURE_RECTANGLE_NV)
&& (target != GL_TEXTURE_EXTERNAL_OES);
break;
case GL_MIRROR_CLAMP_TO_BORDER_EXT:
supported = is_desktop_gl && e->EXT_texture_mirror_clamp
- && (target != GL_TEXTURE_RECTANGLE_NV)
+ && (target != GL_TEXTURE_RECTANGLE_NV)
&& (target != GL_TEXTURE_EXTERNAL_OES);
break;
/**
* Get current texture object for given target.
* Return NULL if any error (and record the error).
- * Note that this is different from _mesa_select_tex_object() in that proxy
- * targets are not accepted.
+ * Note that this is different from _mesa_get_current_tex_object() in that
+ * proxy targets are not accepted.
* Only the glGetTexLevelParameter() functions accept proxy targets.
*/
static struct gl_texture_object *
get_texobj(struct gl_context *ctx, GLenum target, GLboolean get)
{
struct gl_texture_unit *texUnit;
+ int targetIndex;
if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
_mesa_error(ctx, GL_INVALID_OPERATION,
texUnit = _mesa_get_current_tex_unit(ctx);
- switch (target) {
- case GL_TEXTURE_1D:
- if (_mesa_is_desktop_gl(ctx))
- return texUnit->CurrentTex[TEXTURE_1D_INDEX];
- break;
- case GL_TEXTURE_2D:
- return texUnit->CurrentTex[TEXTURE_2D_INDEX];
- case GL_TEXTURE_3D:
- if (ctx->API != API_OPENGLES)
- return texUnit->CurrentTex[TEXTURE_3D_INDEX];
- break;
- case GL_TEXTURE_CUBE_MAP:
- if (ctx->Extensions.ARB_texture_cube_map) {
- return texUnit->CurrentTex[TEXTURE_CUBE_INDEX];
- }
- break;
- case GL_TEXTURE_RECTANGLE_NV:
- if (_mesa_is_desktop_gl(ctx)
- && ctx->Extensions.NV_texture_rectangle) {
- return texUnit->CurrentTex[TEXTURE_RECT_INDEX];
- }
- break;
- case GL_TEXTURE_1D_ARRAY_EXT:
- if (_mesa_is_desktop_gl(ctx)
- && (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array)) {
- return texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX];
- }
- break;
- case GL_TEXTURE_2D_ARRAY_EXT:
- if ((_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx))
- && (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array)) {
- return texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX];
- }
- break;
- case GL_TEXTURE_EXTERNAL_OES:
- if (_mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external) {
- return texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX];
- }
- break;
- case GL_TEXTURE_CUBE_MAP_ARRAY:
- if (ctx->Extensions.ARB_texture_cube_map_array) {
- return texUnit->CurrentTex[TEXTURE_CUBE_ARRAY_INDEX];
- }
- break;
- case GL_TEXTURE_2D_MULTISAMPLE:
- if (ctx->Extensions.ARB_texture_storage_multisample) {
- return texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_INDEX];
- }
- break;
- case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
- if (ctx->Extensions.ARB_texture_storage_multisample) {
- return texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX];
- }
- break;
- default:
- ;
+ targetIndex = _mesa_tex_target_to_index(ctx, target);
+ if (targetIndex < 0 || targetIndex == TEXTURE_BUFFER_INDEX) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "gl%sTexParameter(target)", get ? "Get" : "");
+ return NULL;
}
+ assert(targetIndex < NUM_TEXTURE_TARGETS);
- _mesa_error(ctx, GL_INVALID_ENUM,
- "gl%sTexParameter(target)", get ? "Get" : "");
- return NULL;
+ return texUnit->CurrentTex[targetIndex];
}
incomplete(struct gl_context *ctx, struct gl_texture_object *texObj)
{
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
- _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
+ _mesa_dirty_texobj(ctx, texObj);
}
return GL_FALSE;
}
incomplete(ctx, texObj);
- texObj->BaseLevel = params[0];
+
+ /** See note about ARB_texture_storage below */
+ if (texObj->Immutable)
+ texObj->BaseLevel = MIN2(texObj->ImmutableLevels - 1, params[0]);
+ else
+ texObj->BaseLevel = params[0];
+
return GL_TRUE;
case GL_TEXTURE_MAX_LEVEL:
if (texObj->MaxLevel == params[0])
return GL_FALSE;
- if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) {
+ if (params[0] < 0 ||
+ (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] > 0)) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glTexParameter(param=%d)", params[0]);
return GL_FALSE;
}
incomplete(ctx, texObj);
- texObj->MaxLevel = params[0];
+
+ /** From ARB_texture_storage:
+ * However, if TEXTURE_IMMUTABLE_FORMAT is TRUE, then level_base is
+ * clamped to the range [0, <levels> - 1] and level_max is then clamped to
+ * the range [level_base, <levels> - 1], where <levels> is the parameter
+ * passed the call to TexStorage* for the texture object.
+ */
+ if (texObj->Immutable)
+ texObj->MaxLevel = CLAMP(params[0], texObj->BaseLevel,
+ texObj->ImmutableLevels - 1);
+ else
+ texObj->MaxLevel = params[0];
+
return GL_TRUE;
case GL_GENERATE_MIPMAP_SGIS:
switch (params[0]) {
case GL_LEQUAL:
case GL_GEQUAL:
- flush(ctx);
- texObj->Sampler.CompareFunc = params[0];
- 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);
- texObj->Sampler.CompareFunc = params[0];
- return GL_TRUE;
- }
- /* fall-through */
+ flush(ctx);
+ texObj->Sampler.CompareFunc = params[0];
+ return GL_TRUE;
default:
goto invalid_param;
}
}
goto invalid_pname;
+ case GL_DEPTH_STENCIL_TEXTURE_MODE:
+ if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_stencil_texturing) {
+ bool stencil = params[0] == GL_STENCIL_INDEX;
+ if (!stencil && params[0] != GL_DEPTH_COMPONENT)
+ goto invalid_param;
+
+ if (texObj->StencilSampling == stencil)
+ return GL_FALSE;
+
+ texObj->StencilSampling = stencil;
+ return GL_TRUE;
+ }
+ goto invalid_pname;
+
case GL_TEXTURE_CROP_RECT_OES:
if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
goto invalid_pname;
return GL_FALSE;
case GL_TEXTURE_LOD_BIAS:
- /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias.
- * It was removed in core-profile, and it has never existed in OpenGL
- * ES.
- */
- if (ctx->API != API_OPENGL_COMPAT)
+ /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias. */
+ if (_mesa_is_gles(ctx))
goto invalid_pname;
if (!target_allows_setting_sampler_parameters(texObj->Target))
case GL_TEXTURE_COMPARE_MODE_ARB:
case GL_TEXTURE_COMPARE_FUNC_ARB:
case GL_DEPTH_TEXTURE_MODE_ARB:
+ case GL_DEPTH_STENCIL_TEXTURE_MODE:
case GL_TEXTURE_SRGB_DECODE_EXT:
case GL_TEXTURE_CUBE_MAP_SEAMLESS:
case GL_TEXTURE_SWIZZLE_R_EXT:
}
if (ctx->Driver.TexParameter && need_update) {
- ctx->Driver.TexParameter(ctx, target, texObj, pname, ¶m);
+ ctx->Driver.TexParameter(ctx, texObj, pname, ¶m);
}
}
case GL_TEXTURE_COMPARE_MODE_ARB:
case GL_TEXTURE_COMPARE_FUNC_ARB:
case GL_DEPTH_TEXTURE_MODE_ARB:
+ case GL_DEPTH_STENCIL_TEXTURE_MODE:
case GL_TEXTURE_SRGB_DECODE_EXT:
case GL_TEXTURE_CUBE_MAP_SEAMLESS:
{
}
if (ctx->Driver.TexParameter && need_update) {
- ctx->Driver.TexParameter(ctx, target, texObj, pname, params);
+ ctx->Driver.TexParameter(ctx, texObj, pname, params);
}
}
if (ctx->Driver.TexParameter && need_update) {
GLfloat fparam = (GLfloat) param;
- ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam);
+ ctx->Driver.TexParameter(ctx, texObj, pname, &fparam);
}
}
fparams[2] = INT_TO_FLOAT(params[2]);
fparams[3] = INT_TO_FLOAT(params[3]);
}
- ctx->Driver.TexParameter(ctx, target, texObj, pname, fparams);
+ ctx->Driver.TexParameter(ctx, texObj, pname, fparams);
}
}
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
return ctx->Extensions.ARB_texture_cube_map;
+ case GL_TEXTURE_CUBE_MAP_ARRAY_ARB:
+ case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB:
+ return ctx->Extensions.ARB_texture_cube_map_array;
case GL_TEXTURE_RECTANGLE_NV:
case GL_PROXY_TEXTURE_RECTANGLE_NV:
return ctx->Extensions.NV_texture_rectangle;
case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
case GL_TEXTURE_2D_ARRAY_EXT:
case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
- return (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array);
+ return ctx->Extensions.EXT_texture_array;
case GL_TEXTURE_BUFFER:
/* GetTexLevelParameter accepts GL_TEXTURE_BUFFER in GL 3.1+ contexts,
* but not in earlier versions that expose ARB_texture_buffer_object.
return ctx->API == API_OPENGL_CORE && ctx->Version >= 31;
case GL_TEXTURE_2D_MULTISAMPLE:
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
return ctx->Extensions.ARB_texture_multisample;
default:
return GL_FALSE;
GLenum pname, GLint *params)
{
const struct gl_texture_image *img = NULL;
- gl_format texFormat;
+ mesa_format texFormat;
img = _mesa_select_tex_image(ctx, texObj, target, level);
if (!img || img->TexFormat == MESA_FORMAT_NONE) {
- /* undefined texture image */
- if (pname == GL_TEXTURE_COMPONENTS)
- *params = 1;
+ /* In case of undefined texture image return the default values.
+ *
+ * From OpenGL 4.0 spec, page 398:
+ * "The initial internal format of a texel array is RGBA
+ * instead of 1. TEXTURE_COMPONENTS is deprecated; always
+ * use TEXTURE_INTERNAL_FORMAT."
+ */
+
+ if (pname == GL_TEXTURE_INTERNAL_FORMAT)
+ *params = GL_RGBA;
else
*params = 0;
return;
goto invalid_pname;
*params = _mesa_get_format_bits(texFormat, pname);
break;
- case GL_TEXTURE_STENCIL_SIZE_EXT:
- if (!ctx->Extensions.EXT_packed_depth_stencil &&
- !ctx->Extensions.ARB_framebuffer_object)
- goto invalid_pname;
+ case GL_TEXTURE_STENCIL_SIZE:
*params = _mesa_get_format_bits(texFormat, pname);
break;
case GL_TEXTURE_SHARED_SIZE:
if (ctx->Version < 30 &&
!ctx->Extensions.EXT_texture_shared_exponent)
goto invalid_pname;
- *params = texFormat == MESA_FORMAT_RGB9_E5_FLOAT ? 5 : 0;
+ *params = texFormat == MESA_FORMAT_R9G9B9E5_FLOAT ? 5 : 0;
break;
/* GL_ARB_texture_compression */
GLenum pname, GLint *params)
{
const struct gl_buffer_object *bo = texObj->BufferObject;
- gl_format texFormat = texObj->_BufferObjectFormat;
+ mesa_format texFormat = texObj->_BufferObjectFormat;
GLenum internalFormat = texObj->BufferObjectFormat;
GLenum baseFormat = _mesa_get_format_base_format(texFormat);
_mesa_GetTexLevelParameteriv( GLenum target, GLint level,
GLenum pname, GLint *params )
{
- const struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
GLint maxLevels;
GET_CURRENT_CONTEXT(ctx);
return;
}
- texUnit = _mesa_get_current_tex_unit(ctx);
-
if (!legal_get_tex_level_parameter_target(ctx, target)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetTexLevelParameter[if]v(target=0x%x)", target);
return;
}
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texObj = _mesa_get_current_tex_object(ctx, target);
if (target == GL_TEXTURE_BUFFER)
get_tex_level_parameter_buffer(ctx, texObj, pname, params);
goto invalid_pname;
*params = (GLfloat) obj->DepthMode;
break;
+ case GL_DEPTH_STENCIL_TEXTURE_MODE:
+ if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_stencil_texturing)
+ goto invalid_pname;
+ *params = (GLfloat)
+ (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT);
+ break;
case GL_TEXTURE_LOD_BIAS:
- if (ctx->API != API_OPENGL_COMPAT)
+ if (_mesa_is_gles(ctx))
goto invalid_pname;
*params = obj->Sampler.LodBias;
break;
case GL_TEXTURE_IMMUTABLE_FORMAT:
- if (!ctx->Extensions.ARB_texture_storage)
- goto invalid_pname;
*params = (GLfloat) obj->Immutable;
break;
case GL_TEXTURE_IMMUTABLE_LEVELS:
- if (!_mesa_is_gles3(ctx))
+ if (_mesa_is_gles3(ctx) ||
+ (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view))
+ *params = (GLfloat) obj->ImmutableLevels;
+ else
+ goto invalid_pname;
+ break;
+
+ case GL_TEXTURE_VIEW_MIN_LEVEL:
+ if (!ctx->Extensions.ARB_texture_view)
+ goto invalid_pname;
+ *params = (GLfloat) obj->MinLevel;
+ break;
+
+ case GL_TEXTURE_VIEW_NUM_LEVELS:
+ if (!ctx->Extensions.ARB_texture_view)
+ goto invalid_pname;
+ *params = (GLfloat) obj->NumLevels;
+ break;
+
+ case GL_TEXTURE_VIEW_MIN_LAYER:
+ if (!ctx->Extensions.ARB_texture_view)
+ goto invalid_pname;
+ *params = (GLfloat) obj->MinLayer;
+ break;
+
+ case GL_TEXTURE_VIEW_NUM_LAYERS:
+ if (!ctx->Extensions.ARB_texture_view)
goto invalid_pname;
- *params = (GLfloat) obj->ImmutableLevels;
+ *params = (GLfloat) obj->NumLayers;
break;
case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
goto invalid_pname;
- *params = obj->RequiredTextureImageUnits;
+ *params = (GLfloat) obj->RequiredTextureImageUnits;
break;
case GL_TEXTURE_SRGB_DECODE_EXT:
goto invalid_pname;
*params = (GLint) obj->DepthMode;
break;
+ case GL_DEPTH_STENCIL_TEXTURE_MODE:
+ if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_stencil_texturing)
+ goto invalid_pname;
+ *params = (GLint)
+ (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT);
+ break;
case GL_TEXTURE_LOD_BIAS:
- if (ctx->API != API_OPENGL_COMPAT)
+ if (_mesa_is_gles(ctx))
goto invalid_pname;
- *params = (GLint) obj->Sampler.LodBias;
+ /* GL spec 'Data Conversions' section specifies that floating-point
+ * value in integer Get function is rounded to nearest integer
+ */
+ *params = IROUND(obj->Sampler.LodBias);
break;
case GL_TEXTURE_CROP_RECT_OES:
if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
break;
case GL_TEXTURE_IMMUTABLE_FORMAT:
- if (!ctx->Extensions.ARB_texture_storage)
- goto invalid_pname;
*params = (GLint) obj->Immutable;
break;
case GL_TEXTURE_IMMUTABLE_LEVELS:
- if (!_mesa_is_gles3(ctx))
+ if (_mesa_is_gles3(ctx) ||
+ (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view))
+ *params = obj->ImmutableLevels;
+ else
+ goto invalid_pname;
+ break;
+
+ case GL_TEXTURE_VIEW_MIN_LEVEL:
+ if (!ctx->Extensions.ARB_texture_view)
goto invalid_pname;
- *params = obj->ImmutableLevels;
+ *params = (GLint) obj->MinLevel;
+ break;
+
+ case GL_TEXTURE_VIEW_NUM_LEVELS:
+ if (!ctx->Extensions.ARB_texture_view)
+ goto invalid_pname;
+ *params = (GLint) obj->NumLevels;
+ break;
+
+ case GL_TEXTURE_VIEW_MIN_LAYER:
+ if (!ctx->Extensions.ARB_texture_view)
+ goto invalid_pname;
+ *params = (GLint) obj->MinLayer;
+ break;
+
+ case GL_TEXTURE_VIEW_NUM_LAYERS:
+ if (!ctx->Extensions.ARB_texture_view)
+ goto invalid_pname;
+ *params = (GLint) obj->NumLayers;
break;
case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
*params = obj->Sampler.sRGBDecode;
break;
+ case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
+ if (!ctx->Extensions.ARB_shader_image_load_store)
+ goto invalid_pname;
+ *params = obj->ImageFormatCompatibilityType;
+ break;
+
default:
goto invalid_pname;
}
texObj = get_texobj(ctx, target, GL_TRUE);
if (!texObj)
return;
-
+
switch (pname) {
case GL_TEXTURE_BORDER_COLOR:
COPY_4V(params, texObj->Sampler.BorderColor.i);
texObj = get_texobj(ctx, target, GL_TRUE);
if (!texObj)
return;
-
+
switch (pname) {
case GL_TEXTURE_BORDER_COLOR:
COPY_4V(params, texObj->Sampler.BorderColor.i);
GLint ip[4];
_mesa_GetTexParameteriv(target, pname, ip);
params[0] = ip[0];
- if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT ||
+ if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT ||
pname == GL_TEXTURE_CROP_RECT_OES) {
params[1] = ip[1];
params[2] = ip[2];