mesa: implement GL_ARB_texture_buffer_range
v2: Record texObj.BufferSize as -1 in TexBuffer(non-Range) instead of the buffer's current size so we know we always have to use the full size of the buffer object (i.e. even if it changes without the user calling TexBuffer again) for the texture. Clarify invalid offset alignment error message. v3: Use extra GL_CORE-only section in get_hash_params.py for TEXTURE_BUFFER_OFFSET_ALIGNMENT. v4: Remove unnecessary check for profile in _mesa_TexBufferRange. Add check for extension enable in get_tex_level_parameter_buffer. v5: Fix position in gl_API.xml. Add comment about meaning of BufferSize == -1. v6: Add back checks for core profile and add a note about it. Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
22
src/mapi/glapi/gen/ARB_texture_buffer_range.xml
Normal file
22
src/mapi/glapi/gen/ARB_texture_buffer_range.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
|
||||||
|
|
||||||
|
<OpenGLAPI>
|
||||||
|
|
||||||
|
<category name="GL_ARB_texture_buffer_range" number="139">
|
||||||
|
|
||||||
|
<enum name="TEXTURE_BUFFER_OFFSET" value="0x919D"/>
|
||||||
|
<enum name="TEXTURE_BUFFER_SIZE" value="0x919E"/>
|
||||||
|
<enum name="TEXTURE_BUFFER_OFFSET_ALIGNMENT" value="0x919F"/>
|
||||||
|
|
||||||
|
<function name="TexBufferRange" offset="assign">
|
||||||
|
<param name="target" type="GLenum"/>
|
||||||
|
<param name="internalformat" type="GLenum"/>
|
||||||
|
<param name="buffer" type="GLuint"/>
|
||||||
|
<param name="offset" type="GLintptr"/>
|
||||||
|
<param name="size" type="GLsizeiptr"/>
|
||||||
|
</function>
|
||||||
|
|
||||||
|
</category>
|
||||||
|
|
||||||
|
</OpenGLAPI>
|
@@ -108,6 +108,7 @@ API_XML = \
|
|||||||
ARB_seamless_cube_map.xml \
|
ARB_seamless_cube_map.xml \
|
||||||
ARB_sync.xml \
|
ARB_sync.xml \
|
||||||
ARB_texture_buffer_object.xml \
|
ARB_texture_buffer_object.xml \
|
||||||
|
ARB_texture_buffer_range.xml \
|
||||||
ARB_texture_compression_rgtc.xml \
|
ARB_texture_compression_rgtc.xml \
|
||||||
ARB_texture_float.xml \
|
ARB_texture_float.xml \
|
||||||
ARB_texture_rg.xml \
|
ARB_texture_rg.xml \
|
||||||
|
@@ -8316,6 +8316,10 @@
|
|||||||
|
|
||||||
<xi:include href="ARB_invalidate_subdata.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
<xi:include href="ARB_invalidate_subdata.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
||||||
|
|
||||||
|
<!-- ARB extensions #133...#138 -->
|
||||||
|
|
||||||
|
<xi:include href="ARB_texture_buffer_range.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
||||||
|
|
||||||
<!-- Non-ARB extensions sorted by extension number. -->
|
<!-- Non-ARB extensions sorted by extension number. -->
|
||||||
|
|
||||||
<category name="GL_EXT_blend_color" number="2">
|
<category name="GL_EXT_blend_color" number="2">
|
||||||
|
@@ -564,6 +564,7 @@ _mesa_init_constants(struct gl_context *ctx)
|
|||||||
ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
|
ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
|
||||||
ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
|
ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
|
||||||
ctx->Const.MaxTextureBufferSize = 65536;
|
ctx->Const.MaxTextureBufferSize = 65536;
|
||||||
|
ctx->Const.TextureBufferOffsetAlignment = 1;
|
||||||
ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
|
ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
|
||||||
ctx->Const.SubPixelBits = SUB_PIXEL_BITS;
|
ctx->Const.SubPixelBits = SUB_PIXEL_BITS;
|
||||||
ctx->Const.MinPointSize = MIN_POINT_SIZE;
|
ctx->Const.MinPointSize = MIN_POINT_SIZE;
|
||||||
|
@@ -131,6 +131,7 @@ static const struct extension extension_table[] = {
|
|||||||
{ "GL_ARB_texture_border_clamp", o(ARB_texture_border_clamp), GLL, 2000 },
|
{ "GL_ARB_texture_border_clamp", o(ARB_texture_border_clamp), GLL, 2000 },
|
||||||
{ "GL_ARB_texture_buffer_object", o(ARB_texture_buffer_object), GLC, 2008 },
|
{ "GL_ARB_texture_buffer_object", o(ARB_texture_buffer_object), GLC, 2008 },
|
||||||
{ "GL_ARB_texture_buffer_object_rgb32", o(ARB_texture_buffer_object_rgb32), GLC, 2009 },
|
{ "GL_ARB_texture_buffer_object_rgb32", o(ARB_texture_buffer_object_rgb32), GLC, 2009 },
|
||||||
|
{ "GL_ARB_texture_buffer_range", o(ARB_texture_buffer_range), GLC, 2012 },
|
||||||
{ "GL_ARB_texture_compression", o(dummy_true), GLL, 2000 },
|
{ "GL_ARB_texture_compression", o(dummy_true), GLL, 2000 },
|
||||||
{ "GL_ARB_texture_compression_rgtc", o(ARB_texture_compression_rgtc), GL, 2004 },
|
{ "GL_ARB_texture_compression_rgtc", o(ARB_texture_compression_rgtc), GL, 2004 },
|
||||||
{ "GL_ARB_texture_cube_map", o(ARB_texture_cube_map), GLL, 1999 },
|
{ "GL_ARB_texture_cube_map", o(ARB_texture_cube_map), GLL, 1999 },
|
||||||
|
@@ -353,6 +353,7 @@ EXTRA_EXT(ARB_uniform_buffer_object);
|
|||||||
EXTRA_EXT(ARB_timer_query);
|
EXTRA_EXT(ARB_timer_query);
|
||||||
EXTRA_EXT(ARB_map_buffer_alignment);
|
EXTRA_EXT(ARB_map_buffer_alignment);
|
||||||
EXTRA_EXT(ARB_texture_cube_map_array);
|
EXTRA_EXT(ARB_texture_cube_map_array);
|
||||||
|
EXTRA_EXT(ARB_texture_buffer_range);
|
||||||
|
|
||||||
static const int
|
static const int
|
||||||
extra_NV_primitive_restart[] = {
|
extra_NV_primitive_restart[] = {
|
||||||
|
@@ -701,6 +701,12 @@ descriptor=[
|
|||||||
|
|
||||||
# GL_ARB_texture_cube_map_array
|
# GL_ARB_texture_cube_map_array
|
||||||
[ "TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB", "LOC_CUSTOM, TYPE_INT, TEXTURE_CUBE_ARRAY_INDEX, extra_ARB_texture_cube_map_array" ],
|
[ "TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB", "LOC_CUSTOM, TYPE_INT, TEXTURE_CUBE_ARRAY_INDEX, extra_ARB_texture_cube_map_array" ],
|
||||||
|
]},
|
||||||
|
|
||||||
|
# Enums restricted to OpenGL Core profile
|
||||||
|
{ "apis": ["GL_CORE"], "params": [
|
||||||
|
# GL_ARB_texture_buffer_range
|
||||||
|
[ "TEXTURE_BUFFER_OFFSET_ALIGNMENT", "CONTEXT_INT(Const.TextureBufferOffsetAlignment), extra_ARB_texture_buffer_range" ],
|
||||||
]}
|
]}
|
||||||
|
|
||||||
]
|
]
|
||||||
|
@@ -1295,6 +1295,9 @@ struct gl_texture_object
|
|||||||
GLenum BufferObjectFormat;
|
GLenum BufferObjectFormat;
|
||||||
/** Equivalent Mesa format for BufferObjectFormat. */
|
/** Equivalent Mesa format for BufferObjectFormat. */
|
||||||
gl_format _BufferObjectFormat;
|
gl_format _BufferObjectFormat;
|
||||||
|
/** GL_ARB_texture_buffer_range */
|
||||||
|
GLintptr BufferOffset;
|
||||||
|
GLsizeiptr BufferSize; /**< if this is -1, use BufferObject->Size instead */
|
||||||
|
|
||||||
/** GL_OES_EGL_image_external */
|
/** GL_OES_EGL_image_external */
|
||||||
GLint RequiredTextureImageUnits;
|
GLint RequiredTextureImageUnits;
|
||||||
@@ -2851,6 +2854,8 @@ struct gl_constants
|
|||||||
GLfloat MaxTextureLodBias; /**< GL_EXT_texture_lod_bias */
|
GLfloat MaxTextureLodBias; /**< GL_EXT_texture_lod_bias */
|
||||||
GLuint MaxTextureBufferSize; /**< GL_ARB_texture_buffer_object */
|
GLuint MaxTextureBufferSize; /**< GL_ARB_texture_buffer_object */
|
||||||
|
|
||||||
|
GLuint TextureBufferOffsetAlignment; /**< GL_ARB_texture_buffer_range */
|
||||||
|
|
||||||
GLuint MaxArrayLockSize;
|
GLuint MaxArrayLockSize;
|
||||||
|
|
||||||
GLint SubPixelBits;
|
GLint SubPixelBits;
|
||||||
@@ -3075,6 +3080,7 @@ struct gl_extensions
|
|||||||
GLboolean ARB_texture_border_clamp;
|
GLboolean ARB_texture_border_clamp;
|
||||||
GLboolean ARB_texture_buffer_object;
|
GLboolean ARB_texture_buffer_object;
|
||||||
GLboolean ARB_texture_buffer_object_rgb32;
|
GLboolean ARB_texture_buffer_object_rgb32;
|
||||||
|
GLboolean ARB_texture_buffer_range;
|
||||||
GLboolean ARB_texture_compression_rgtc;
|
GLboolean ARB_texture_compression_rgtc;
|
||||||
GLboolean ARB_texture_cube_map;
|
GLboolean ARB_texture_cube_map;
|
||||||
GLboolean ARB_texture_cube_map_array;
|
GLboolean ARB_texture_cube_map_array;
|
||||||
|
@@ -3994,23 +3994,16 @@ validate_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** GL_ARB_texture_buffer_object */
|
static void
|
||||||
void GLAPIENTRY
|
texbufferrange(struct gl_context *ctx, GLenum target, GLenum internalFormat,
|
||||||
_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer)
|
struct gl_buffer_object *bufObj,
|
||||||
|
GLintptr offset, GLsizeiptr size)
|
||||||
{
|
{
|
||||||
struct gl_texture_object *texObj;
|
struct gl_texture_object *texObj;
|
||||||
struct gl_buffer_object *bufObj;
|
|
||||||
gl_format format;
|
gl_format format;
|
||||||
|
|
||||||
GET_CURRENT_CONTEXT(ctx);
|
|
||||||
FLUSH_VERTICES(ctx, 0);
|
FLUSH_VERTICES(ctx, 0);
|
||||||
|
|
||||||
if (!(ctx->API == API_OPENGL_CORE &&
|
|
||||||
ctx->Extensions.ARB_texture_buffer_object)) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target != GL_TEXTURE_BUFFER_ARB) {
|
if (target != GL_TEXTURE_BUFFER_ARB) {
|
||||||
_mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(target)");
|
_mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(target)");
|
||||||
return;
|
return;
|
||||||
@@ -4023,12 +4016,6 @@ _mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bufObj = _mesa_lookup_bufferobj(ctx, buffer);
|
|
||||||
if (buffer && !bufObj) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer(buffer %u)", buffer);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
texObj = _mesa_get_current_tex_object(ctx, target);
|
texObj = _mesa_get_current_tex_object(ctx, target);
|
||||||
|
|
||||||
_mesa_lock_texture(ctx, texObj);
|
_mesa_lock_texture(ctx, texObj);
|
||||||
@@ -4036,6 +4023,74 @@ _mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer)
|
|||||||
_mesa_reference_buffer_object(ctx, &texObj->BufferObject, bufObj);
|
_mesa_reference_buffer_object(ctx, &texObj->BufferObject, bufObj);
|
||||||
texObj->BufferObjectFormat = internalFormat;
|
texObj->BufferObjectFormat = internalFormat;
|
||||||
texObj->_BufferObjectFormat = format;
|
texObj->_BufferObjectFormat = format;
|
||||||
|
texObj->BufferOffset = offset;
|
||||||
|
texObj->BufferSize = size;
|
||||||
}
|
}
|
||||||
_mesa_unlock_texture(ctx, texObj);
|
_mesa_unlock_texture(ctx, texObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** GL_ARB_texture_buffer_object */
|
||||||
|
void GLAPIENTRY
|
||||||
|
_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer)
|
||||||
|
{
|
||||||
|
struct gl_buffer_object *bufObj;
|
||||||
|
|
||||||
|
GET_CURRENT_CONTEXT(ctx);
|
||||||
|
|
||||||
|
/* NOTE: ARB_texture_buffer_object has interactions with
|
||||||
|
* the compatibility profile that are not implemented.
|
||||||
|
*/
|
||||||
|
if (!(ctx->API == API_OPENGL_CORE &&
|
||||||
|
ctx->Extensions.ARB_texture_buffer_object)) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufObj = _mesa_lookup_bufferobj(ctx, buffer);
|
||||||
|
if (!bufObj && buffer) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer(buffer %u)", buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
texbufferrange(ctx, target, internalFormat, bufObj, 0, buffer ? -1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** GL_ARB_texture_buffer_range */
|
||||||
|
void GLAPIENTRY
|
||||||
|
_mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer,
|
||||||
|
GLintptr offset, GLsizeiptr size)
|
||||||
|
{
|
||||||
|
struct gl_buffer_object *bufObj;
|
||||||
|
|
||||||
|
GET_CURRENT_CONTEXT(ctx);
|
||||||
|
|
||||||
|
if (!(ctx->API == API_OPENGL_CORE &&
|
||||||
|
ctx->Extensions.ARB_texture_buffer_range)) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_OPERATION, "glTexBufferRange");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufObj = _mesa_lookup_bufferobj(ctx, buffer);
|
||||||
|
if (bufObj) {
|
||||||
|
if (offset < 0 ||
|
||||||
|
size <= 0 ||
|
||||||
|
(offset + size) > bufObj->Size) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_VALUE, "glTexBufferRange");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (offset % ctx->Const.TextureBufferOffsetAlignment) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||||
|
"glTexBufferRange(invalid offset alignment)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (buffer) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_OPERATION, "glTexBufferRange(buffer %u)",
|
||||||
|
buffer);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
offset = 0;
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
texbufferrange(ctx, target, internalFormat, bufObj, offset, size);
|
||||||
|
}
|
||||||
|
@@ -289,6 +289,10 @@ _mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset,
|
|||||||
extern void GLAPIENTRY
|
extern void GLAPIENTRY
|
||||||
_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer);
|
_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer);
|
||||||
|
|
||||||
|
extern void GLAPIENTRY
|
||||||
|
_mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer,
|
||||||
|
GLintptr offset, GLsizeiptr size);
|
||||||
|
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
|
@@ -1181,6 +1181,18 @@ get_tex_level_parameter_buffer(struct gl_context *ctx,
|
|||||||
*params = _mesa_get_format_bits(texFormat, pname);
|
*params = _mesa_get_format_bits(texFormat, pname);
|
||||||
break;
|
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 */
|
/* GL_ARB_texture_compression */
|
||||||
case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
|
case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
|
||||||
/* Always illegal for GL_TEXTURE_BUFFER */
|
/* Always illegal for GL_TEXTURE_BUFFER */
|
||||||
|
Reference in New Issue
Block a user