diff options
author | Roland Scheidegger <[email protected]> | 2013-06-25 23:27:04 +0200 |
---|---|---|
committer | Roland Scheidegger <[email protected]> | 2013-06-26 23:17:53 +0200 |
commit | 08203428800554215657f1ebf19d74328103800e (patch) | |
tree | 2ffcdf6192673c70944a0087a114dc7877f49b82 /src/gallium/drivers/llvmpipe/lp_setup.c | |
parent | 3dbba95b72262344b82fba018b7c2c1208754cd2 (diff) |
llvmpipe: rework query logic
Previously lp_rast_begin_query commands were always inserted into each bin,
and re-issued if the scene was restarted, while lp_rast_end_query commands
were executed for each still active query at the end of tile rasterization.
Also, the ps_invocations and vis_counter were set to zero when the respective
command was encountered.
This however cannot work for multiple queries of the same type (note that
occlusion counter and occlusion predicate while different type were also
affected).
So, change the logic to always set the ps_invocations and vis_counter to zero
at the start of tile rasterization, and then use "start" and "end" per-thread
query values when encountering the begin/end query commands instead, which
should work for multiple queries of the same type. This also means queries do
not have to be reissued in a new scene, however they still need to be finished
at end of tile rasterization, so a list of queries still active at the end of
a scene needs to be maintained.
Also while here don't bin the queries which don't do anything in rasterization.
(This change does not actually handle multiple queries of the same type yet,
as the list of active queries is just a simple fixed array and setup can still
only have one query active per type.)
Reviewed-by: Jose Fonseca <[email protected]>
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c')
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup.c | 81 |
1 files changed, 52 insertions, 29 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 6b644460cd3..d2c53255259 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -155,6 +155,23 @@ lp_setup_rasterize_scene( struct lp_setup_context *setup ) struct lp_scene *scene = setup->scene; struct llvmpipe_screen *screen = llvmpipe_screen(scene->pipe->screen); + scene->num_active_queries = 0; + if (setup->active_query[PIPE_QUERY_OCCLUSION_COUNTER]) { + scene->active_queries[scene->num_active_queries] = + setup->active_query[PIPE_QUERY_OCCLUSION_COUNTER]; + scene->num_active_queries++; + } + if (setup->active_query[PIPE_QUERY_OCCLUSION_PREDICATE]) { + scene->active_queries[scene->num_active_queries] = + setup->active_query[PIPE_QUERY_OCCLUSION_PREDICATE]; + scene->num_active_queries++; + } + if (setup->active_query[PIPE_QUERY_PIPELINE_STATISTICS]) { + scene->active_queries[scene->num_active_queries] = + setup->active_query[PIPE_QUERY_PIPELINE_STATISTICS]; + scene->num_active_queries++; + } + lp_scene_end_binning(scene); lp_fence_reference(&setup->last_fence, scene->fence); @@ -181,7 +198,6 @@ begin_binning( struct lp_setup_context *setup ) struct lp_scene *scene = setup->scene; boolean need_zsload = FALSE; boolean ok; - unsigned i; assert(scene); assert(scene->fence == NULL); @@ -230,16 +246,6 @@ begin_binning( struct lp_setup_context *setup ) } } - for (i = 0; i < PIPE_QUERY_TYPES; ++i) { - if (setup->active_query[i]) { - ok = lp_scene_bin_everywhere( scene, - LP_RAST_OP_BEGIN_QUERY, - lp_rast_arg_query(setup->active_query[i]) ); - if (!ok) - return FALSE; - } - } - setup->clear.flags = 0; setup->clear.zsmask = 0; setup->clear.zsvalue = 0; @@ -1211,18 +1217,20 @@ void lp_setup_begin_query(struct lp_setup_context *setup, struct llvmpipe_query *pq) { - /* init the query to its beginning state */ - assert(setup->active_query[pq->type] == NULL); set_scene_state(setup, SETUP_ACTIVE, "begin_query"); - setup->active_query[pq->type] = pq; + if (!(pq->type == PIPE_QUERY_OCCLUSION_COUNTER || + pq->type == PIPE_QUERY_OCCLUSION_PREDICATE || + pq->type == PIPE_QUERY_PIPELINE_STATISTICS)) + return; - /* XXX: It is possible that a query is created before the scene - * has been created. This means that setup->scene == NULL resulting - * in the query not being binned and thus is ignored. - */ + /* init the query to its beginning state */ + assert(setup->active_query[pq->type] == NULL); + + setup->active_query[pq->type] = pq; + assert(setup->scene); if (setup->scene) { if (!lp_scene_bin_everywhere(setup->scene, LP_RAST_OP_BEGIN_QUERY, @@ -1249,31 +1257,46 @@ lp_setup_end_query(struct lp_setup_context *setup, struct llvmpipe_query *pq) { set_scene_state(setup, SETUP_ACTIVE, "end_query"); - if (pq->type != PIPE_QUERY_TIMESTAMP && pq->type != PIPE_QUERY_GPU_FINISHED) { + if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER || + pq->type == PIPE_QUERY_OCCLUSION_PREDICATE || + pq->type == PIPE_QUERY_PIPELINE_STATISTICS) { assert(setup->active_query[pq->type] == pq); - setup->active_query[pq->type] = NULL; } - /* Setup will automatically re-issue any query which carried over a - * scene boundary, and the rasterizer automatically "ends" queries - * which are active at the end of a scene, so there is no need to - * retry this commands on failure. - */ + assert(setup->scene); if (setup->scene) { /* pq->fence should be the fence of the *last* scene which * contributed to the query result. */ lp_fence_reference(&pq->fence, setup->scene->fence); - if (!lp_scene_bin_everywhere(setup->scene, - LP_RAST_OP_END_QUERY, - lp_rast_arg_query(pq))) { - lp_setup_flush(setup, NULL, __FUNCTION__); + if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER || + pq->type == PIPE_QUERY_OCCLUSION_PREDICATE || + pq->type == PIPE_QUERY_PIPELINE_STATISTICS || + pq->type == PIPE_QUERY_TIMESTAMP) { + if (!lp_scene_bin_everywhere(setup->scene, + LP_RAST_OP_END_QUERY, + lp_rast_arg_query(pq))) { + if (!lp_setup_flush_and_restart(setup)) + goto fail; + + if (!lp_scene_bin_everywhere(setup->scene, + LP_RAST_OP_END_QUERY, + lp_rast_arg_query(pq))) { + goto fail; + } + } } } else { lp_fence_reference(&pq->fence, setup->last_fence); } + +fail: + /* Need to do this now not earlier since it still needs to be marked as + * active when binning it would cause a flush. + */ + setup->active_query[pq->type] = NULL; } |