[Mesa-dev] [PATCH 5/6] main: Refactor Tex[ture]Buffer[Range].
Laura Ekstrand
laura at jlekstrand.net
Fri Feb 27 16:07:16 PST 2015
Uses _mesa_lookup_bufferobj_err to clean up buffer object retrieval. Moves
error checking statements into separate functions to allow code sharing
between traditional and ARB_direct_state_access entry points.
---
src/mesa/main/teximage.c | 201 ++++++++++++++++++++++++++++++-----------------
src/mesa/main/teximage.h | 6 +-
2 files changed, 132 insertions(+), 75 deletions(-)
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index d454dd9..9853bc0 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -5301,24 +5301,34 @@ _mesa_validate_texbuffer_format(const struct gl_context *ctx,
void
_mesa_texture_buffer_range(struct gl_context *ctx,
- struct gl_texture_object *texObj, GLenum target,
+ struct gl_texture_object *texObj,
GLenum internalFormat,
struct gl_buffer_object *bufObj,
- GLintptr offset, GLsizeiptr size, bool range,
- bool dsa)
+ GLintptr offset, GLsizeiptr size,
+ const char *caller)
{
mesa_format format;
- FLUSH_VERTICES(ctx, 0);
+ /* 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,
+ "%s(ARB_texture_buffer_object is not"
+ " implemented for the compatibility profile)", caller);
+ return;
+ }
format = _mesa_validate_texbuffer_format(ctx, internalFormat);
if (format == MESA_FORMAT_NONE) {
_mesa_error(ctx, GL_INVALID_ENUM,
- "glTex%sBuffer%s(internalFormat 0x%x)", dsa ? "ture" : "",
- range ? "Range" : "", internalFormat);
+ "%s(internalFormat 0x%x)", caller, internalFormat);
return;
}
+ FLUSH_VERTICES(ctx, 0);
+
_mesa_lock_texture(ctx, texObj);
{
_mesa_reference_buffer_object(ctx, &texObj->BufferObject, bufObj);
@@ -5337,6 +5347,75 @@ _mesa_texture_buffer_range(struct gl_context *ctx,
}
+/**
+ * Make sure the texture buffer target is GL_TEXTURE_BUFFER.
+ * Return true if it is, and return false if it is not
+ * (and throw INVALID ENUM as dictated in the OpenGL 4.5
+ * core spec, 02.02.2015, PDF page 245).
+ */
+static bool
+check_texture_buffer_target(struct gl_context *ctx, GLenum target,
+ const char *caller)
+{
+ if (target != GL_TEXTURE_BUFFER_ARB) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "%s(texture target is not GL_TEXTURE_BUFFER)", caller);
+ return false;
+ }
+ else
+ return true;
+}
+
+/**
+ * Check for errors related to the texture buffer range.
+ * Return false if errors are found, true if none are found.
+ */
+static bool
+check_texture_buffer_range(struct gl_context *ctx,
+ struct gl_buffer_object *bufObj,
+ GLintptr offset, GLsizeiptr size,
+ const char *caller)
+{
+ /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
+ * Textures (PDF page 245):
+ * "An INVALID_VALUE error is generated if offset is negative, if
+ * size is less than or equal to zero, or if offset + size is greater
+ * than the value of BUFFER_SIZE for the buffer bound to target."
+ */
+ if (offset < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset=%d < 0)", caller,
+ (int) offset);
+ return false;
+ }
+
+ if (size <= 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d <= 0)", caller,
+ (int) size);
+ return false;
+ }
+
+ if (offset + size > bufObj->Size) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(offset=%d + size=%d > buffer_size=%d)", caller,
+ (int) offset, (int) size, (int) bufObj->Size);
+ return false;
+ }
+
+ /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
+ * Textures (PDF page 245):
+ * "An INVALID_VALUE error is generated if offset is not an integer
+ * multiple of the value of TEXTURE_BUFFER_OFFSET_ALIGNMENT."
+ */
+ if (offset % ctx->Const.TextureBufferOffsetAlignment) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(invalid offset alignment)", caller);
+ return false;
+ }
+
+ return true;
+}
+
+
/** GL_ARB_texture_buffer_object */
void GLAPIENTRY
_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer)
@@ -5346,33 +5425,26 @@ _mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer)
GET_CURRENT_CONTEXT(ctx);
- /* Need to catch this before it gets to _mesa_get_current_tex_object */
- if (target != GL_TEXTURE_BUFFER_ARB) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(target)");
- return;
- }
-
- /* NOTE: ARB_texture_buffer_object has interactions with
- * the compatibility profile that are not implemented.
+ /* Need to catch a bad target before it gets to
+ * _mesa_get_current_tex_object.
*/
- if (!(ctx->API == API_OPENGL_CORE &&
- ctx->Extensions.ARB_texture_buffer_object)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer");
+ if (!check_texture_buffer_target(ctx, target, "glTexBuffer"))
return;
- }
- bufObj = _mesa_lookup_bufferobj(ctx, buffer);
- if (!bufObj && buffer) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer(buffer %u)", buffer);
- return;
+ if (buffer) {
+ bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTexBuffer");
+ if (!bufObj)
+ return;
}
+ else
+ bufObj = NULL;
texObj = _mesa_get_current_tex_object(ctx, target);
if (!texObj)
return;
- _mesa_texture_buffer_range(ctx, texObj, target, internalFormat, bufObj, 0,
- buffer ? -1 : 0, false, false);
+ _mesa_texture_buffer_range(ctx, texObj, internalFormat, bufObj, 0,
+ buffer ? -1 : 0, "glTexBuffer");
}
@@ -5386,46 +5458,41 @@ _mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer,
GET_CURRENT_CONTEXT(ctx);
- /* Need to catch this before it gets to _mesa_get_current_tex_object */
- if (target != GL_TEXTURE_BUFFER_ARB) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glTexBufferRange(target)");
- return;
- }
-
- if (!(ctx->API == API_OPENGL_CORE &&
- ctx->Extensions.ARB_texture_buffer_range)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBufferRange");
+ /* Need to catch a bad target before it gets to
+ * _mesa_get_current_tex_object.
+ */
+ if (!check_texture_buffer_target(ctx, target, "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");
+ if (buffer) {
+ bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTexBufferRange");
+ if (!bufObj)
return;
- }
- if (offset % ctx->Const.TextureBufferOffsetAlignment) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexBufferRange(invalid offset alignment)");
+
+ if (!check_texture_buffer_range(ctx, bufObj, offset, size,
+ "glTexBufferRange"))
return;
- }
- } else if (buffer) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBufferRange(buffer %u)",
- buffer);
- return;
+
} else {
+
+ /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
+ * Textures (PDF page 254):
+ * "If buffer is zero, then any buffer object attached to the buffer
+ * texture is detached, the values offset and size are ignored and
+ * the state for offset and size for the buffer texture are reset to
+ * zero."
+ */
offset = 0;
size = 0;
+ bufObj = NULL;
}
texObj = _mesa_get_current_tex_object(ctx, target);
if (!texObj)
return;
- _mesa_texture_buffer_range(ctx, texObj, target, internalFormat, bufObj,
- offset, size, true, false);
+ _mesa_texture_buffer_range(ctx, texObj, internalFormat, bufObj,
+ offset, size, "glTexBufferRange");
}
void GLAPIENTRY
@@ -5436,37 +5503,27 @@ _mesa_TextureBuffer(GLuint texture, GLenum internalFormat, GLuint buffer)
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, "glTextureBuffer");
- return;
- }
-
- bufObj = _mesa_lookup_bufferobj(ctx, buffer);
- if (!bufObj && buffer) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureBuffer(buffer %u)",
- buffer);
- return;
+ if (buffer) {
+ bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTextureBuffer");
+ if (!bufObj)
+ return;
}
+ else
+ bufObj = NULL;
/* Get the texture object by Name. */
- texObj = _mesa_lookup_texture_err(ctx, texture,
- "glTextureBuffer(texture)");
+ texObj = _mesa_lookup_texture_err(ctx, texture, "glTextureBuffer");
if (!texObj)
return;
- if (texObj->Target != GL_TEXTURE_BUFFER_ARB) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glTextureBuffer(target)");
+ if (!check_texture_buffer_target(ctx, texObj->Target, "glTextureBuffer"))
return;
- }
- _mesa_texture_buffer_range(ctx, texObj, texObj->Target, internalFormat,
- bufObj, 0, buffer ? -1 : 0, false, true);
+ _mesa_texture_buffer_range(ctx, texObj, internalFormat,
+ bufObj, 0, buffer ? -1 : 0, "glTextureBuffer");
}
+
static GLboolean
is_renderable_texture_format(struct gl_context *ctx, GLenum internalformat)
{
diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h
index 9468650..db6b648 100644
--- a/src/mesa/main/teximage.h
+++ b/src/mesa/main/teximage.h
@@ -209,11 +209,11 @@ _mesa_texture_image_multisample(struct gl_context *ctx, GLuint dims,
extern void
_mesa_texture_buffer_range(struct gl_context *ctx,
- struct gl_texture_object *texObj, GLenum target,
+ struct gl_texture_object *texObj,
GLenum internalFormat,
struct gl_buffer_object *bufObj,
- GLintptr offset, GLsizeiptr size, bool range,
- bool dsa);
+ GLintptr offset, GLsizeiptr size,
+ const char *caller);
/*@}*/
--
2.1.0
More information about the mesa-dev
mailing list