[Mesa-dev] [PATCH 5/8] mesa: Store GetQueryObject{ui64}v results in QueryBuffer if bound
Rafal Mielniczuk
rafal.mielniczuk2 at gmail.com
Wed Mar 19 14:30:47 PDT 2014
If QueryBuffer is bound, store query result in it at given offset,
otherwise store query result in client memory pointer
Signed-off-by: Rafal Mielniczuk <rafal.mielniczuk2 at gmail.com>
---
src/mesa/main/queryobj.c | 88 ++++++++++++++++++++++++++++++++++++++----------
1 file changed, 71 insertions(+), 17 deletions(-)
diff --git a/src/mesa/main/queryobj.c b/src/mesa/main/queryobj.c
index 66250b6..88e80c4 100644
--- a/src/mesa/main/queryobj.c
+++ b/src/mesa/main/queryobj.c
@@ -187,6 +187,44 @@ get_query_binding_point(struct gl_context *ctx, GLenum target)
}
}
+/**
+ * This function is run by GetQueryObject{ui64}v functions.
+ * It stores the result of the query in QueryBuffer, if it is bound.
+ * Otherwise it just copies the value into params location.
+ */
+static void
+query_store_result(struct gl_context *ctx, void *params,
+ GLuint size, void *data, const char *caller)
+{
+ /* Page 44 of the OpenGL 4.4 spec says:
+ *
+ * "Initially, zero is bound to the QUERY_BUFFER binding point,
+ * indicating that params is a pointer into client memory.
+ * However, if a non-zero buffer object is bound as the current query
+ * result buffer (see section 6.1), then params is treated as an offset
+ * into the designated buffer object."
+ */
+ if (ctx->QueryBuffer != ctx->Shared->NullBufferObj) {
+ GLsizeiptr offset = (GLsizeiptr)params;
+
+ /* ARB_query_buffer_object spec says:
+ *
+ * "An INVALID_OPERATION error is generated if the command would
+ * cause data to be written beyond the bounds of the buffer currently
+ * bound to the QUERY_BUFFER target."
+ */
+ if (offset + size > ctx->QueryBuffer->Size) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(buffer bounds exceeded)", caller);
+ return;
+ }
+
+ ctx->Driver.BufferSubData(ctx, offset, size, data,
+ ctx->QueryBuffer);
+ } else {
+ memcpy(params, data, size);
+ }
+}
void GLAPIENTRY
_mesa_GenQueries(GLsizei n, GLuint *ids)
@@ -599,28 +637,34 @@ _mesa_GetQueryObjectiv(GLuint id, GLenum pname, GLint *params)
break;
//else fall through
case GL_QUERY_RESULT_ARB:
+ {
+ GLint result = 0;
if (!q->Ready)
ctx->Driver.WaitQuery(ctx, q);
/* if result is too large for returned type, clamp to max value */
if (q->Target == GL_ANY_SAMPLES_PASSED
|| q->Target == GL_ANY_SAMPLES_PASSED_CONSERVATIVE) {
if (q->Result)
- *params = GL_TRUE;
+ result = GL_TRUE;
else
- *params = GL_FALSE;
+ result = GL_FALSE;
} else {
if (q->Result > 0x7fffffff) {
- *params = 0x7fffffff;
+ result = 0x7fffffff;
}
else {
- *params = (GLint)q->Result;
+ result = (GLint)q->Result;
}
}
+ query_store_result(ctx, params, sizeof(result), &result,
+ "glGetQueryObjectivARB");
break;
+ }
case GL_QUERY_RESULT_AVAILABLE_ARB:
if (!q->Ready)
ctx->Driver.CheckQuery( ctx, q );
- *params = q->Ready;
+ query_store_result(ctx, params, sizeof(q->Ready), &q->Ready,
+ "glGetQueryObjectivARB");
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectivARB(pname)");
@@ -628,7 +672,6 @@ _mesa_GetQueryObjectiv(GLuint id, GLenum pname, GLint *params)
}
}
-
void GLAPIENTRY
_mesa_GetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
{
@@ -654,28 +697,35 @@ _mesa_GetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
break;
//else fall through
case GL_QUERY_RESULT_ARB:
+ {
+ GLuint result = 0;
if (!q->Ready)
ctx->Driver.WaitQuery(ctx, q);
/* if result is too large for returned type, clamp to max value */
if (q->Target == GL_ANY_SAMPLES_PASSED
|| q->Target == GL_ANY_SAMPLES_PASSED_CONSERVATIVE) {
- if (q->Result)
- *params = GL_TRUE;
- else
- *params = GL_FALSE;
+ if (q->Result) {
+ result = GL_TRUE;
+ } else {
+ result = GL_FALSE;
+ }
} else {
if (q->Result > 0xffffffff) {
- *params = 0xffffffff;
+ result = 0xffffffff;
}
else {
- *params = (GLuint)q->Result;
+ result = (GLuint)q->Result;
}
}
+ query_store_result(ctx, params, sizeof(result), &result,
+ "glGetQueryObjectuivARB");
break;
+ }
case GL_QUERY_RESULT_AVAILABLE_ARB:
if (!q->Ready)
ctx->Driver.CheckQuery( ctx, q );
- *params = q->Ready;
+ query_store_result(ctx, params, sizeof(q->Ready), &q->Ready,
+ "glGetQueryObjectuivARB");;
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectuivARB(pname)");
@@ -714,12 +764,14 @@ _mesa_GetQueryObjecti64v(GLuint id, GLenum pname, GLint64EXT *params)
case GL_QUERY_RESULT_ARB:
if (!q->Ready)
ctx->Driver.WaitQuery(ctx, q);
- *params = q->Result;
+ query_store_result(ctx, params, sizeof(q->Result), &q->Result,
+ "glGetQueryObjecti64vARB");
break;
case GL_QUERY_RESULT_AVAILABLE_ARB:
if (!q->Ready)
ctx->Driver.CheckQuery( ctx, q );
- *params = q->Ready;
+ query_store_result(ctx, params, sizeof(q->Ready), &q->Ready,
+ "glGetQueryObjecti64vARB");
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjecti64vARB(pname)");
@@ -758,12 +810,14 @@ _mesa_GetQueryObjectui64v(GLuint id, GLenum pname, GLuint64EXT *params)
case GL_QUERY_RESULT_ARB:
if (!q->Ready)
ctx->Driver.WaitQuery(ctx, q);
- *params = q->Result;
+ query_store_result(ctx, params, sizeof(q->Result), &q->Result,
+ "glGetQueryObjectui64vARB");
break;
case GL_QUERY_RESULT_AVAILABLE_ARB:
if (!q->Ready)
ctx->Driver.CheckQuery( ctx, q );
- *params = q->Ready;
+ query_store_result(ctx, params, sizeof(q->Ready), &q->Ready,
+ "glGetQueryObjectui64vARB");
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectui64vARB(pname)");
--
1.9.0
More information about the mesa-dev
mailing list