From 1c73afa462763a802e2b076c1842c755c350e30d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 9 Dec 2021 17:14:39 +1000 Subject: [PATCH] mesa/st: merge queryobj code from st into mesa. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This merges all the query object code from st into mesa. Acked-by: Marek Olšák Part-of: --- src/mesa/main/condrender.c | 9 +- src/mesa/main/get.c | 4 +- src/mesa/main/mtypes.h | 7 + src/mesa/main/queryobj.c | 456 +++++++++++++++++++++++++++- src/mesa/main/queryobj.h | 9 +- src/mesa/main/syncobj.c | 1 - src/mesa/meson.build | 2 - src/mesa/state_tracker/st_cb_condrender.c | 4 +- src/mesa/state_tracker/st_cb_queryobj.c | 479 ------------------------------ src/mesa/state_tracker/st_cb_queryobj.h | 78 ----- src/mesa/state_tracker/st_context.c | 1 - 11 files changed, 464 insertions(+), 586 deletions(-) delete mode 100644 src/mesa/state_tracker/st_cb_queryobj.c delete mode 100644 src/mesa/state_tracker/st_cb_queryobj.h diff --git a/src/mesa/main/condrender.c b/src/mesa/main/condrender.c index a119359..db4fde3 100644 --- a/src/mesa/main/condrender.c +++ b/src/mesa/main/condrender.c @@ -36,7 +36,6 @@ #include "mtypes.h" #include "queryobj.h" -#include "state_tracker/st_cb_queryobj.h" #include "state_tracker/st_cb_condrender.h" #include "api_exec_decl.h" @@ -196,27 +195,27 @@ _mesa_check_conditional_render(struct gl_context *ctx) FALLTHROUGH; case GL_QUERY_WAIT: if (!q->Ready) { - st_WaitQuery(ctx, q); + _mesa_wait_query(ctx, q); } return q->Result > 0; case GL_QUERY_BY_REGION_WAIT_INVERTED: FALLTHROUGH; case GL_QUERY_WAIT_INVERTED: if (!q->Ready) { - st_WaitQuery(ctx, q); + _mesa_wait_query(ctx, q); } return q->Result == 0; case GL_QUERY_BY_REGION_NO_WAIT: FALLTHROUGH; case GL_QUERY_NO_WAIT: if (!q->Ready) - st_CheckQuery(ctx, q); + _mesa_check_query(ctx, q); return q->Ready ? (q->Result > 0) : GL_TRUE; case GL_QUERY_BY_REGION_NO_WAIT_INVERTED: FALLTHROUGH; case GL_QUERY_NO_WAIT_INVERTED: if (!q->Ready) - st_CheckQuery(ctx, q); + _mesa_check_query(ctx, q); return q->Ready ? (q->Result == 0) : GL_TRUE; default: _mesa_problem(ctx, "Bad cond render mode %s in " diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index f1eb650..97b1229 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -35,6 +35,7 @@ #include "macros.h" #include "multisample.h" #include "mtypes.h" +#include "queryobj.h" #include "spirv_extensions.h" #include "state.h" #include "texcompress.h" @@ -44,7 +45,6 @@ #include "stencil.h" #include "version.h" -#include "state_tracker/st_cb_queryobj.h" #include "state_tracker/st_context.h" #include "api_exec_decl.h" @@ -1187,7 +1187,7 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu break; /* GL_ARB_timer_query */ case GL_TIMESTAMP: - v->value_int64 = st_GetTimestamp(ctx); + v->value_int64 = _mesa_get_timestamp(ctx); break; /* GL_KHR_DEBUG */ case GL_DEBUG_OUTPUT: diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index f4f9bfb..da98588 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2208,6 +2208,13 @@ struct gl_query_object GLboolean Ready; /**< result is ready? */ GLboolean EverBound;/**< has query object ever been bound */ GLuint Stream; /**< The stream */ + + struct pipe_query *pq; + + /* Begin TIMESTAMP query for GL_TIME_ELAPSED_EXT queries */ + struct pipe_query *pq_begin; + + unsigned type; /**< PIPE_QUERY_x */ }; diff --git a/src/mesa/main/queryobj.c b/src/mesa/main/queryobj.c index e9d79a3..98faae8 100644 --- a/src/mesa/main/queryobj.c +++ b/src/mesa/main/queryobj.c @@ -35,8 +35,436 @@ #include "pipe/p_screen.h" #include "util/u_memory.h" -#include "state_tracker/st_cb_queryobj.h" #include "api_exec_decl.h" +#include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_cb_bitmap.h" + + +static struct gl_query_object * +new_query_object(struct gl_context *ctx, GLuint id) +{ + struct gl_query_object *q = CALLOC_STRUCT(gl_query_object); + if (q) { + q->Id = id; + q->Ready = GL_TRUE; + q->pq = NULL; + q->type = PIPE_QUERY_TYPES; /* an invalid value */ + return q; + } + return NULL; +} + + +static void +free_queries(struct pipe_context *pipe, struct gl_query_object *q) +{ + if (q->pq) { + pipe->destroy_query(pipe, q->pq); + q->pq = NULL; + } + + if (q->pq_begin) { + pipe->destroy_query(pipe, q->pq_begin); + q->pq_begin = NULL; + } +} + + +static void +delete_query(struct gl_context *ctx, struct gl_query_object *q) +{ + struct pipe_context *pipe = ctx->pipe; + + free_queries(pipe, q); + free(q->Label); + FREE(q); +} + +static int +target_to_index(const struct st_context *st, const struct gl_query_object *q) +{ + if (q->Target == GL_PRIMITIVES_GENERATED || + q->Target == GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN || + q->Target == GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB) + return q->Stream; + + if (st->has_single_pipe_stat) { + switch (q->Target) { + case GL_VERTICES_SUBMITTED_ARB: + return PIPE_STAT_QUERY_IA_VERTICES; + case GL_PRIMITIVES_SUBMITTED_ARB: + return PIPE_STAT_QUERY_IA_PRIMITIVES; + case GL_VERTEX_SHADER_INVOCATIONS_ARB: + return PIPE_STAT_QUERY_VS_INVOCATIONS; + case GL_GEOMETRY_SHADER_INVOCATIONS: + return PIPE_STAT_QUERY_GS_INVOCATIONS; + case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: + return PIPE_STAT_QUERY_GS_PRIMITIVES; + case GL_CLIPPING_INPUT_PRIMITIVES_ARB: + return PIPE_STAT_QUERY_C_INVOCATIONS; + case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: + return PIPE_STAT_QUERY_C_PRIMITIVES; + case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: + return PIPE_STAT_QUERY_PS_INVOCATIONS; + case GL_TESS_CONTROL_SHADER_PATCHES_ARB: + return PIPE_STAT_QUERY_HS_INVOCATIONS; + case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: + return PIPE_STAT_QUERY_DS_INVOCATIONS; + case GL_COMPUTE_SHADER_INVOCATIONS_ARB: + return PIPE_STAT_QUERY_CS_INVOCATIONS; + default: + break; + } + } + + return 0; +} + +static void +begin_query(struct gl_context *ctx, struct gl_query_object *q) +{ + struct st_context *st = st_context(ctx); + struct pipe_context *pipe = ctx->pipe; + unsigned type; + bool ret = false; + + st_flush_bitmap_cache(st_context(ctx)); + + /* convert GL query type to Gallium query type */ + switch (q->Target) { + case GL_ANY_SAMPLES_PASSED: + type = PIPE_QUERY_OCCLUSION_PREDICATE; + break; + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: + type = PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE; + break; + case GL_SAMPLES_PASSED_ARB: + type = PIPE_QUERY_OCCLUSION_COUNTER; + break; + case GL_PRIMITIVES_GENERATED: + type = PIPE_QUERY_PRIMITIVES_GENERATED; + break; + case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + type = PIPE_QUERY_PRIMITIVES_EMITTED; + break; + case GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB: + type = PIPE_QUERY_SO_OVERFLOW_PREDICATE; + break; + case GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB: + type = PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE; + break; + case GL_TIME_ELAPSED: + if (st->has_time_elapsed) + type = PIPE_QUERY_TIME_ELAPSED; + else + type = PIPE_QUERY_TIMESTAMP; + break; + case GL_VERTICES_SUBMITTED_ARB: + case GL_PRIMITIVES_SUBMITTED_ARB: + case GL_VERTEX_SHADER_INVOCATIONS_ARB: + case GL_TESS_CONTROL_SHADER_PATCHES_ARB: + case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: + case GL_GEOMETRY_SHADER_INVOCATIONS: + case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: + case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: + case GL_COMPUTE_SHADER_INVOCATIONS_ARB: + case GL_CLIPPING_INPUT_PRIMITIVES_ARB: + case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: + type = st->has_single_pipe_stat ? PIPE_QUERY_PIPELINE_STATISTICS_SINGLE + : PIPE_QUERY_PIPELINE_STATISTICS; + break; + default: + assert(0 && "unexpected query target in st_BeginQuery()"); + return; + } + + if (q->type != type) { + /* free old query of different type */ + free_queries(pipe, q); + q->type = PIPE_QUERY_TYPES; /* an invalid value */ + } + + if (q->Target == GL_TIME_ELAPSED && + type == PIPE_QUERY_TIMESTAMP) { + /* Determine time elapsed by emitting two timestamp queries. */ + if (!q->pq_begin) { + q->pq_begin = pipe->create_query(pipe, type, 0); + q->type = type; + } + if (q->pq_begin) + ret = pipe->end_query(pipe, q->pq_begin); + } else { + if (!q->pq) { + q->pq = pipe->create_query(pipe, type, target_to_index(st, q)); + q->type = type; + } + if (q->pq) + ret = pipe->begin_query(pipe, q->pq); + } + + if (!ret) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBeginQuery"); + + free_queries(pipe, q); + q->Active = GL_FALSE; + return; + } + + if (q->type != PIPE_QUERY_TIMESTAMP) + st->active_queries++; + + assert(q->type == type); +} + + +static void +end_query(struct gl_context *ctx, struct gl_query_object *q) +{ + struct st_context *st = st_context(ctx); + struct pipe_context *pipe = ctx->pipe; + bool ret = false; + + st_flush_bitmap_cache(st_context(ctx)); + + if ((q->Target == GL_TIMESTAMP || + q->Target == GL_TIME_ELAPSED) && + !q->pq) { + q->pq = pipe->create_query(pipe, PIPE_QUERY_TIMESTAMP, 0); + q->type = PIPE_QUERY_TIMESTAMP; + } + + if (q->pq) + ret = pipe->end_query(pipe, q->pq); + + if (!ret) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEndQuery"); + return; + } + + if (q->type != PIPE_QUERY_TIMESTAMP) + st->active_queries--; +} + + +static boolean +get_query_result(struct pipe_context *pipe, + struct gl_query_object *q, + boolean wait) +{ + union pipe_query_result data; + + if (!q->pq) { + /* Only needed in case we failed to allocate the gallium query earlier. + * Return TRUE so we don't spin on this forever. + */ + return TRUE; + } + + if (!pipe->get_query_result(pipe, q->pq, wait, &data)) + return FALSE; + + switch (q->type) { + case PIPE_QUERY_PIPELINE_STATISTICS: + switch (q->Target) { + case GL_VERTICES_SUBMITTED_ARB: + q->Result = data.pipeline_statistics.ia_vertices; + break; + case GL_PRIMITIVES_SUBMITTED_ARB: + q->Result = data.pipeline_statistics.ia_primitives; + break; + case GL_VERTEX_SHADER_INVOCATIONS_ARB: + q->Result = data.pipeline_statistics.vs_invocations; + break; + case GL_TESS_CONTROL_SHADER_PATCHES_ARB: + q->Result = data.pipeline_statistics.hs_invocations; + break; + case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: + q->Result = data.pipeline_statistics.ds_invocations; + break; + case GL_GEOMETRY_SHADER_INVOCATIONS: + q->Result = data.pipeline_statistics.gs_invocations; + break; + case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: + q->Result = data.pipeline_statistics.gs_primitives; + break; + case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: + q->Result = data.pipeline_statistics.ps_invocations; + break; + case GL_COMPUTE_SHADER_INVOCATIONS_ARB: + q->Result = data.pipeline_statistics.cs_invocations; + break; + case GL_CLIPPING_INPUT_PRIMITIVES_ARB: + q->Result = data.pipeline_statistics.c_invocations; + break; + case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: + q->Result = data.pipeline_statistics.c_primitives; + break; + default: + unreachable("invalid pipeline statistics counter"); + } + break; + case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: + case PIPE_QUERY_SO_OVERFLOW_PREDICATE: + case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE: + q->Result = !!data.b; + break; + default: + q->Result = data.u64; + break; + } + + if (q->Target == GL_TIME_ELAPSED && + q->type == PIPE_QUERY_TIMESTAMP) { + /* Calculate the elapsed time from the two timestamp queries */ + GLuint64EXT Result0 = 0; + assert(q->pq_begin); + pipe->get_query_result(pipe, q->pq_begin, TRUE, (void *)&Result0); + q->Result -= Result0; + } else { + assert(!q->pq_begin); + } + + return TRUE; +} + + +void +_mesa_wait_query(struct gl_context *ctx, struct gl_query_object *q) +{ + struct pipe_context *pipe = ctx->pipe; + + /* this function should only be called if we don't have a ready result */ + assert(!q->Ready); + + while (!q->Ready && + !get_query_result(pipe, q, TRUE)) + { + /* nothing */ + } + + q->Ready = GL_TRUE; +} + + +void +_mesa_check_query(struct gl_context *ctx, struct gl_query_object *q) +{ + struct pipe_context *pipe = ctx->pipe; + assert(!q->Ready); /* we should not get called if Ready is TRUE */ + q->Ready = get_query_result(pipe, q, FALSE); +} + + +uint64_t +_mesa_get_timestamp(struct gl_context *ctx) +{ + struct pipe_context *pipe = ctx->pipe; + struct pipe_screen *screen = pipe->screen; + + /* Prefer the per-screen function */ + if (screen->get_timestamp) { + return screen->get_timestamp(screen); + } + else { + /* Fall back to the per-context function */ + assert(pipe->get_timestamp); + return pipe->get_timestamp(pipe); + } +} + +static void +store_query_result(struct gl_context *ctx, struct gl_query_object *q, + struct gl_buffer_object *buf, intptr_t offset, + GLenum pname, GLenum ptype) +{ + struct pipe_context *pipe = ctx->pipe; + boolean wait = pname == GL_QUERY_RESULT; + enum pipe_query_value_type result_type; + int index; + + /* GL_QUERY_TARGET is a bit of an extension since it has nothing to + * do with the GPU end of the query. Write it in "by hand". + */ + if (pname == GL_QUERY_TARGET) { + /* Assume that the data must be LE. The endianness situation wrt CPU and + * GPU is incredibly confusing, but the vast majority of GPUs are + * LE. When a BE one comes along, this needs some form of resolution. + */ + unsigned data[2] = { CPU_TO_LE32(q->Target), 0 }; + pipe_buffer_write(pipe, buf->buffer, offset, + (ptype == GL_INT64_ARB || + ptype == GL_UNSIGNED_INT64_ARB) ? 8 : 4, + data); + return; + } + + switch (ptype) { + case GL_INT: + result_type = PIPE_QUERY_TYPE_I32; + break; + case GL_UNSIGNED_INT: + result_type = PIPE_QUERY_TYPE_U32; + break; + case GL_INT64_ARB: + result_type = PIPE_QUERY_TYPE_I64; + break; + case GL_UNSIGNED_INT64_ARB: + result_type = PIPE_QUERY_TYPE_U64; + break; + default: + unreachable("Unexpected result type"); + } + + if (pname == GL_QUERY_RESULT_AVAILABLE) { + index = -1; + } else if (q->type == PIPE_QUERY_PIPELINE_STATISTICS) { + switch (q->Target) { + case GL_VERTICES_SUBMITTED_ARB: + index = PIPE_STAT_QUERY_IA_VERTICES; + break; + case GL_PRIMITIVES_SUBMITTED_ARB: + index = PIPE_STAT_QUERY_IA_PRIMITIVES; + break; + case GL_VERTEX_SHADER_INVOCATIONS_ARB: + index = PIPE_STAT_QUERY_VS_INVOCATIONS; + break; + case GL_GEOMETRY_SHADER_INVOCATIONS: + index = PIPE_STAT_QUERY_GS_INVOCATIONS; + break; + case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: + index = PIPE_STAT_QUERY_GS_PRIMITIVES; + break; + case GL_CLIPPING_INPUT_PRIMITIVES_ARB: + index = PIPE_STAT_QUERY_C_INVOCATIONS; + break; + case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: + index = PIPE_STAT_QUERY_C_PRIMITIVES; + break; + case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: + index = PIPE_STAT_QUERY_PS_INVOCATIONS; + break; + case GL_TESS_CONTROL_SHADER_PATCHES_ARB: + index = PIPE_STAT_QUERY_HS_INVOCATIONS; + break; + case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: + index = PIPE_STAT_QUERY_DS_INVOCATIONS; + break; + case GL_COMPUTE_SHADER_INVOCATIONS_ARB: + index = PIPE_STAT_QUERY_CS_INVOCATIONS; + break; + default: + unreachable("Unexpected target"); + } + } else { + index = 0; + } + + pipe->get_query_result_resource(pipe, q->pq, wait, result_type, index, + buf->buffer, offset); +} static struct gl_query_object ** get_pipe_stats_binding_point(struct gl_context *ctx, @@ -165,7 +593,7 @@ create_queries(struct gl_context *ctx, GLenum target, GLsizei n, GLuint *ids, GLsizei i; for (i = 0; i < n; i++) { struct gl_query_object *q - = st_NewQueryObject(ctx, ids[i]); + = new_query_object(ctx, ids[i]); if (!q) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); return; @@ -239,10 +667,10 @@ _mesa_DeleteQueries(GLsizei n, const GLuint *ids) *bindpt = NULL; } q->Active = GL_FALSE; - st_EndQuery(ctx, q); + end_query(ctx, q); } _mesa_HashRemoveLocked(ctx->Query.QueryObjects, ids[i]); - st_DeleteQuery(ctx, q); + delete_query(ctx, q); } } } @@ -339,7 +767,7 @@ _mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id) return; } else { /* create new object */ - q = st_NewQueryObject(ctx, id); + q = new_query_object(ctx, id); if (!q) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBeginQuery{Indexed}"); return; @@ -394,7 +822,7 @@ _mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id) /* XXX should probably refcount query objects */ *bindpt = q; - st_BeginQuery(ctx, q); + begin_query(ctx, q); } @@ -440,7 +868,7 @@ _mesa_EndQueryIndexed(GLenum target, GLuint index) } q->Active = GL_FALSE; - st_EndQuery(ctx, q); + end_query(ctx, q); } void GLAPIENTRY @@ -481,7 +909,7 @@ _mesa_QueryCounter(GLuint id, GLenum target) /* XXX the Core profile should throw INVALID_OPERATION here */ /* create new object */ - q = st_NewQueryObject(ctx, id); + q = new_query_object(ctx, id); if (!q) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glQueryCounter"); return; @@ -521,7 +949,7 @@ _mesa_QueryCounter(GLuint id, GLenum target) /* QueryCounter is implemented using EndQuery without BeginQuery * in drivers. This is actually Direct3D and Gallium convention. */ - st_EndQuery(ctx, q); + end_query(ctx, q); } @@ -731,7 +1159,7 @@ get_query_object(struct gl_context *ctx, const char *func, case GL_QUERY_RESULT_NO_WAIT: case GL_QUERY_RESULT_AVAILABLE: case GL_QUERY_TARGET: - st_StoreQueryResult(ctx, q, buf, offset, pname, ptype); + store_query_result(ctx, q, buf, offset, pname, ptype); return; } @@ -741,20 +1169,20 @@ get_query_object(struct gl_context *ctx, const char *func, switch (pname) { case GL_QUERY_RESULT: if (!q->Ready) - st_WaitQuery(ctx, q); + _mesa_wait_query(ctx, q); value = q->Result; break; case GL_QUERY_RESULT_NO_WAIT: if (!_mesa_has_ARB_query_buffer_object(ctx)) goto invalid_enum; - st_CheckQuery(ctx, q); + _mesa_check_query(ctx, q); if (!q->Ready) return; value = q->Result; break; case GL_QUERY_RESULT_AVAILABLE: if (!q->Ready) - st_CheckQuery(ctx, q); + _mesa_check_query(ctx, q); value = q->Ready; break; case GL_QUERY_TARGET: @@ -953,7 +1381,7 @@ delete_queryobj_cb(void *data, void *userData) { struct gl_query_object *q= (struct gl_query_object *) data; struct gl_context *ctx = (struct gl_context *)userData; - st_DeleteQuery(ctx, q); + delete_query(ctx, q); } diff --git a/src/mesa/main/queryobj.h b/src/mesa/main/queryobj.h index 7461f04..63432cc 100644 --- a/src/mesa/main/queryobj.h +++ b/src/mesa/main/queryobj.h @@ -44,4 +44,11 @@ _mesa_init_queryobj(struct gl_context *ctx); extern void _mesa_free_queryobj_data(struct gl_context *ctx); -#endif /* QUERYOBJ_H */ +void +_mesa_wait_query(struct gl_context *ctx, struct gl_query_object *q); +void +_mesa_check_query(struct gl_context *ctx, struct gl_query_object *q); + +uint64_t +_mesa_get_timestamp(struct gl_context *ctx); +#endif diff --git a/src/mesa/main/syncobj.c b/src/mesa/main/syncobj.c index 968a1d5..918604d 100644 --- a/src/mesa/main/syncobj.c +++ b/src/mesa/main/syncobj.c @@ -68,7 +68,6 @@ #include "syncobj.h" -#include "state_tracker/st_cb_syncobj.h" #include "api_exec_decl.h" #include "pipe/p_context.h" diff --git a/src/mesa/meson.build b/src/mesa/meson.build index 46a2d18..23af754 100644 --- a/src/mesa/meson.build +++ b/src/mesa/meson.build @@ -350,8 +350,6 @@ files_libmesa = files( 'state_tracker/st_cb_perfquery.h', 'state_tracker/st_cb_program.c', 'state_tracker/st_cb_program.h', - 'state_tracker/st_cb_queryobj.c', - 'state_tracker/st_cb_queryobj.h', 'state_tracker/st_cb_rasterpos.c', 'state_tracker/st_cb_rasterpos.h', 'state_tracker/st_cb_readpixels.c', diff --git a/src/mesa/state_tracker/st_cb_condrender.c b/src/mesa/state_tracker/st_cb_condrender.c index 6769d8b..ed93ec8 100644 --- a/src/mesa/state_tracker/st_cb_condrender.c +++ b/src/mesa/state_tracker/st_cb_condrender.c @@ -40,7 +40,6 @@ #include "pipe/p_defines.h" #include "cso_cache/cso_context.h" #include "st_context.h" -#include "st_cb_queryobj.h" #include "st_cb_condrender.h" #include "st_cb_bitmap.h" @@ -49,7 +48,6 @@ void st_BeginConditionalRender(struct gl_context *ctx, struct gl_query_object *q, GLenum mode) { - struct st_query_object *stq = st_query_object(q); struct st_context *st = st_context(ctx); uint m; /* Don't invert the condition for rendering by default */ @@ -91,7 +89,7 @@ st_BeginConditionalRender(struct gl_context *ctx, struct gl_query_object *q, m = PIPE_RENDER_COND_WAIT; } - cso_set_render_condition(st->cso_context, stq->pq, inverted, m); + cso_set_render_condition(st->cso_context, q->pq, inverted, m); } void diff --git a/src/mesa/state_tracker/st_cb_queryobj.c b/src/mesa/state_tracker/st_cb_queryobj.c deleted file mode 100644 index 4f96393..0000000 --- a/src/mesa/state_tracker/st_cb_queryobj.c +++ /dev/null @@ -1,479 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * glBegin/EndQuery interface to pipe - * - * \author Brian Paul - */ - - -#include "util/compiler.h" -#include "main/context.h" -#include "main/queryobj.h" - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_screen.h" -#include "util/u_inlines.h" -#include "util/u_memory.h" -#include "st_context.h" -#include "st_cb_queryobj.h" -#include "st_cb_bitmap.h" -#include "st_util.h" - - -struct gl_query_object * -st_NewQueryObject(struct gl_context *ctx, GLuint id) -{ - struct st_query_object *stq = CALLOC_STRUCT(st_query_object); - if (stq) { - stq->base.Id = id; - stq->base.Ready = GL_TRUE; - stq->pq = NULL; - stq->type = PIPE_QUERY_TYPES; /* an invalid value */ - return &stq->base; - } - return NULL; -} - - -static void -free_queries(struct pipe_context *pipe, struct st_query_object *stq) -{ - if (stq->pq) { - pipe->destroy_query(pipe, stq->pq); - stq->pq = NULL; - } - - if (stq->pq_begin) { - pipe->destroy_query(pipe, stq->pq_begin); - stq->pq_begin = NULL; - } -} - - -void -st_DeleteQuery(struct gl_context *ctx, struct gl_query_object *q) -{ - struct pipe_context *pipe = st_context(ctx)->pipe; - struct st_query_object *stq = st_query_object(q); - - free_queries(pipe, stq); - free(stq->base.Label); - FREE(stq); -} - -static int -target_to_index(const struct st_context *st, const struct gl_query_object *q) -{ - if (q->Target == GL_PRIMITIVES_GENERATED || - q->Target == GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN || - q->Target == GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB) - return q->Stream; - - if (st->has_single_pipe_stat) { - switch (q->Target) { - case GL_VERTICES_SUBMITTED_ARB: - return PIPE_STAT_QUERY_IA_VERTICES; - case GL_PRIMITIVES_SUBMITTED_ARB: - return PIPE_STAT_QUERY_IA_PRIMITIVES; - case GL_VERTEX_SHADER_INVOCATIONS_ARB: - return PIPE_STAT_QUERY_VS_INVOCATIONS; - case GL_GEOMETRY_SHADER_INVOCATIONS: - return PIPE_STAT_QUERY_GS_INVOCATIONS; - case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: - return PIPE_STAT_QUERY_GS_PRIMITIVES; - case GL_CLIPPING_INPUT_PRIMITIVES_ARB: - return PIPE_STAT_QUERY_C_INVOCATIONS; - case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: - return PIPE_STAT_QUERY_C_PRIMITIVES; - case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: - return PIPE_STAT_QUERY_PS_INVOCATIONS; - case GL_TESS_CONTROL_SHADER_PATCHES_ARB: - return PIPE_STAT_QUERY_HS_INVOCATIONS; - case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: - return PIPE_STAT_QUERY_DS_INVOCATIONS; - case GL_COMPUTE_SHADER_INVOCATIONS_ARB: - return PIPE_STAT_QUERY_CS_INVOCATIONS; - default: - break; - } - } - - return 0; -} - -void -st_BeginQuery(struct gl_context *ctx, struct gl_query_object *q) -{ - struct st_context *st = st_context(ctx); - struct pipe_context *pipe = st->pipe; - struct st_query_object *stq = st_query_object(q); - unsigned type; - bool ret = false; - - st_flush_bitmap_cache(st_context(ctx)); - - /* convert GL query type to Gallium query type */ - switch (q->Target) { - case GL_ANY_SAMPLES_PASSED: - type = PIPE_QUERY_OCCLUSION_PREDICATE; - break; - case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: - type = PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE; - break; - case GL_SAMPLES_PASSED_ARB: - type = PIPE_QUERY_OCCLUSION_COUNTER; - break; - case GL_PRIMITIVES_GENERATED: - type = PIPE_QUERY_PRIMITIVES_GENERATED; - break; - case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: - type = PIPE_QUERY_PRIMITIVES_EMITTED; - break; - case GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB: - type = PIPE_QUERY_SO_OVERFLOW_PREDICATE; - break; - case GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB: - type = PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE; - break; - case GL_TIME_ELAPSED: - if (st->has_time_elapsed) - type = PIPE_QUERY_TIME_ELAPSED; - else - type = PIPE_QUERY_TIMESTAMP; - break; - case GL_VERTICES_SUBMITTED_ARB: - case GL_PRIMITIVES_SUBMITTED_ARB: - case GL_VERTEX_SHADER_INVOCATIONS_ARB: - case GL_TESS_CONTROL_SHADER_PATCHES_ARB: - case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: - case GL_GEOMETRY_SHADER_INVOCATIONS: - case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: - case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: - case GL_COMPUTE_SHADER_INVOCATIONS_ARB: - case GL_CLIPPING_INPUT_PRIMITIVES_ARB: - case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: - type = st->has_single_pipe_stat ? PIPE_QUERY_PIPELINE_STATISTICS_SINGLE - : PIPE_QUERY_PIPELINE_STATISTICS; - break; - default: - assert(0 && "unexpected query target in st_BeginQuery()"); - return; - } - - if (stq->type != type) { - /* free old query of different type */ - free_queries(pipe, stq); - stq->type = PIPE_QUERY_TYPES; /* an invalid value */ - } - - if (q->Target == GL_TIME_ELAPSED && - type == PIPE_QUERY_TIMESTAMP) { - /* Determine time elapsed by emitting two timestamp queries. */ - if (!stq->pq_begin) { - stq->pq_begin = pipe->create_query(pipe, type, 0); - stq->type = type; - } - if (stq->pq_begin) - ret = pipe->end_query(pipe, stq->pq_begin); - } else { - if (!stq->pq) { - stq->pq = pipe->create_query(pipe, type, target_to_index(st, q)); - stq->type = type; - } - if (stq->pq) - ret = pipe->begin_query(pipe, stq->pq); - } - - if (!ret) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBeginQuery"); - - free_queries(pipe, stq); - q->Active = GL_FALSE; - return; - } - - if (stq->type != PIPE_QUERY_TIMESTAMP) - st->active_queries++; - - assert(stq->type == type); -} - - -void -st_EndQuery(struct gl_context *ctx, struct gl_query_object *q) -{ - struct st_context *st = st_context(ctx); - struct pipe_context *pipe = st->pipe; - struct st_query_object *stq = st_query_object(q); - bool ret = false; - - st_flush_bitmap_cache(st_context(ctx)); - - if ((q->Target == GL_TIMESTAMP || - q->Target == GL_TIME_ELAPSED) && - !stq->pq) { - stq->pq = pipe->create_query(pipe, PIPE_QUERY_TIMESTAMP, 0); - stq->type = PIPE_QUERY_TIMESTAMP; - } - - if (stq->pq) - ret = pipe->end_query(pipe, stq->pq); - - if (!ret) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEndQuery"); - return; - } - - if (stq->type != PIPE_QUERY_TIMESTAMP) - st->active_queries--; -} - - -static boolean -get_query_result(struct pipe_context *pipe, - struct st_query_object *stq, - boolean wait) -{ - union pipe_query_result data; - - if (!stq->pq) { - /* Only needed in case we failed to allocate the gallium query earlier. - * Return TRUE so we don't spin on this forever. - */ - return TRUE; - } - - if (!pipe->get_query_result(pipe, stq->pq, wait, &data)) - return FALSE; - - switch (stq->type) { - case PIPE_QUERY_PIPELINE_STATISTICS: - switch (stq->base.Target) { - case GL_VERTICES_SUBMITTED_ARB: - stq->base.Result = data.pipeline_statistics.ia_vertices; - break; - case GL_PRIMITIVES_SUBMITTED_ARB: - stq->base.Result = data.pipeline_statistics.ia_primitives; - break; - case GL_VERTEX_SHADER_INVOCATIONS_ARB: - stq->base.Result = data.pipeline_statistics.vs_invocations; - break; - case GL_TESS_CONTROL_SHADER_PATCHES_ARB: - stq->base.Result = data.pipeline_statistics.hs_invocations; - break; - case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: - stq->base.Result = data.pipeline_statistics.ds_invocations; - break; - case GL_GEOMETRY_SHADER_INVOCATIONS: - stq->base.Result = data.pipeline_statistics.gs_invocations; - break; - case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: - stq->base.Result = data.pipeline_statistics.gs_primitives; - break; - case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: - stq->base.Result = data.pipeline_statistics.ps_invocations; - break; - case GL_COMPUTE_SHADER_INVOCATIONS_ARB: - stq->base.Result = data.pipeline_statistics.cs_invocations; - break; - case GL_CLIPPING_INPUT_PRIMITIVES_ARB: - stq->base.Result = data.pipeline_statistics.c_invocations; - break; - case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: - stq->base.Result = data.pipeline_statistics.c_primitives; - break; - default: - unreachable("invalid pipeline statistics counter"); - } - break; - case PIPE_QUERY_OCCLUSION_PREDICATE: - case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: - case PIPE_QUERY_SO_OVERFLOW_PREDICATE: - case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE: - stq->base.Result = !!data.b; - break; - default: - stq->base.Result = data.u64; - break; - } - - if (stq->base.Target == GL_TIME_ELAPSED && - stq->type == PIPE_QUERY_TIMESTAMP) { - /* Calculate the elapsed time from the two timestamp queries */ - GLuint64EXT Result0 = 0; - assert(stq->pq_begin); - pipe->get_query_result(pipe, stq->pq_begin, TRUE, (void *)&Result0); - stq->base.Result -= Result0; - } else { - assert(!stq->pq_begin); - } - - return TRUE; -} - - -void -st_WaitQuery(struct gl_context *ctx, struct gl_query_object *q) -{ - struct pipe_context *pipe = st_context(ctx)->pipe; - struct st_query_object *stq = st_query_object(q); - - /* this function should only be called if we don't have a ready result */ - assert(!stq->base.Ready); - - while (!stq->base.Ready && - !get_query_result(pipe, stq, TRUE)) - { - /* nothing */ - } - - q->Ready = GL_TRUE; -} - - -void -st_CheckQuery(struct gl_context *ctx, struct gl_query_object *q) -{ - struct pipe_context *pipe = st_context(ctx)->pipe; - struct st_query_object *stq = st_query_object(q); - assert(!q->Ready); /* we should not get called if Ready is TRUE */ - q->Ready = get_query_result(pipe, stq, FALSE); -} - - -uint64_t -st_GetTimestamp(struct gl_context *ctx) -{ - struct pipe_context *pipe = st_context(ctx)->pipe; - struct pipe_screen *screen = st_context(ctx)->screen; - - /* Prefer the per-screen function */ - if (screen->get_timestamp) { - return screen->get_timestamp(screen); - } - else { - /* Fall back to the per-context function */ - assert(pipe->get_timestamp); - return pipe->get_timestamp(pipe); - } -} - -void -st_StoreQueryResult(struct gl_context *ctx, struct gl_query_object *q, - struct gl_buffer_object *buf, intptr_t offset, - GLenum pname, GLenum ptype) -{ - struct pipe_context *pipe = st_context(ctx)->pipe; - struct st_query_object *stq = st_query_object(q); - boolean wait = pname == GL_QUERY_RESULT; - enum pipe_query_value_type result_type; - int index; - - /* GL_QUERY_TARGET is a bit of an extension since it has nothing to - * do with the GPU end of the query. Write it in "by hand". - */ - if (pname == GL_QUERY_TARGET) { - /* Assume that the data must be LE. The endianness situation wrt CPU and - * GPU is incredibly confusing, but the vast majority of GPUs are - * LE. When a BE one comes along, this needs some form of resolution. - */ - unsigned data[2] = { CPU_TO_LE32(q->Target), 0 }; - pipe_buffer_write(pipe, buf->buffer, offset, - (ptype == GL_INT64_ARB || - ptype == GL_UNSIGNED_INT64_ARB) ? 8 : 4, - data); - return; - } - - switch (ptype) { - case GL_INT: - result_type = PIPE_QUERY_TYPE_I32; - break; - case GL_UNSIGNED_INT: - result_type = PIPE_QUERY_TYPE_U32; - break; - case GL_INT64_ARB: - result_type = PIPE_QUERY_TYPE_I64; - break; - case GL_UNSIGNED_INT64_ARB: - result_type = PIPE_QUERY_TYPE_U64; - break; - default: - unreachable("Unexpected result type"); - } - - if (pname == GL_QUERY_RESULT_AVAILABLE) { - index = -1; - } else if (stq->type == PIPE_QUERY_PIPELINE_STATISTICS) { - switch (q->Target) { - case GL_VERTICES_SUBMITTED_ARB: - index = PIPE_STAT_QUERY_IA_VERTICES; - break; - case GL_PRIMITIVES_SUBMITTED_ARB: - index = PIPE_STAT_QUERY_IA_PRIMITIVES; - break; - case GL_VERTEX_SHADER_INVOCATIONS_ARB: - index = PIPE_STAT_QUERY_VS_INVOCATIONS; - break; - case GL_GEOMETRY_SHADER_INVOCATIONS: - index = PIPE_STAT_QUERY_GS_INVOCATIONS; - break; - case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: - index = PIPE_STAT_QUERY_GS_PRIMITIVES; - break; - case GL_CLIPPING_INPUT_PRIMITIVES_ARB: - index = PIPE_STAT_QUERY_C_INVOCATIONS; - break; - case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: - index = PIPE_STAT_QUERY_C_PRIMITIVES; - break; - case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: - index = PIPE_STAT_QUERY_PS_INVOCATIONS; - break; - case GL_TESS_CONTROL_SHADER_PATCHES_ARB: - index = PIPE_STAT_QUERY_HS_INVOCATIONS; - break; - case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: - index = PIPE_STAT_QUERY_DS_INVOCATIONS; - break; - case GL_COMPUTE_SHADER_INVOCATIONS_ARB: - index = PIPE_STAT_QUERY_CS_INVOCATIONS; - break; - default: - unreachable("Unexpected target"); - } - } else { - index = 0; - } - - pipe->get_query_result_resource(pipe, stq->pq, wait, result_type, index, - buf->buffer, offset); -} diff --git a/src/mesa/state_tracker/st_cb_queryobj.h b/src/mesa/state_tracker/st_cb_queryobj.h deleted file mode 100644 index e0ef14d..0000000 --- a/src/mesa/state_tracker/st_cb_queryobj.h +++ /dev/null @@ -1,78 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef ST_CB_QUERYOBJ_H -#define ST_CB_QUERYOBJ_H - - -#include "main/mtypes.h" - -/** - * Subclass of gl_query_object - */ -struct st_query_object -{ - struct gl_query_object base; - struct pipe_query *pq; - - /* Begin TIMESTAMP query for GL_TIME_ELAPSED_EXT queries */ - struct pipe_query *pq_begin; - - unsigned type; /**< PIPE_QUERY_x */ -}; - - -/** - * Cast wrapper - */ -static inline struct st_query_object * -st_query_object(struct gl_query_object *q) -{ - return (struct st_query_object *) q; -} - - -struct gl_query_object * -st_NewQueryObject(struct gl_context *ctx, GLuint id); -void -st_DeleteQuery(struct gl_context *ctx, struct gl_query_object *q); -void -st_BeginQuery(struct gl_context *ctx, struct gl_query_object *q); -void -st_EndQuery(struct gl_context *ctx, struct gl_query_object *q); -void -st_WaitQuery(struct gl_context *ctx, struct gl_query_object *q); -void -st_CheckQuery(struct gl_context *ctx, struct gl_query_object *q); -void -st_StoreQueryResult(struct gl_context *ctx, struct gl_query_object *q, - struct gl_buffer_object *buf, intptr_t offset, - GLenum pname, GLenum ptype); - -uint64_t -st_GetTimestamp(struct gl_context *ctx); -#endif diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 364ffa5..b477015 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -50,7 +50,6 @@ #include "st_cb_perfmon.h" #include "st_cb_perfquery.h" #include "st_cb_program.h" -#include "st_cb_queryobj.h" #include "st_cb_flush.h" #include "st_atom.h" #include "st_draw.h" -- 2.7.4