summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2012-06-10 19:33:01 -0700
committerIan Romanick <ian.d.romanick@intel.com>2012-08-17 09:14:36 -0700
commit3df13b32e56dbc76bdc72b75ea1462f79b44dce9 (patch)
treec4ce2ab56692a3ce7a349d583389ce2253b96d6d
parent8c37fc1e9240a323b07c21da83dbd5432fc6895a (diff)
downloadmesa-master.tar.gz
mesa-master.tar.xz
mesa-master.zip
mesa: Support GL_TEXTURE_BUFFER in GetTexLevelParameter[if]v in GL 3.1+.HEADmaster
The OpenGL 3.1 specification explicitly allows this. Oddly, the ARB_texture_buffer_object spec's issues section claims this isn't allowed, but proceeds to explain that the extension simply doesn't edit the underlying spec to allow it, and thus it didn't appear in the list of legal texture targets. Thus, this patch legalizes it only in 3.1+ contexts, but still returns INVALID_ENUM in earlier contexts that expose ARB_texture_buffer_object. Unfortunately, the behavior of the call is horrendously undefined. Fixes oglconform's tbo/negative.textureParams test. v2: Require desktop OpenGL. Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
-rw-r--r--src/mesa/main/teximage.c3
-rw-r--r--src/mesa/main/texparam.c128
2 files changed, 130 insertions, 1 deletions
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 9deaab2ad9..fd02a1be23 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 7285c47d17..8a5abe5e1c 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);
}