X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Ftexparam.c;h=c642f4569928195d94cf3ba7c04b438e78b78e0e;hb=c2d6f61f26c60f1cd2c61c4e350d38015660c2fd;hp=c0611c3e489e527501403c1c37d5226c6f2db807;hpb=a4bde371c7172fd775dea4377f9bccc3a38992c0;p=mesa.git diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index c0611c3e489..c642f456992 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -72,7 +72,7 @@ validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap) break; case GL_CLAMP_TO_BORDER: - supported = is_desktop_gl && e->ARB_texture_border_clamp + supported = ctx->API != API_OPENGLES && e->ARB_texture_border_clamp && (target != GL_TEXTURE_EXTERNAL_OES); break; @@ -114,38 +114,27 @@ validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap) } -/** - * Get current texture object for given target. - * Return NULL if any error (and record the error). - * 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_by_target(struct gl_context *ctx, GLenum target, GLboolean get) +static bool +is_texparameteri_target_valid(GLenum target) { - struct gl_texture_unit *texUnit; - int targetIndex; - - if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "gl%sTexParameter(current unit)", get ? "Get" : ""); - return NULL; - } - - texUnit = _mesa_get_current_tex_unit(ctx); - - 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; + switch (target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_1D_ARRAY: + case GL_TEXTURE_2D: + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_2D_MULTISAMPLE: + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + case GL_TEXTURE_3D: + case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_TEXTURE_RECTANGLE: + return true; + default: + return false; } - assert(targetIndex < NUM_TEXTURE_TARGETS); - - return texUnit->CurrentTex[targetIndex]; } + /** * Get current texture object for given name. * Return NULL if any error (and record the error). @@ -153,37 +142,20 @@ get_texobj_by_target(struct gl_context *ctx, GLenum target, GLboolean get) * Only the glGetTexLevelParameter() functions accept proxy targets. */ static struct gl_texture_object * -get_texobj_by_name(struct gl_context *ctx, GLuint texture, GLboolean get) +get_texobj_by_name(struct gl_context *ctx, GLuint texture, const char *name) { struct gl_texture_object *texObj; - texObj = _mesa_lookup_texture(ctx, texture); - if (!texObj) { - /* - * User passed a non-generated name. - * Throw the error in the caller. - */ + texObj = _mesa_lookup_texture_err(ctx, texture, name); + if (!texObj) return NULL; - } - switch (texObj->Target) { - case GL_TEXTURE_1D: - case GL_TEXTURE_1D_ARRAY: - case GL_TEXTURE_2D: - case GL_TEXTURE_2D_ARRAY: - case GL_TEXTURE_2D_MULTISAMPLE: - case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: - case GL_TEXTURE_3D: - case GL_TEXTURE_CUBE_MAP: - case GL_TEXTURE_CUBE_MAP_ARRAY: - case GL_TEXTURE_RECTANGLE: - return texObj; - default: - _mesa_error(ctx, GL_INVALID_ENUM, - "gl%sTextureParameter(target)", get ? "Get" : ""); + if (!is_texparameteri_target_valid(texObj->Target)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(target)", name); return NULL; } + return texObj; } @@ -214,7 +186,7 @@ comp_to_swizzle(GLenum comp) static void -set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz) +set_swizzle_component(GLushort *swizzle, GLuint comp, GLuint swz) { assert(comp < 4); assert(swz <= SWIZZLE_NIL); @@ -233,27 +205,27 @@ set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz) static inline void flush(struct gl_context *ctx) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE); + FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT); } /** * This is called just prior to changing any texture object state which * could affect texture completeness (texture base level, max level). - * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE + * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE_OBJECT * state flag and then mark the texture object as 'incomplete' so that any * per-texture derived state gets recomputed. */ static inline void incomplete(struct gl_context *ctx, struct gl_texture_object *texObj) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE); + FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT); _mesa_dirty_texobj(ctx, texObj); } -static GLboolean -target_allows_setting_sampler_parameters(GLenum target) +GLboolean +_mesa_target_allows_setting_sampler_parameters(GLenum target) { switch (target) { case GL_TEXTURE_2D_MULTISAMPLE: @@ -277,9 +249,22 @@ set_tex_parameteri(struct gl_context *ctx, { const char *suffix = dsa ? "ture" : ""; + if (texObj->HandleAllocated) { + /* The ARB_bindless_texture spec says: + * + * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*, + * CompressedTexImage*, TexBuffer*, TexParameter*, as well as other + * functions defined in terms of these, if the texture object to be + * modified is referenced by one or more texture or image handles." + */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTex%sParameter(immutable texture)", suffix); + return GL_FALSE; + } + switch (pname) { case GL_TEXTURE_MIN_FILTER: - if (!target_allows_setting_sampler_parameters(texObj->Target)) + if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) goto invalid_enum; if (texObj->Sampler.MinFilter == params[0]) @@ -307,7 +292,7 @@ set_tex_parameteri(struct gl_context *ctx, return GL_FALSE; case GL_TEXTURE_MAG_FILTER: - if (!target_allows_setting_sampler_parameters(texObj->Target)) + if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) goto invalid_enum; if (texObj->Sampler.MagFilter == params[0]) @@ -324,7 +309,7 @@ set_tex_parameteri(struct gl_context *ctx, return GL_FALSE; case GL_TEXTURE_WRAP_S: - if (!target_allows_setting_sampler_parameters(texObj->Target)) + if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) goto invalid_enum; if (texObj->Sampler.WrapS == params[0]) @@ -337,7 +322,7 @@ set_tex_parameteri(struct gl_context *ctx, return GL_FALSE; case GL_TEXTURE_WRAP_T: - if (!target_allows_setting_sampler_parameters(texObj->Target)) + if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) goto invalid_enum; if (texObj->Sampler.WrapT == params[0]) @@ -350,7 +335,7 @@ set_tex_parameteri(struct gl_context *ctx, return GL_FALSE; case GL_TEXTURE_WRAP_R: - if (!target_allows_setting_sampler_parameters(texObj->Target)) + if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) goto invalid_enum; if (texObj->Sampler.WrapR == params[0]) @@ -369,8 +354,26 @@ set_tex_parameteri(struct gl_context *ctx, if (texObj->BaseLevel == params[0]) return GL_FALSE; + /* Section 8.10 (Texture Parameters) of the OpenGL 4.5 Core Profile spec + * says: + * + * An INVALID_OPERATION error is generated if the effective target is + * TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY, or + * TEXTURE_RECTANGLE, and pname TEXTURE_BASE_LEVEL is set to a value + * other than zero. + * + * Note that section 3.8.8 (Texture Parameters) of the OpenGL 3.3 Core + * Profile spec said: + * + * The error INVALID_VALUE is generated if TEXTURE_BASE_LEVEL is set + * to any value other than zero. + * + * We take the 4.5 language as a correction to 3.3, and we implement + * that on all GL versions. + */ if ((texObj->Target == GL_TEXTURE_2D_MULTISAMPLE || - texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) && params[0] != 0) + texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || + texObj->Target == GL_TEXTURE_RECTANGLE) && params[0] != 0) goto invalid_operation; if (params[0] < 0) { @@ -378,12 +381,6 @@ set_tex_parameteri(struct gl_context *ctx, "glTex%sParameter(param=%d)", suffix, params[0]); return GL_FALSE; } - if (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glTex%sParameter(target=%s, param=%d)", suffix, - _mesa_enum_to_string(texObj->Target), params[0]); - return GL_FALSE; - } incomplete(ctx, texObj); /** See note about ARB_texture_storage below */ @@ -438,7 +435,7 @@ set_tex_parameteri(struct gl_context *ctx, if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow) || _mesa_is_gles3(ctx)) { - if (!target_allows_setting_sampler_parameters(texObj->Target)) + if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) goto invalid_enum; if (texObj->Sampler.CompareMode == params[0]) @@ -457,7 +454,7 @@ set_tex_parameteri(struct gl_context *ctx, if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow) || _mesa_is_gles3(ctx)) { - if (!target_allows_setting_sampler_parameters(texObj->Target)) + if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) goto invalid_enum; if (texObj->Sampler.CompareFunc == params[0]) @@ -500,9 +497,7 @@ set_tex_parameteri(struct gl_context *ctx, goto invalid_pname; case GL_DEPTH_STENCIL_TEXTURE_MODE: - if ((_mesa_is_desktop_gl(ctx) && - ctx->Extensions.ARB_stencil_texturing) || - _mesa_is_gles31(ctx)) { + if (_mesa_has_ARB_stencil_texturing(ctx) || _mesa_is_gles31(ctx)) { bool stencil = params[0] == GL_STENCIL_INDEX; if (!stencil && params[0] != GL_DEPTH_COMPONENT) goto invalid_param; @@ -570,11 +565,10 @@ set_tex_parameteri(struct gl_context *ctx, goto invalid_pname; case GL_TEXTURE_SRGB_DECODE_EXT: - if (_mesa_is_desktop_gl(ctx) - && ctx->Extensions.EXT_texture_sRGB_decode) { + if (ctx->Extensions.EXT_texture_sRGB_decode) { GLenum decode = params[0]; - if (!target_allows_setting_sampler_parameters(texObj->Target)) + if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) goto invalid_enum; if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) { @@ -592,7 +586,7 @@ set_tex_parameteri(struct gl_context *ctx, && ctx->Extensions.AMD_seamless_cubemap_per_texture) { GLenum param = params[0]; - if (!target_allows_setting_sampler_parameters(texObj->Target)) + if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) goto invalid_enum; if (param != GL_TRUE && param != GL_FALSE) { @@ -606,6 +600,14 @@ set_tex_parameteri(struct gl_context *ctx, } goto invalid_pname; + case GL_TEXTURE_TILING_EXT: + if (ctx->Extensions.EXT_memory_object) { + texObj->TextureTiling = params[0]; + + return GL_TRUE; + } + goto invalid_pname; + default: goto invalid_pname; } @@ -643,12 +645,25 @@ set_tex_parameterf(struct gl_context *ctx, { const char *suffix = dsa ? "ture" : ""; + if (texObj->HandleAllocated) { + /* The ARB_bindless_texture spec says: + * + * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*, + * CompressedTexImage*, TexBuffer*, TexParameter*, as well as other + * functions defined in terms of these, if the texture object to be + * modified is referenced by one or more texture or image handles." + */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTex%sParameter(immutable texture)", suffix); + 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)) + if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) goto invalid_enum; if (texObj->Sampler.MinLod == params[0]) @@ -661,7 +676,7 @@ set_tex_parameterf(struct gl_context *ctx, if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_pname; - if (!target_allows_setting_sampler_parameters(texObj->Target)) + if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) goto invalid_enum; if (texObj->Sampler.MaxLod == params[0]) @@ -680,7 +695,7 @@ set_tex_parameterf(struct gl_context *ctx, case GL_TEXTURE_MAX_ANISOTROPY_EXT: if (ctx->Extensions.EXT_texture_filter_anisotropic) { - if (!target_allows_setting_sampler_parameters(texObj->Target)) + if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) goto invalid_enum; if (texObj->Sampler.MaxAnisotropy == params[0]) @@ -708,7 +723,7 @@ set_tex_parameterf(struct gl_context *ctx, if (_mesa_is_gles(ctx)) goto invalid_pname; - if (!target_allows_setting_sampler_parameters(texObj->Target)) + if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) goto invalid_enum; if (texObj->Sampler.LodBias != params[0]) { @@ -719,10 +734,19 @@ set_tex_parameterf(struct gl_context *ctx, break; case GL_TEXTURE_BORDER_COLOR: - if (!_mesa_is_desktop_gl(ctx)) + /* Border color exists in desktop OpenGL since 1.0 for GL_CLAMP. In + * OpenGL ES 2.0+, it only exists in when GL_OES_texture_border_clamp is + * enabled. It is never available in OpenGL ES 1.x. + * + * FIXME: Every driver that supports GLES2 has this extension. Elide + * the check? + */ + if (ctx->API == API_OPENGLES || + (ctx->API == API_OPENGLES2 && + !ctx->Extensions.ARB_texture_border_clamp)) goto invalid_pname; - if (!target_allows_setting_sampler_parameters(texObj->Target)) + if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) goto invalid_enum; flush(ctx); @@ -740,6 +764,13 @@ set_tex_parameterf(struct gl_context *ctx, } return GL_TRUE; + case GL_TEXTURE_TILING_EXT: + if (ctx->Extensions.EXT_memory_object) { + texObj->TextureTiling = params[0]; + return GL_TRUE; + } + goto invalid_pname; + default: goto invalid_pname; } @@ -809,7 +840,7 @@ _mesa_texture_parameterf(struct gl_context *ctx, } if (ctx->Driver.TexParameter && need_update) { - ctx->Driver.TexParameter(ctx, texObj, pname, ¶m); + ctx->Driver.TexParameter(ctx, texObj, pname); } } @@ -876,7 +907,7 @@ _mesa_texture_parameterfv(struct gl_context *ctx, } if (ctx->Driver.TexParameter && need_update) { - ctx->Driver.TexParameter(ctx, texObj, pname, params); + ctx->Driver.TexParameter(ctx, texObj, pname); } } @@ -921,8 +952,7 @@ _mesa_texture_parameteri(struct gl_context *ctx, } if (ctx->Driver.TexParameter && need_update) { - GLfloat fparam = (GLfloat) param; - ctx->Driver.TexParameter(ctx, texObj, pname, &fparam); + ctx->Driver.TexParameter(ctx, texObj, pname); } } @@ -966,15 +996,7 @@ _mesa_texture_parameteriv(struct gl_context *ctx, } if (ctx->Driver.TexParameter && need_update) { - GLfloat fparams[4]; - fparams[0] = INT_TO_FLOAT(params[0]); - if (pname == GL_TEXTURE_BORDER_COLOR || - pname == GL_TEXTURE_CROP_RECT_OES) { - fparams[1] = INT_TO_FLOAT(params[1]); - fparams[2] = INT_TO_FLOAT(params[2]); - fparams[3] = INT_TO_FLOAT(params[3]); - } - ctx->Driver.TexParameter(ctx, texObj, pname, fparams); + ctx->Driver.TexParameter(ctx, texObj, pname); } } @@ -985,7 +1007,17 @@ _mesa_texture_parameterIiv(struct gl_context *ctx, { switch (pname) { case GL_TEXTURE_BORDER_COLOR: - FLUSH_VERTICES(ctx, _NEW_TEXTURE); + if (texObj->HandleAllocated) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureParameterIiv(immutable texture)"); + return; + } + + if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTextureParameterIiv(texture)"); + return; + } + FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT); /* set the integer-valued border color */ COPY_4V(texObj->Sampler.BorderColor.i, params); break; @@ -1003,7 +1035,17 @@ _mesa_texture_parameterIuiv(struct gl_context *ctx, { switch (pname) { case GL_TEXTURE_BORDER_COLOR: - FLUSH_VERTICES(ctx, _NEW_TEXTURE); + if (texObj->HandleAllocated) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureParameterIuiv(immutable texture)"); + return; + } + + if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTextureParameterIuiv(texture)"); + return; + } + FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT); /* set the unsigned integer-valued border color */ COPY_4V(texObj->Sampler.BorderColor.ui, params); break; @@ -1021,7 +1063,10 @@ _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj_by_target(ctx, target, GL_FALSE); + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + ctx->Texture.CurrentUnit, + false, + "glTexParameterf"); if (!texObj) return; @@ -1034,7 +1079,10 @@ _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj_by_target(ctx, target, GL_FALSE); + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + ctx->Texture.CurrentUnit, + false, + "glTexParameterfv"); if (!texObj) return; @@ -1047,7 +1095,10 @@ _mesa_TexParameteri(GLenum target, GLenum pname, GLint param) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj_by_target(ctx, target, GL_FALSE); + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + ctx->Texture.CurrentUnit, + false, + "glTexParameteri"); if (!texObj) return; @@ -1060,7 +1111,10 @@ _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj_by_target(ctx, target, GL_FALSE); + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + ctx->Texture.CurrentUnit, + false, + "glTexParameteriv"); if (!texObj) return; @@ -1078,7 +1132,10 @@ _mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj_by_target(ctx, target, GL_FALSE); + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + ctx->Texture.CurrentUnit, + false, + "glTexParameterIiv"); if (!texObj) return; @@ -1096,13 +1153,34 @@ _mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj_by_target(ctx, target, GL_FALSE); + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + ctx->Texture.CurrentUnit, + false, + "glTexParameterIuiv"); if (!texObj) return; _mesa_texture_parameterIuiv(ctx, texObj, pname, params, false); } +void GLAPIENTRY +_mesa_TextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, const GLfloat *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glTextureParameterfvEXT"); + if (!texObj) + return; + + if (!is_texparameteri_target_valid(texObj->Target)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameterfvEXT"); + return; + } + + _mesa_texture_parameterfv(ctx, texObj, pname, params, true); +} void GLAPIENTRY _mesa_TextureParameterfv(GLuint texture, GLenum pname, const GLfloat *params) @@ -1110,210 +1188,414 @@ _mesa_TextureParameterfv(GLuint texture, GLenum pname, const GLfloat *params) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj_by_name(ctx, texture, GL_FALSE); - if (!texObj) { - /* User passed a non-generated name. */ - _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameterfv(texture)"); + texObj = get_texobj_by_name(ctx, texture, "glTextureParameterfv"); + if (!texObj) return; - } _mesa_texture_parameterfv(ctx, texObj, pname, params, true); } void GLAPIENTRY -_mesa_TextureParameterf(GLuint texture, GLenum pname, GLfloat param) +_mesa_MultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, const GLfloat *params) { struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj_by_name(ctx, texture, GL_FALSE); - if (!texObj) { - /* User passed a non-generated name. */ - _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameterf(texture)"); + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + false, + "glMultiTexParameterfvEXT"); + if (!texObj) + return; + + if (!is_texparameteri_target_valid(texObj->Target)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glMultiTexParameterifvEXT(target)"); return; } - _mesa_texture_parameterf(ctx, texObj, pname, param, true); + _mesa_texture_parameterfv(ctx, texObj, pname, params, true); } void GLAPIENTRY -_mesa_TextureParameteri(GLuint texture, GLenum pname, GLint param) +_mesa_TextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, GLfloat param) { struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj_by_name(ctx, texture, GL_FALSE); - if (!texObj) { - /* User passed a non-generated name. */ - _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameteri(texture)"); + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glTextureParameterfEXT"); + if (!texObj) + return; + + if (!is_texparameteri_target_valid(texObj->Target)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameterfEXT"); return; } - _mesa_texture_parameteri(ctx, texObj, pname, param, true); + _mesa_texture_parameterf(ctx, texObj, pname, param, true); } void GLAPIENTRY -_mesa_TextureParameteriv(GLuint texture, GLenum pname, - const GLint *params) +_mesa_MultiTexParameterfEXT(GLenum texunit, GLenum target, GLenum pname, + GLfloat param) { struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj_by_name(ctx, texture, GL_FALSE); - if (!texObj) { - /* User passed a non-generated name. */ - _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameteriv(texture)"); + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + false, + "glMultiTexParameterfEXT"); + if (!texObj) + return; + + if (!is_texparameteri_target_valid(texObj->Target)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glMultiTexParameterfEXT"); return; } - _mesa_texture_parameteriv(ctx, texObj, pname, params, true); + _mesa_texture_parameterf(ctx, texObj, pname, param, true); } - void GLAPIENTRY -_mesa_TextureParameterIiv(GLuint texture, GLenum pname, const GLint *params) +_mesa_TextureParameterf(GLuint texture, GLenum pname, GLfloat param) { struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj_by_name(ctx, texture, GL_FALSE); - if (!texObj) { - /* User passed a non-generated name. */ - _mesa_error(ctx, GL_INVALID_OPERATION, - "glTextureParameterIiv(texture)"); + texObj = get_texobj_by_name(ctx, texture, "glTextureParameterf"); + if (!texObj) return; - } - _mesa_texture_parameterIiv(ctx, texObj, pname, params, true); + _mesa_texture_parameterf(ctx, texObj, pname, param, true); } void GLAPIENTRY -_mesa_TextureParameterIuiv(GLuint texture, GLenum pname, const GLuint *params) +_mesa_TextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, GLint param) { struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj_by_name(ctx, texture, GL_FALSE); - if (!texObj) { - /* User passed a non-generated name. */ - _mesa_error(ctx, GL_INVALID_OPERATION, - "glTextureParameterIuiv(texture)"); + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glTextureParameteriEXT"); + if (!texObj) + return; + + if (!is_texparameteri_target_valid(texObj->Target)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameteriEXT(target)"); return; } - _mesa_texture_parameterIuiv(ctx, texObj, pname, params, true); + _mesa_texture_parameteri(ctx, texObj, pname, param, true); } -static GLboolean -legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target, - bool dsa) +void GLAPIENTRY +_mesa_MultiTexParameteriEXT(GLenum texunit, GLenum target, GLenum pname, + GLint param) { - switch (target) { - case GL_TEXTURE_1D: - case GL_PROXY_TEXTURE_1D: - case GL_TEXTURE_2D: - case GL_PROXY_TEXTURE_2D: - case GL_TEXTURE_3D: - case GL_PROXY_TEXTURE_3D: - return GL_TRUE; - case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: - 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_TEXTURE_1D_ARRAY_EXT: - case GL_PROXY_TEXTURE_1D_ARRAY_EXT: - case GL_TEXTURE_2D_ARRAY_EXT: - case GL_PROXY_TEXTURE_2D_ARRAY_EXT: - 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 ARB_texture_buffer_object spec: - * "(7) Do buffer textures support texture parameters (TexParameter) or - * queries (GetTexParameter, GetTexLevelParameter, GetTexImage)? - * - * RESOLVED: No. [...] Note that the spec edits above don't add - * explicit error language for any of these cases. That is because - * each of the functions enumerate the set of valid - * parameters. Not editing the spec to allow TEXTURE_BUFFER_ARB in - * these cases means that target is not legal, and an INVALID_ENUM - * error should be generated." - * - * From the OpenGL 3.1 spec: - * "target may also be TEXTURE_BUFFER, indicating the texture buffer." - */ - 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; + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); - /* This is a valid target for dsa, but the OpenGL 4.5 core spec - * (30.10.2014) Section 8.11 Texture Queries says: - * "For GetTextureLevelParameter* only, texture may also be a cube - * map texture object. In this case the query is always performed - * for face zero (the TEXTURE_CUBE_MAP_POSITIVE_X face), since there - * is no way to specify another face." - */ - case GL_TEXTURE_CUBE_MAP: - return dsa; - default: - return GL_FALSE; + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + false, + "glMultiTexParameteriEXT"); + if (!texObj) + return; + + if (!is_texparameteri_target_valid(texObj->Target)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glMultiTexParameteriEXT(target)"); + return; } + + _mesa_texture_parameteri(ctx, texObj, pname, param, true); } +void GLAPIENTRY +_mesa_TextureParameteri(GLuint texture, GLenum pname, GLint param) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, "glTextureParameteri"); + if (!texObj) + return; -static void -get_tex_level_parameter_image(struct gl_context *ctx, - const struct gl_texture_object *texObj, - GLenum target, GLint level, - GLenum pname, GLint *params, - bool dsa) + _mesa_texture_parameteri(ctx, texObj, pname, param, true); +} + +void GLAPIENTRY +_mesa_TextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, + const GLint *params) { - const struct gl_texture_image *img = NULL; - struct gl_texture_image dummy_image; - mesa_format texFormat; - const char *suffix = dsa ? "ture" : ""; + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); - img = _mesa_select_tex_image(texObj, target, level); - if (!img || img->TexFormat == MESA_FORMAT_NONE) { - /* 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." - */ - memset(&dummy_image, 0, sizeof(dummy_image)); - dummy_image.TexFormat = MESA_FORMAT_NONE; - dummy_image.InternalFormat = GL_RGBA; - dummy_image._BaseFormat = GL_NONE; + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glTextureParameterivEXT"); + if (!texObj) + return; - img = &dummy_image; + if (!is_texparameteri_target_valid(texObj->Target)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameterivEXT(target)"); + return; } - texFormat = img->TexFormat; + _mesa_texture_parameteriv(ctx, texObj, pname, params, true); +} - switch (pname) { - case GL_TEXTURE_WIDTH: - *params = img->Width; - break; - case GL_TEXTURE_HEIGHT: - *params = img->Height; - break; - case GL_TEXTURE_DEPTH: +void GLAPIENTRY +_mesa_MultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, + const GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + false, + "glMultiTexParameterivEXT"); + if (!texObj) + return; + + if (!is_texparameteri_target_valid(texObj->Target)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glMultiTexParameterivEXT(target)"); + return; + } + + _mesa_texture_parameteriv(ctx, texObj, pname, params, true); +} + +void GLAPIENTRY +_mesa_TextureParameteriv(GLuint texture, GLenum pname, + const GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, "glTextureParameteriv"); + if (!texObj) + return; + + _mesa_texture_parameteriv(ctx, texObj, pname, params, true); +} + + +void GLAPIENTRY +_mesa_TextureParameterIiv(GLuint texture, GLenum pname, const GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, "glTextureParameterIiv"); + if (!texObj) + return; + + _mesa_texture_parameterIiv(ctx, texObj, pname, params, true); +} + +void GLAPIENTRY +_mesa_TextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, + const GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glTextureParameterIivEXT"); + if (!texObj) + return; + + _mesa_texture_parameterIiv(ctx, texObj, pname, params, true); +} + +void GLAPIENTRY +_mesa_MultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname, + const GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + true, + "glMultiTexParameterIivEXT"); + if (!texObj) + return; + + _mesa_texture_parameterIiv(ctx, texObj, pname, params, true); +} + +void GLAPIENTRY +_mesa_TextureParameterIuiv(GLuint texture, GLenum pname, const GLuint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, "glTextureParameterIuiv"); + if (!texObj) + return; + + _mesa_texture_parameterIuiv(ctx, texObj, pname, params, true); +} + +void GLAPIENTRY +_mesa_TextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, + const GLuint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glTextureParameterIuivEXT"); + if (!texObj) + return; + + _mesa_texture_parameterIuiv(ctx, texObj, pname, params, true); +} + +void GLAPIENTRY +_mesa_MultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname, + const GLuint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + true, + "glMultiTexParameterIuivEXT"); + if (!texObj) + return; + + _mesa_texture_parameterIuiv(ctx, texObj, pname, params, true); +} + +GLboolean +_mesa_legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target, + bool dsa) +{ + /* Common targets for desktop GL and GLES 3.1. */ + switch (target) { + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + return GL_TRUE; + case GL_TEXTURE_2D_ARRAY_EXT: + return ctx->Extensions.EXT_texture_array; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + return ctx->Extensions.ARB_texture_cube_map; + case GL_TEXTURE_2D_MULTISAMPLE: + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + return ctx->Extensions.ARB_texture_multisample; + 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 ARB_texture_buffer_object spec: + * "(7) Do buffer textures support texture parameters (TexParameter) or + * queries (GetTexParameter, GetTexLevelParameter, GetTexImage)? + * + * RESOLVED: No. [...] Note that the spec edits above don't add + * explicit error language for any of these cases. That is because + * each of the functions enumerate the set of valid + * parameters. Not editing the spec to allow TEXTURE_BUFFER_ARB in + * these cases means that target is not legal, and an INVALID_ENUM + * error should be generated." + * + * 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) || + _mesa_has_OES_texture_buffer(ctx); + case GL_TEXTURE_CUBE_MAP_ARRAY: + return _mesa_has_texture_cube_map_array(ctx); + } + + if (!_mesa_is_desktop_gl(ctx)) + return GL_FALSE; + + /* Rest of the desktop GL targets. */ + switch (target) { + case GL_TEXTURE_1D: + case GL_PROXY_TEXTURE_1D: + case GL_PROXY_TEXTURE_2D: + case GL_PROXY_TEXTURE_3D: + return GL_TRUE; + case GL_PROXY_TEXTURE_CUBE_MAP: + return ctx->Extensions.ARB_texture_cube_map; + case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: + 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_TEXTURE_1D_ARRAY_EXT: + case GL_PROXY_TEXTURE_1D_ARRAY_EXT: + case GL_PROXY_TEXTURE_2D_ARRAY_EXT: + return ctx->Extensions.EXT_texture_array; + case GL_PROXY_TEXTURE_2D_MULTISAMPLE: + case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: + return ctx->Extensions.ARB_texture_multisample; + + /* This is a valid target for dsa, but the OpenGL 4.5 core spec + * (30.10.2014) Section 8.11 Texture Queries says: + * "For GetTextureLevelParameter* only, texture may also be a cube + * map texture object. In this case the query is always performed + * for face zero (the TEXTURE_CUBE_MAP_POSITIVE_X face), since there + * is no way to specify another face." + */ + case GL_TEXTURE_CUBE_MAP: + return dsa; + default: + return GL_FALSE; + } +} + + +static void +get_tex_level_parameter_image(struct gl_context *ctx, + const struct gl_texture_object *texObj, + GLenum target, GLint level, + GLenum pname, GLint *params, + bool dsa) +{ + const struct gl_texture_image *img = NULL; + struct gl_texture_image dummy_image; + mesa_format texFormat; + const char *suffix = dsa ? "ture" : ""; + + img = _mesa_select_tex_image(texObj, target, level); + if (!img || img->TexFormat == MESA_FORMAT_NONE) { + /* 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." + */ + memset(&dummy_image, 0, sizeof(dummy_image)); + dummy_image.TexFormat = MESA_FORMAT_NONE; + dummy_image.InternalFormat = GL_RGBA; + dummy_image._BaseFormat = GL_NONE; + dummy_image.FixedSampleLocations = GL_TRUE; + + img = &dummy_image; + } + + texFormat = img->TexFormat; + + switch (pname) { + case GL_TEXTURE_WIDTH: + *params = img->Width; + break; + case GL_TEXTURE_HEIGHT: + *params = img->Height; + break; + case GL_TEXTURE_DEPTH: *params = img->Depth; break; case GL_TEXTURE_INTERNAL_FORMAT: @@ -1367,6 +1649,11 @@ get_tex_level_parameter_image(struct gl_context *ctx, _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE)); } + if (*params == 0 && pname == GL_TEXTURE_INTENSITY_SIZE) { + /* Gallium may store intensity as LA */ + *params = _mesa_get_format_bits(texFormat, + GL_TEXTURE_ALPHA_SIZE); + } } else { *params = 0; @@ -1389,16 +1676,15 @@ get_tex_level_parameter_image(struct gl_context *ctx, /* GL_ARB_texture_compression */ case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: - if (_mesa_is_format_compressed(texFormat) && + if (_mesa_is_format_compressed(texFormat) && !_mesa_is_proxy_texture(target)) { *params = _mesa_format_image_size(texFormat, img->Width, img->Height, img->Depth); - } - else { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, - _mesa_enum_to_string(pname)); - } + } else { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, + _mesa_enum_to_string(pname)); + } break; case GL_TEXTURE_COMPRESSED: *params = (GLint) _mesa_is_format_compressed(texFormat); @@ -1436,6 +1722,29 @@ get_tex_level_parameter_image(struct gl_context *ctx, *params = img->FixedSampleLocations; break; + /* There is never a buffer data store here, but these pnames still have + * to work. + */ + + /* GL_ARB_texture_buffer_object */ + case GL_TEXTURE_BUFFER_DATA_STORE_BINDING: + if (!ctx->Extensions.ARB_texture_buffer_object) + goto invalid_pname; + *params = 0; + break; + + /* GL_ARB_texture_buffer_range */ + case GL_TEXTURE_BUFFER_OFFSET: + if (!ctx->Extensions.ARB_texture_buffer_range) + goto invalid_pname; + *params = 0; + break; + case GL_TEXTURE_BUFFER_SIZE: + if (!ctx->Extensions.ARB_texture_buffer_range) + goto invalid_pname; + *params = 0; + break; + default: goto invalid_pname; } @@ -1450,6 +1759,9 @@ invalid_pname: } +/** + * Handle a glGetTexLevelParamteriv() call for a texture buffer. + */ static void get_tex_level_parameter_buffer(struct gl_context *ctx, const struct gl_texture_object *texObj, @@ -1457,13 +1769,26 @@ get_tex_level_parameter_buffer(struct gl_context *ctx, { const struct gl_buffer_object *bo = texObj->BufferObject; mesa_format texFormat = texObj->_BufferObjectFormat; + int bytes = MAX2(1, _mesa_get_format_bytes(texFormat)); GLenum internalFormat = texObj->BufferObjectFormat; GLenum baseFormat = _mesa_get_format_base_format(texFormat); const char *suffix = dsa ? "ture" : ""; + assert(texObj->Target == GL_TEXTURE_BUFFER); + if (!bo) { /* undefined texture buffer object */ - *params = pname == GL_TEXTURE_COMPONENTS ? 1 : 0; + switch (pname) { + case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS: + *params = GL_TRUE; + break; + case GL_TEXTURE_INTERNAL_FORMAT: + *params = internalFormat; + break; + default: + *params = 0; + break; + } return; } @@ -1472,10 +1797,13 @@ get_tex_level_parameter_buffer(struct gl_context *ctx, *params = bo->Name; break; case GL_TEXTURE_WIDTH: - *params = bo->Size; + *params = ((texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize) + / bytes; break; case GL_TEXTURE_HEIGHT: case GL_TEXTURE_DEPTH: + *params = 1; + break; case GL_TEXTURE_BORDER: case GL_TEXTURE_SHARED_SIZE: case GL_TEXTURE_COMPRESSED: @@ -1525,6 +1853,19 @@ get_tex_level_parameter_buffer(struct gl_context *ctx, *params = (texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize; break; + /* GL_ARB_texture_multisample */ + case GL_TEXTURE_SAMPLES: + if (!ctx->Extensions.ARB_texture_multisample) + goto invalid_pname; + *params = 0; + break; + + case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS: + if (!ctx->Extensions.ARB_texture_multisample) + goto invalid_pname; + *params = GL_TRUE; + break; + /* GL_ARB_texture_compression */ case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: /* Always illegal for GL_TEXTURE_BUFFER */ @@ -1562,6 +1903,19 @@ invalid_pname: _mesa_enum_to_string(pname)); } +static bool +valid_tex_level_parameteriv_target(struct gl_context *ctx, GLenum target, + bool dsa) +{ + const char *suffix = dsa ? "ture" : ""; + if (!_mesa_legal_get_tex_level_parameter_target(ctx, target, dsa)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTex%sLevelParameter[if]v(target=%s)", suffix, + _mesa_enum_to_string(target)); + return false; + } + return true; +} /** * This isn't exposed to the rest of the driver because it is a part of the @@ -1585,13 +1939,6 @@ get_tex_level_parameteriv(struct gl_context *ctx, return; } - if (!legal_get_tex_level_parameter_target(ctx, target, dsa)) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetTex%sLevelParameter[if]v(target=%s)", suffix, - _mesa_enum_to_string(target)); - return; - } - maxLevels = _mesa_max_texture_levels(ctx, target); assert(maxLevels != 0); @@ -1619,6 +1966,9 @@ _mesa_GetTexLevelParameterfv( GLenum target, GLint level, GLint iparam; GET_CURRENT_CONTEXT(ctx); + if (!valid_tex_level_parameteriv_target(ctx, target, false)) + return; + texObj = _mesa_get_current_tex_object(ctx, target); if (!texObj) return; @@ -1636,6 +1986,9 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); + if (!valid_tex_level_parameteriv_target(ctx, target, false)) + return; + texObj = _mesa_get_current_tex_object(ctx, target); if (!texObj) return; @@ -1657,6 +2010,55 @@ _mesa_GetTextureLevelParameterfv(GLuint texture, GLint level, if (!texObj) return; + if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true)) + return; + + get_tex_level_parameteriv(ctx, texObj, texObj->Target, level, + pname, &iparam, true); + + *params = (GLfloat) iparam; +} + +void GLAPIENTRY +_mesa_GetTextureLevelParameterfvEXT(GLuint texture, GLenum target, GLint level, + GLenum pname, GLfloat *params) +{ + struct gl_texture_object *texObj; + GLint iparam; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glGetTextureLevelParameterfvEXT"); + if (!texObj) + return; + + if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true)) + return; + + get_tex_level_parameteriv(ctx, texObj, texObj->Target, level, + pname, &iparam, true); + + *params = (GLfloat) iparam; +} + +void GLAPIENTRY +_mesa_GetMultiTexLevelParameterfvEXT(GLenum texunit, GLenum target, GLint level, + GLenum pname, GLfloat *params) +{ + struct gl_texture_object *texObj; + GLint iparam; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + true, + "glGetMultiTexLevelParameterfvEXT"); + if (!texObj) + return; + + if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true)) + return; + get_tex_level_parameteriv(ctx, texObj, texObj->Target, level, pname, &iparam, true); @@ -1675,10 +2077,54 @@ _mesa_GetTextureLevelParameteriv(GLuint texture, GLint level, if (!texObj) return; + if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true)) + return; + + get_tex_level_parameteriv(ctx, texObj, texObj->Target, level, + pname, params, true); +} + +void GLAPIENTRY +_mesa_GetTextureLevelParameterivEXT(GLuint texture, GLenum target, GLint level, + GLenum pname, GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glGetTextureLevelParameterivEXT"); + if (!texObj) + return; + + if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true)) + return; + get_tex_level_parameteriv(ctx, texObj, texObj->Target, level, pname, params, true); } +void GLAPIENTRY +_mesa_GetMultiTexLevelParameterivEXT(GLenum texunit, GLenum target, GLint level, + GLenum pname, GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + true, + "glGetMultiTexLevelParameterivEXT"); + if (!texObj) + return; + + if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true)) + return; + + get_tex_level_parameteriv(ctx, texObj, texObj->Target, level, + pname, params, true); +} + + /** * This isn't exposed to the rest of the driver because it is a part of the * OpenGL API that is rarely used. @@ -1706,7 +2152,8 @@ get_tex_parameterfv(struct gl_context *ctx, *params = ENUM_TO_FLOAT(obj->Sampler.WrapR); break; case GL_TEXTURE_BORDER_COLOR: - if (!_mesa_is_desktop_gl(ctx)) + if (ctx->API == API_OPENGLES || + !ctx->Extensions.ARB_texture_border_clamp) goto invalid_pname; if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP)) @@ -1789,7 +2236,7 @@ get_tex_parameterfv(struct gl_context *ctx, *params = (GLfloat) obj->DepthMode; break; case GL_DEPTH_STENCIL_TEXTURE_MODE: - if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_stencil_texturing) + if (!_mesa_has_ARB_stencil_texturing(ctx) && !_mesa_is_gles31(ctx)) goto invalid_pname; *params = (GLfloat) (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT); @@ -1847,33 +2294,32 @@ get_tex_parameterfv(struct gl_context *ctx, break; case GL_TEXTURE_IMMUTABLE_LEVELS: - if (_mesa_is_gles3(ctx) || - (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view)) + if (_mesa_is_gles3(ctx) || _mesa_has_texture_view(ctx)) *params = (GLfloat) obj->ImmutableLevels; else goto invalid_pname; break; case GL_TEXTURE_VIEW_MIN_LEVEL: - if (!ctx->Extensions.ARB_texture_view) + if (!_mesa_has_texture_view(ctx)) goto invalid_pname; *params = (GLfloat) obj->MinLevel; break; case GL_TEXTURE_VIEW_NUM_LEVELS: - if (!ctx->Extensions.ARB_texture_view) + if (!_mesa_has_texture_view(ctx)) goto invalid_pname; *params = (GLfloat) obj->NumLevels; break; case GL_TEXTURE_VIEW_MIN_LAYER: - if (!ctx->Extensions.ARB_texture_view) + if (!_mesa_has_texture_view(ctx)) goto invalid_pname; *params = (GLfloat) obj->MinLayer; break; case GL_TEXTURE_VIEW_NUM_LAYERS: - if (!ctx->Extensions.ARB_texture_view) + if (!_mesa_has_texture_view(ctx)) goto invalid_pname; *params = (GLfloat) obj->NumLayers; break; @@ -1890,6 +2336,24 @@ get_tex_parameterfv(struct gl_context *ctx, *params = (GLfloat) obj->Sampler.sRGBDecode; break; + case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: + if (!ctx->Extensions.ARB_shader_image_load_store) + goto invalid_pname; + *params = (GLfloat) obj->ImageFormatCompatibilityType; + break; + + case GL_TEXTURE_TARGET: + if (ctx->API != API_OPENGL_CORE) + goto invalid_pname; + *params = ENUM_TO_FLOAT(obj->Target); + break; + + case GL_TEXTURE_TILING_EXT: + if (!ctx->Extensions.EXT_memory_object) + goto invalid_pname; + *params = ENUM_TO_FLOAT(obj->TextureTiling); + break; + default: goto invalid_pname; } @@ -1928,7 +2392,8 @@ get_tex_parameteriv(struct gl_context *ctx, *params = (GLint) obj->Sampler.WrapR; break; case GL_TEXTURE_BORDER_COLOR: - if (!_mesa_is_desktop_gl(ctx)) + if (ctx->API == API_OPENGLES || + !ctx->Extensions.ARB_texture_border_clamp) goto invalid_pname; { @@ -2012,7 +2477,7 @@ get_tex_parameteriv(struct gl_context *ctx, *params = (GLint) obj->DepthMode; break; case GL_DEPTH_STENCIL_TEXTURE_MODE: - if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_stencil_texturing) + if (!_mesa_has_ARB_stencil_texturing(ctx) && !_mesa_is_gles31(ctx)) goto invalid_pname; *params = (GLint) (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT); @@ -2115,6 +2580,18 @@ get_tex_parameteriv(struct gl_context *ctx, *params = obj->ImageFormatCompatibilityType; break; + case GL_TEXTURE_TARGET: + if (ctx->API != API_OPENGL_CORE) + goto invalid_pname; + *params = (GLint) obj->Target; + break; + + case GL_TEXTURE_TILING_EXT: + if (!ctx->Extensions.EXT_memory_object) + goto invalid_pname; + *params = (GLint) obj->TextureTiling; + break; + default: goto invalid_pname; } @@ -2143,37 +2620,16 @@ get_tex_parameterIiv(struct gl_context *ctx, } } -static void -get_tex_parameterIuiv(struct gl_context *ctx, - struct gl_texture_object *obj, - GLenum pname, GLuint *params, bool dsa) -{ - switch (pname) { - case GL_TEXTURE_BORDER_COLOR: - COPY_4V(params, obj->Sampler.BorderColor.i); - break; - default: - { - GLint ip[4]; - get_tex_parameteriv(ctx, obj, pname, ip, dsa); - params[0] = ip[0]; - if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT || - pname == GL_TEXTURE_CROP_RECT_OES) { - params[1] = ip[1]; - params[2] = ip[2]; - params[3] = ip[3]; - } - } - } -} - void GLAPIENTRY _mesa_GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) { struct gl_texture_object *obj; GET_CURRENT_CONTEXT(ctx); - obj = get_texobj_by_target(ctx, target, GL_TRUE); + obj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + ctx->Texture.CurrentUnit, + false, + "glGetTexParameterfv"); if (!obj) return; @@ -2186,7 +2642,10 @@ _mesa_GetTexParameteriv(GLenum target, GLenum pname, GLint *params) struct gl_texture_object *obj; GET_CURRENT_CONTEXT(ctx); - obj = get_texobj_by_target(ctx, target, GL_TRUE); + obj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + ctx->Texture.CurrentUnit, + false, + "glGetTexParameteriv"); if (!obj) return; @@ -2200,7 +2659,10 @@ _mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj_by_target(ctx, target, GL_TRUE); + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + ctx->Texture.CurrentUnit, + false, + "glGetTexParameterIiv"); if (!texObj) return; @@ -2215,13 +2677,54 @@ _mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj_by_target(ctx, target, GL_TRUE); + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + ctx->Texture.CurrentUnit, + false, + "glGetTexParameterIuiv"); if (!texObj) return; - get_tex_parameterIuiv(ctx, texObj, pname, params, false); + get_tex_parameterIiv(ctx, texObj, pname, (GLint *) params, false); } +void GLAPIENTRY +_mesa_GetTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, GLfloat *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glGetTextureParameterfvEXT"); + if (!texObj) + return; + + if (!is_texparameteri_target_valid(texObj->Target)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTextureParameterfvEXT"); + return; + } + + get_tex_parameterfv(ctx, texObj, pname, params, true); +} + +void GLAPIENTRY +_mesa_GetMultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + false, + "glGetMultiTexParameterfvEXT"); + if (!texObj) + return; + + if (!is_texparameteri_target_valid(texObj->Target)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMultiTexParameterfvEXT"); + return; + } + get_tex_parameterfv(ctx, texObj, pname, params, true); +} void GLAPIENTRY _mesa_GetTextureParameterfv(GLuint texture, GLenum pname, GLfloat *params) @@ -2229,30 +2732,60 @@ _mesa_GetTextureParameterfv(GLuint texture, GLenum pname, GLfloat *params) struct gl_texture_object *obj; GET_CURRENT_CONTEXT(ctx); - obj = get_texobj_by_name(ctx, texture, GL_TRUE); - if (!obj) { - /* User passed a non-generated name. */ - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTextureParameterfv(texture)"); + obj = get_texobj_by_name(ctx, texture, "glGetTextureParameterfv"); + if (!obj) return; - } get_tex_parameterfv(ctx, obj, pname, params, true); } +void GLAPIENTRY +_mesa_GetTextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glGetTextureParameterivEXT"); + if (!texObj) + return; + + if (!is_texparameteri_target_valid(texObj->Target)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTextureParameterivEXT"); + return; + } + get_tex_parameteriv(ctx, texObj, pname, params, true); +} + +void GLAPIENTRY +_mesa_GetMultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + false, + "glGetMultiTexParameterivEXT"); + if (!texObj) + return; + + if (!is_texparameteri_target_valid(texObj->Target)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMultiTexParameterivEXT"); + return; + } + get_tex_parameteriv(ctx, texObj, pname, params, true); +} + void GLAPIENTRY _mesa_GetTextureParameteriv(GLuint texture, GLenum pname, GLint *params) { struct gl_texture_object *obj; GET_CURRENT_CONTEXT(ctx); - obj = get_texobj_by_name(ctx, texture, GL_TRUE); - if (!obj) { - /* User passed a non-generated name. */ - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTextureParameteriv(texture)"); + obj = get_texobj_by_name(ctx, texture, "glGetTextureParameteriv"); + if (!obj) return; - } get_tex_parameteriv(ctx, obj, pname, params, true); } @@ -2263,17 +2796,44 @@ _mesa_GetTextureParameterIiv(GLuint texture, GLenum pname, GLint *params) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj_by_name(ctx, texture, GL_TRUE); - if (!texObj) { - /* User passed a non-generated name. */ - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTextureParameterIiv(texture)"); + texObj = get_texobj_by_name(ctx, texture, "glGetTextureParameterIiv"); + if (!texObj) return; - } get_tex_parameterIiv(ctx, texObj, pname, params, true); } +void GLAPIENTRY +_mesa_GetTextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glGetTextureParameterIivEXT"); + if (!texObj) + return; + + + get_tex_parameterIiv(ctx, texObj, pname, params, true); +} + +void GLAPIENTRY +_mesa_GetMultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname, + GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + true, + "glGetMultiTexParameterIiv"); + if (!texObj) + return; + + get_tex_parameterIiv(ctx, texObj, pname, params, true); +} void GLAPIENTRY _mesa_GetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint *params) @@ -2281,13 +2841,41 @@ _mesa_GetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint *params) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj_by_name(ctx, texture, GL_TRUE); - if (!texObj) { - /* User passed a non-generated name. */ - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTextureParameterIuiv(texture)"); + texObj = get_texobj_by_name(ctx, texture, "glGetTextureParameterIuiv"); + if (!texObj) + return; + + get_tex_parameterIiv(ctx, texObj, pname, (GLint *) params, true); +} + +void GLAPIENTRY +_mesa_GetTextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, + GLuint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glGetTextureParameterIuvEXT"); + if (!texObj) + return; + + get_tex_parameterIiv(ctx, texObj, pname, (GLint *) params, true); +} + +void GLAPIENTRY +_mesa_GetMultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname, + GLuint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + true, + "glGetMultiTexParameterIuiv"); + if (!texObj) return; - } - get_tex_parameterIuiv(ctx, texObj, pname, params, true); + get_tex_parameterIiv(ctx, texObj, pname, (GLint *) params, true); }