/*
* 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
#include <stdbool.h>
#include "main/glheader.h"
+#include "main/blend.h"
#include "main/colormac.h"
#include "main/context.h"
#include "main/enums.h"
#include "main/formats.h"
#include "main/glformats.h"
#include "main/macros.h"
-#include "main/mfeatures.h"
#include "main/mtypes.h"
#include "main/state.h"
#include "main/texcompress.h"
* 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;
+ const bool is_desktop_gl = _mesa_is_desktop_gl(ctx);
bool supported;
switch (wrap) {
case GL_CLAMP:
- supported = (target != GL_TEXTURE_EXTERNAL_OES);
+ /* GL_CLAMP was removed in the core profile, and it has never existed in
+ * OpenGL ES.
+ */
+ supported = (ctx->API == API_OPENGL_COMPAT)
+ && (target != GL_TEXTURE_EXTERNAL_OES);
break;
case GL_CLAMP_TO_EDGE:
break;
case GL_CLAMP_TO_BORDER:
- supported = e->ARB_texture_border_clamp
+ supported = is_desktop_gl && e->ARB_texture_border_clamp
&& (target != GL_TEXTURE_EXTERNAL_OES);
break;
break;
case GL_MIRROR_CLAMP_EXT:
+ supported = is_desktop_gl
+ && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)
+ && (target != GL_TEXTURE_RECTANGLE_NV)
+ && (target != GL_TEXTURE_EXTERNAL_OES);
+ break;
+
case GL_MIRROR_CLAMP_TO_EDGE_EXT:
- supported = (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)
- && (target != GL_TEXTURE_RECTANGLE_NV)
+ 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 = e->EXT_texture_mirror_clamp
- && (target != GL_TEXTURE_RECTANGLE_NV)
+ supported = is_desktop_gl && e->EXT_texture_mirror_clamp
+ && (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:
- return texUnit->CurrentTex[TEXTURE_1D_INDEX];
- case GL_TEXTURE_2D:
- return texUnit->CurrentTex[TEXTURE_2D_INDEX];
- case GL_TEXTURE_3D:
- return texUnit->CurrentTex[TEXTURE_3D_INDEX];
- 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 (ctx->Extensions.NV_texture_rectangle) {
- return texUnit->CurrentTex[TEXTURE_RECT_INDEX];
- }
- break;
- case GL_TEXTURE_1D_ARRAY_EXT:
- if (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 (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array) {
- return texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX];
- }
- break;
- case GL_TEXTURE_EXTERNAL_OES:
- if (ctx->Extensions.OES_EGL_image_external) {
- return texUnit->CurrentTex[TEXTURE_EXTERNAL_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);
+}
+
+
+static GLboolean
+target_allows_setting_sampler_parameters(GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return GL_FALSE;
+
+ default:
+ return GL_TRUE;
+ }
}
{
switch (pname) {
case GL_TEXTURE_MIN_FILTER:
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.MinFilter == params[0])
return GL_FALSE;
switch (params[0]) {
return GL_FALSE;
case GL_TEXTURE_MAG_FILTER:
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.MagFilter == params[0])
return GL_FALSE;
switch (params[0]) {
return GL_FALSE;
case GL_TEXTURE_WRAP_S:
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.WrapS == params[0])
return GL_FALSE;
if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
return GL_FALSE;
case GL_TEXTURE_WRAP_T:
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.WrapT == params[0])
return GL_FALSE;
if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
return GL_FALSE;
case GL_TEXTURE_WRAP_R:
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.WrapR == params[0])
return GL_FALSE;
if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
return GL_FALSE;
case GL_TEXTURE_BASE_LEVEL:
+ if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
+ goto invalid_pname;
+
if (texObj->BaseLevel == params[0])
return GL_FALSE;
+
+ if ((texObj->Target == GL_TEXTURE_2D_MULTISAMPLE ||
+ texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) && params[0] != 0)
+ goto invalid_operation;
+
if (params[0] < 0 ||
(texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) {
_mesa_error(ctx, GL_INVALID_VALUE,
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) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
+
+ 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:
+ if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
+ goto invalid_pname;
+
if (params[0] && texObj->Target == GL_TEXTURE_EXTERNAL_OES)
goto invalid_param;
if (texObj->GenerateMipmap != params[0]) {
return GL_FALSE;
case GL_TEXTURE_COMPARE_MODE_ARB:
- if (ctx->Extensions.ARB_shadow) {
+ if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow)
+ || _mesa_is_gles3(ctx)) {
+
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.CompareMode == params[0])
return GL_FALSE;
if (params[0] == GL_NONE ||
goto invalid_pname;
case GL_TEXTURE_COMPARE_FUNC_ARB:
- if (ctx->Extensions.ARB_shadow) {
+ if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow)
+ || _mesa_is_gles3(ctx)) {
+
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.CompareFunc == params[0])
return GL_FALSE;
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_TEXTURE_MODE_ARB:
- if (ctx->Extensions.ARB_depth_texture) {
+ /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has never
+ * existed in OpenGL ES.
+ */
+ if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_depth_texture) {
if (texObj->DepthMode == params[0])
return GL_FALSE;
if (params[0] == GL_LUMINANCE ||
}
goto invalid_pname;
-#if FEATURE_OES_draw_texture
+ 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;
+
texObj->CropRect[0] = params[0];
texObj->CropRect[1] = params[1];
texObj->CropRect[2] = params[2];
texObj->CropRect[3] = params[3];
return GL_TRUE;
-#endif
case GL_TEXTURE_SWIZZLE_R_EXT:
case GL_TEXTURE_SWIZZLE_G_EXT:
case GL_TEXTURE_SWIZZLE_B_EXT:
case GL_TEXTURE_SWIZZLE_A_EXT:
- if (ctx->Extensions.EXT_texture_swizzle) {
+ if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle)
+ || _mesa_is_gles3(ctx)) {
const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
const GLint swz = comp_to_swizzle(params[0]);
if (swz < 0) {
goto invalid_pname;
case GL_TEXTURE_SWIZZLE_RGBA_EXT:
- if (ctx->Extensions.EXT_texture_swizzle) {
+ if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle)
+ || _mesa_is_gles3(ctx)) {
GLuint comp;
flush(ctx);
for (comp = 0; comp < 4; comp++) {
goto invalid_pname;
case GL_TEXTURE_SRGB_DECODE_EXT:
- if (ctx->Extensions.EXT_texture_sRGB_decode) {
- GLenum decode = params[0];
+ if (_mesa_is_desktop_gl(ctx)
+ && ctx->Extensions.EXT_texture_sRGB_decode) {
+ GLenum decode = params[0];
+
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) {
if (texObj->Sampler.sRGBDecode != decode) {
flush(ctx);
goto invalid_pname;
case GL_TEXTURE_CUBE_MAP_SEAMLESS:
- if (ctx->Extensions.AMD_seamless_cubemap_per_texture) {
+ if (_mesa_is_desktop_gl(ctx)
+ && ctx->Extensions.AMD_seamless_cubemap_per_texture) {
GLenum param = params[0];
+
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (param != GL_TRUE && param != GL_FALSE) {
goto invalid_param;
}
_mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param=%s)",
_mesa_lookup_enum_by_nr(params[0]));
return GL_FALSE;
+
+invalid_operation:
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)",
+ _mesa_lookup_enum_by_nr(pname));
+ return GL_FALSE;
}
{
switch (pname) {
case GL_TEXTURE_MIN_LOD:
+ if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
+ goto invalid_pname;
+
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.MinLod == params[0])
return GL_FALSE;
flush(ctx);
return GL_TRUE;
case GL_TEXTURE_MAX_LOD:
+ if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
+ goto invalid_pname;
+
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.MaxLod == params[0])
return GL_FALSE;
flush(ctx);
return GL_TRUE;
case GL_TEXTURE_PRIORITY:
+ if (ctx->API != API_OPENGL_COMPAT)
+ goto invalid_pname;
+
flush(ctx);
texObj->Priority = CLAMP(params[0], 0.0F, 1.0F);
return GL_TRUE;
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (ctx->Extensions.EXT_texture_filter_anisotropic) {
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.MaxAnisotropy == params[0])
return GL_FALSE;
if (params[0] < 1.0) {
else {
static GLuint count = 0;
if (count++ < 10)
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
+ 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 */
+ /* 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))
+ goto invalid_operation;
+
if (texObj->Sampler.LodBias != params[0]) {
flush(ctx);
texObj->Sampler.LodBias = params[0];
break;
case GL_TEXTURE_BORDER_COLOR:
+ if (!_mesa_is_desktop_gl(ctx))
+ goto invalid_pname;
+
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
flush(ctx);
/* ARB_texture_float disables clamping */
if (ctx->Extensions.ARB_texture_float) {
return GL_TRUE;
default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
+ goto invalid_pname;
}
return GL_FALSE;
+
+invalid_pname:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)",
+ _mesa_lookup_enum_by_nr(pname));
+ return GL_FALSE;
+
+invalid_operation:
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)",
+ _mesa_lookup_enum_by_nr(pname));
+ return GL_FALSE;
}
GLboolean need_update;
struct gl_texture_object *texObj;
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
texObj = get_texobj(ctx, target, GL_FALSE);
if (!texObj)
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:
- {
- /* convert float param to int */
- GLint p[4];
- p[0] = (GLint) param;
- p[1] = p[2] = p[3] = 0;
- need_update = set_tex_parameteri(ctx, texObj, pname, p);
- }
- break;
case GL_TEXTURE_SWIZZLE_R_EXT:
case GL_TEXTURE_SWIZZLE_G_EXT:
case GL_TEXTURE_SWIZZLE_B_EXT:
case GL_TEXTURE_SWIZZLE_A_EXT:
{
GLint p[4];
- p[0] = (GLint) param;
+ p[0] = (param > 0) ?
+ ((param > INT_MAX) ? INT_MAX : (GLint) (param + 0.5)) :
+ ((param < INT_MIN) ? INT_MIN : (GLint) (param - 0.5));
+
p[1] = p[2] = p[3] = 0;
need_update = set_tex_parameteri(ctx, texObj, pname, p);
}
}
if (ctx->Driver.TexParameter && need_update) {
- ctx->Driver.TexParameter(ctx, target, texObj, pname, ¶m);
+ ctx->Driver.TexParameter(ctx, texObj, pname, ¶m);
}
}
GLboolean need_update;
struct gl_texture_object *texObj;
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
texObj = get_texobj(ctx, target, GL_FALSE);
if (!texObj)
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:
{
need_update = set_tex_parameteri(ctx, texObj, pname, p);
}
break;
-
-#if FEATURE_OES_draw_texture
case GL_TEXTURE_CROP_RECT_OES:
{
/* convert float params to int */
need_update = set_tex_parameteri(ctx, texObj, pname, iparams);
}
break;
-#endif
-
case GL_TEXTURE_SWIZZLE_R_EXT:
case GL_TEXTURE_SWIZZLE_G_EXT:
case GL_TEXTURE_SWIZZLE_B_EXT:
}
if (ctx->Driver.TexParameter && need_update) {
- ctx->Driver.TexParameter(ctx, target, texObj, pname, params);
+ ctx->Driver.TexParameter(ctx, texObj, pname, params);
}
}
GLboolean need_update;
struct gl_texture_object *texObj;
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
texObj = get_texobj(ctx, target, GL_FALSE);
if (!texObj)
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);
}
}
GLboolean need_update;
struct gl_texture_object *texObj;
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
texObj = get_texobj(ctx, target, GL_FALSE);
if (!texObj)
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);
}
}
{
struct gl_texture_object *texObj;
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
texObj = get_texobj(ctx, target, GL_FALSE);
if (!texObj)
{
struct gl_texture_object *texObj;
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
texObj = get_texobj(ctx, target, GL_FALSE);
if (!texObj)
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.
* From the OpenGL 3.1 spec:
* "target may also be TEXTURE_BUFFER, indicating the texture buffer."
*/
- return _mesa_is_desktop_gl(ctx) && ctx->Version >= 31;
+ 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 */
*params = GL_NONE;
break;
+ /* GL_ARB_texture_multisample */
+ case GL_TEXTURE_SAMPLES:
+ if (!ctx->Extensions.ARB_texture_multisample)
+ goto invalid_pname;
+ *params = img->NumSamples;
+ break;
+
+ case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
+ if (!ctx->Extensions.ARB_texture_multisample)
+ goto invalid_pname;
+ *params = img->FixedSampleLocations;
+ break;
+
default:
goto invalid_pname;
}
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);
*params = _mesa_get_format_bits(texFormat, pname);
break;
+ /* GL_ARB_texture_buffer_range */
+ case GL_TEXTURE_BUFFER_OFFSET:
+ if (!ctx->Extensions.ARB_texture_buffer_range)
+ goto invalid_pname;
+ *params = texObj->BufferOffset;
+ break;
+ case GL_TEXTURE_BUFFER_SIZE:
+ if (!ctx->Extensions.ARB_texture_buffer_range)
+ goto invalid_pname;
+ *params = (texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize;
+ break;
+
/* GL_ARB_texture_compression */
case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
/* Always illegal for GL_TEXTURE_BUFFER */
_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);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
_mesa_error(ctx, GL_INVALID_OPERATION,
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);
{
struct gl_texture_object *obj;
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
obj = get_texobj(ctx, target, GL_TRUE);
if (!obj)
*params = ENUM_TO_FLOAT(obj->Sampler.WrapR);
break;
case GL_TEXTURE_BORDER_COLOR:
+ if (!_mesa_is_desktop_gl(ctx))
+ goto invalid_pname;
+
if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
_mesa_update_state_locked(ctx);
- if (ctx->Color._ClampFragmentColor) {
+ if (_mesa_get_clamp_fragment_color(ctx)) {
params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
}
break;
case GL_TEXTURE_RESIDENT:
+ if (ctx->API != API_OPENGL_COMPAT)
+ goto invalid_pname;
+
*params = 1.0F;
break;
case GL_TEXTURE_PRIORITY:
+ if (ctx->API != API_OPENGL_COMPAT)
+ goto invalid_pname;
+
*params = obj->Priority;
break;
case GL_TEXTURE_MIN_LOD:
+ if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
+ goto invalid_pname;
+
*params = obj->Sampler.MinLod;
break;
case GL_TEXTURE_MAX_LOD:
+ if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
+ goto invalid_pname;
+
*params = obj->Sampler.MaxLod;
break;
case GL_TEXTURE_BASE_LEVEL:
+ if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
+ goto invalid_pname;
+
*params = (GLfloat) obj->BaseLevel;
break;
case GL_TEXTURE_MAX_LEVEL:
*params = obj->Sampler.MaxAnisotropy;
break;
case GL_GENERATE_MIPMAP_SGIS:
+ if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
+ goto invalid_pname;
+
*params = (GLfloat) obj->GenerateMipmap;
break;
case GL_TEXTURE_COMPARE_MODE_ARB:
- if (!ctx->Extensions.ARB_shadow)
+ if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
+ && !_mesa_is_gles3(ctx))
goto invalid_pname;
*params = (GLfloat) obj->Sampler.CompareMode;
break;
case GL_TEXTURE_COMPARE_FUNC_ARB:
- if (!ctx->Extensions.ARB_shadow)
+ if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
+ && !_mesa_is_gles3(ctx))
goto invalid_pname;
*params = (GLfloat) obj->Sampler.CompareFunc;
break;
case GL_DEPTH_TEXTURE_MODE_ARB:
- if (!ctx->Extensions.ARB_depth_texture)
+ /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has
+ * never existed in OpenGL ES.
+ */
+ if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
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 (_mesa_is_gles(ctx))
+ goto invalid_pname;
+
*params = obj->Sampler.LodBias;
break;
-#if FEATURE_OES_draw_texture
case GL_TEXTURE_CROP_RECT_OES:
- params[0] = obj->CropRect[0];
- params[1] = obj->CropRect[1];
- params[2] = obj->CropRect[2];
- params[3] = obj->CropRect[3];
+ if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
+ goto invalid_pname;
+
+ params[0] = (GLfloat) obj->CropRect[0];
+ params[1] = (GLfloat) obj->CropRect[1];
+ params[2] = (GLfloat) obj->CropRect[2];
+ params[3] = (GLfloat) obj->CropRect[3];
break;
-#endif
case GL_TEXTURE_SWIZZLE_R_EXT:
case GL_TEXTURE_SWIZZLE_G_EXT:
case GL_TEXTURE_SWIZZLE_B_EXT:
case GL_TEXTURE_SWIZZLE_A_EXT:
- if (!ctx->Extensions.EXT_texture_swizzle)
+ if ((!_mesa_is_desktop_gl(ctx)
+ || !ctx->Extensions.EXT_texture_swizzle)
+ && !_mesa_is_gles3(ctx))
goto invalid_pname;
*params = (GLfloat) obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
break;
case GL_TEXTURE_SWIZZLE_RGBA_EXT:
- if (!ctx->Extensions.EXT_texture_swizzle) {
+ if ((!_mesa_is_desktop_gl(ctx)
+ || !ctx->Extensions.EXT_texture_swizzle)
+ && !_mesa_is_gles3(ctx)) {
goto invalid_pname;
}
else {
break;
case GL_TEXTURE_CUBE_MAP_SEAMLESS:
- if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
+ if (!_mesa_is_desktop_gl(ctx)
+ || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
goto invalid_pname;
*params = (GLfloat) obj->Sampler.CubeMapSeamless;
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) ||
+ (_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->NumLayers;
+ break;
+
+ case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
+ if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
+ goto invalid_pname;
+ *params = (GLfloat) obj->RequiredTextureImageUnits;
+ break;
+
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ if (!ctx->Extensions.EXT_texture_sRGB_decode)
+ goto invalid_pname;
+ *params = (GLfloat) obj->Sampler.sRGBDecode;
+ break;
+
default:
goto invalid_pname;
}
{
struct gl_texture_object *obj;
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
obj = get_texobj(ctx, target, GL_TRUE);
if (!obj)
*params = (GLint) obj->Sampler.WrapR;
break;
case GL_TEXTURE_BORDER_COLOR:
+ if (!_mesa_is_desktop_gl(ctx))
+ goto invalid_pname;
+
{
GLfloat b[4];
b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
}
break;
case GL_TEXTURE_RESIDENT:
+ if (ctx->API != API_OPENGL_COMPAT)
+ goto invalid_pname;
+
*params = 1;
break;
case GL_TEXTURE_PRIORITY:
+ if (ctx->API != API_OPENGL_COMPAT)
+ goto invalid_pname;
+
*params = FLOAT_TO_INT(obj->Priority);
break;
case GL_TEXTURE_MIN_LOD:
+ if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
+ goto invalid_pname;
+
*params = (GLint) obj->Sampler.MinLod;
break;
case GL_TEXTURE_MAX_LOD:
+ if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
+ goto invalid_pname;
+
*params = (GLint) obj->Sampler.MaxLod;
break;
case GL_TEXTURE_BASE_LEVEL:
+ if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
+ goto invalid_pname;
+
*params = obj->BaseLevel;
break;
case GL_TEXTURE_MAX_LEVEL:
*params = (GLint) obj->Sampler.MaxAnisotropy;
break;
case GL_GENERATE_MIPMAP_SGIS:
+ if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
+ goto invalid_pname;
+
*params = (GLint) obj->GenerateMipmap;
break;
case GL_TEXTURE_COMPARE_MODE_ARB:
- if (!ctx->Extensions.ARB_shadow)
+ if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
+ && !_mesa_is_gles3(ctx))
goto invalid_pname;
*params = (GLint) obj->Sampler.CompareMode;
break;
case GL_TEXTURE_COMPARE_FUNC_ARB:
- if (!ctx->Extensions.ARB_shadow)
+ if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
+ && !_mesa_is_gles3(ctx))
goto invalid_pname;
*params = (GLint) obj->Sampler.CompareFunc;
break;
case GL_DEPTH_TEXTURE_MODE_ARB:
- if (!ctx->Extensions.ARB_depth_texture)
+ if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
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:
- *params = (GLint) obj->Sampler.LodBias;
+ if (_mesa_is_gles(ctx))
+ goto invalid_pname;
+
+ /* 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;
-#if FEATURE_OES_draw_texture
case GL_TEXTURE_CROP_RECT_OES:
+ if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
+ goto invalid_pname;
+
params[0] = obj->CropRect[0];
params[1] = obj->CropRect[1];
params[2] = obj->CropRect[2];
params[3] = obj->CropRect[3];
break;
-#endif
case GL_TEXTURE_SWIZZLE_R_EXT:
case GL_TEXTURE_SWIZZLE_G_EXT:
case GL_TEXTURE_SWIZZLE_B_EXT:
case GL_TEXTURE_SWIZZLE_A_EXT:
- if (!ctx->Extensions.EXT_texture_swizzle)
+ if ((!_mesa_is_desktop_gl(ctx)
+ || !ctx->Extensions.EXT_texture_swizzle)
+ && !_mesa_is_gles3(ctx))
goto invalid_pname;
*params = obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
break;
case GL_TEXTURE_SWIZZLE_RGBA_EXT:
- if (!ctx->Extensions.EXT_texture_swizzle)
+ if ((!_mesa_is_desktop_gl(ctx)
+ || !ctx->Extensions.EXT_texture_swizzle)
+ && !_mesa_is_gles3(ctx))
goto invalid_pname;
COPY_4V(params, obj->Swizzle);
break;
case GL_TEXTURE_CUBE_MAP_SEAMLESS:
- if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
+ if (!_mesa_is_desktop_gl(ctx)
+ || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
goto invalid_pname;
*params = (GLint) obj->Sampler.CubeMapSeamless;
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) ||
+ (_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 = (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:
- if (!ctx->Extensions.OES_EGL_image_external)
+ if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
goto invalid_pname;
*params = obj->RequiredTextureImageUnits;
break;
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ if (!ctx->Extensions.EXT_texture_sRGB_decode)
+ goto invalid_pname;
+ *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;
}
{
struct gl_texture_object *texObj;
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
texObj = get_texobj(ctx, target, GL_TRUE);
if (!texObj)
return;
-
+
switch (pname) {
case GL_TEXTURE_BORDER_COLOR:
COPY_4V(params, texObj->Sampler.BorderColor.i);
{
struct gl_texture_object *texObj;
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
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];