diff options
-rw-r--r-- | src/mesa/main/teximage.c | 3 | ||||
-rw-r--r-- | src/mesa/main/texparam.c | 128 |
2 files changed, 130 insertions, 1 deletions
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 9deaab2ad94..fd02a1be23f 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -967,6 +967,9 @@ _mesa_max_texture_levels(struct gl_context *ctx, GLenum target) ctx->Extensions.EXT_texture_array) ? ctx->Const.MaxTextureLevels : 0; case GL_TEXTURE_BUFFER: + return _mesa_is_desktop_gl(ctx) && + (ctx->Extensions.ARB_texture_buffer_object || + (ctx->Version >= 31)) ? 1 : 0; case GL_TEXTURE_EXTERNAL_OES: /* fall-through */ default: diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index 7285c47d173..8a5abe5e1cc 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -899,6 +899,25 @@ legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target) case GL_PROXY_TEXTURE_2D_ARRAY_EXT: return (ctx->Extensions.MESA_texture_array || 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 <target> + * 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; default: return GL_FALSE; } @@ -1052,6 +1071,110 @@ invalid_pname: } +static void +get_tex_level_parameter_buffer(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum target, GLint level, + GLenum pname, GLint *params) +{ + struct gl_buffer_object *bo = texObj->BufferObject; + gl_format texFormat = texObj->_BufferObjectFormat; + GLenum internalFormat = texObj->BufferObjectFormat; + GLenum baseFormat = _mesa_get_format_base_format(texFormat); + + if (!bo) { + /* undefined texture buffer object */ + *params = pname == GL_TEXTURE_COMPONENTS ? 1 : 0; + return; + } + + switch (pname) { + case GL_TEXTURE_BUFFER_DATA_STORE_BINDING: + *params = bo->Name; + break; + case GL_TEXTURE_WIDTH: + *params = bo->Size; + break; + case GL_TEXTURE_HEIGHT: + case GL_TEXTURE_DEPTH: + case GL_TEXTURE_BORDER: + case GL_TEXTURE_SHARED_SIZE: + case GL_TEXTURE_COMPRESSED: + *params = 0; + break; + case GL_TEXTURE_INTERNAL_FORMAT: + *params = internalFormat; + break; + case GL_TEXTURE_RED_SIZE: + case GL_TEXTURE_GREEN_SIZE: + case GL_TEXTURE_BLUE_SIZE: + case GL_TEXTURE_ALPHA_SIZE: + if (_mesa_base_format_has_channel(baseFormat, pname)) + *params = _mesa_get_format_bits(texFormat, pname); + else + *params = 0; + break; + case GL_TEXTURE_INTENSITY_SIZE: + case GL_TEXTURE_LUMINANCE_SIZE: + if (_mesa_base_format_has_channel(baseFormat, pname)) { + *params = _mesa_get_format_bits(texFormat, pname); + if (*params == 0) { + /* intensity or luminance is probably stored as RGB[A] */ + *params = MIN2(_mesa_get_format_bits(texFormat, + GL_TEXTURE_RED_SIZE), + _mesa_get_format_bits(texFormat, + GL_TEXTURE_GREEN_SIZE)); + } + } else { + *params = 0; + } + break; + case GL_TEXTURE_DEPTH_SIZE_ARB: + case GL_TEXTURE_STENCIL_SIZE_EXT: + *params = _mesa_get_format_bits(texFormat, pname); + break; + + /* GL_ARB_texture_compression */ + case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: + if (_mesa_is_format_compressed(texFormat) && + !_mesa_is_proxy_texture(target)) { + *params = _mesa_format_image_size(texFormat, bo->Size, 0, 0); + } else { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTexLevelParameter[if]v(pname)"); + } + break; + + /* GL_ARB_texture_float */ + case GL_TEXTURE_RED_TYPE_ARB: + case GL_TEXTURE_GREEN_TYPE_ARB: + case GL_TEXTURE_BLUE_TYPE_ARB: + case GL_TEXTURE_ALPHA_TYPE_ARB: + case GL_TEXTURE_LUMINANCE_TYPE_ARB: + case GL_TEXTURE_INTENSITY_TYPE_ARB: + case GL_TEXTURE_DEPTH_TYPE_ARB: + if (!ctx->Extensions.ARB_texture_float) + goto invalid_pname; + if (_mesa_base_format_has_channel(baseFormat, pname)) + *params = _mesa_get_format_datatype(texFormat); + else + *params = GL_NONE; + break; + + default: + goto invalid_pname; + } + + /* no error if we get here */ + return; + +invalid_pname: + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTexLevelParameter[if]v(pname=%s)", + _mesa_lookup_enum_by_nr(pname)); +} + + void GLAPIENTRY _mesa_GetTexLevelParameterfv( GLenum target, GLint level, GLenum pname, GLfloat *params ) @@ -1096,7 +1219,10 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, texObj = _mesa_select_tex_object(ctx, texUnit, target); - get_tex_level_parameter_image(ctx, texObj, target, level, pname, params); + if (target == GL_TEXTURE_BUFFER) + get_tex_level_parameter_buffer(ctx, texObj, target, level, pname, params); + else + get_tex_level_parameter_image(ctx, texObj, target, level, pname, params); } |