llvmpipe: add support for nested / overlapping queries
OpenGL doesn't support this but d3d10 does. It is a bit of a pain as it is necessary to keep track of queries still active at the end of a scene, which is also why I cheat a bit and limit the amount of simultaneously active queries to (arbitrary) 16 (simplifies things because don't have to deal with a real list that way). I can't think of a reason why you'd really want large numbers of overlapping/nested queries so it is hopefully fine. (This only affects queries which need to be binned.) v2: don't copy remainder of array when deleting an entry simply replace the deleted entry with the last one (order doesn't matter). Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
This commit is contained in:
parent
0820342880
commit
2e4da1f594
10 changed files with 45 additions and 40 deletions
|
|
@ -97,9 +97,9 @@ struct llvmpipe_context {
|
|||
struct pipe_query_data_pipeline_statistics pipeline_statistics;
|
||||
unsigned active_statistics_queries;
|
||||
|
||||
unsigned dirty; /**< Mask of LP_NEW_x flags */
|
||||
unsigned active_occlusion_queries;
|
||||
|
||||
unsigned active_occlusion_query;
|
||||
unsigned dirty; /**< Mask of LP_NEW_x flags */
|
||||
|
||||
/** Mapped vertex buffers */
|
||||
ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS];
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ llvmpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q)
|
|||
break;
|
||||
case PIPE_QUERY_OCCLUSION_COUNTER:
|
||||
case PIPE_QUERY_OCCLUSION_PREDICATE:
|
||||
llvmpipe->active_occlusion_query++;
|
||||
llvmpipe->active_occlusion_queries++;
|
||||
llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -288,8 +288,8 @@ llvmpipe_end_query(struct pipe_context *pipe, struct pipe_query *q)
|
|||
break;
|
||||
case PIPE_QUERY_OCCLUSION_COUNTER:
|
||||
case PIPE_QUERY_OCCLUSION_PREDICATE:
|
||||
assert(llvmpipe->active_occlusion_query);
|
||||
llvmpipe->active_occlusion_query--;
|
||||
assert(llvmpipe->active_occlusion_queries);
|
||||
llvmpipe->active_occlusion_queries--;
|
||||
llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY;
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ struct cmd_bin;
|
|||
/* Rasterizer output size going to jit fs, width/height */
|
||||
#define LP_RASTER_BLOCK_SIZE 4
|
||||
|
||||
#define LP_MAX_ACTIVE_BINNED_QUERIES 16
|
||||
|
||||
|
||||
struct lp_rasterizer_task;
|
||||
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ struct lp_scene {
|
|||
struct lp_fence *fence;
|
||||
|
||||
/* The queries still active at end of scene */
|
||||
struct llvmpipe_query *active_queries[3];
|
||||
struct llvmpipe_query *active_queries[LP_MAX_ACTIVE_BINNED_QUERIES];
|
||||
unsigned num_active_queries;
|
||||
|
||||
/* Framebuffer mappings - valid only between begin_rasterization()
|
||||
|
|
|
|||
|
|
@ -155,22 +155,9 @@ 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++;
|
||||
}
|
||||
scene->num_active_queries = setup->active_binned_queries;
|
||||
memcpy(scene->active_queries, setup->active_queries,
|
||||
scene->num_active_queries * sizeof(scene->active_queries[0]));
|
||||
|
||||
lp_scene_end_binning(scene);
|
||||
|
||||
|
|
@ -1226,9 +1213,14 @@ lp_setup_begin_query(struct lp_setup_context *setup,
|
|||
return;
|
||||
|
||||
/* init the query to its beginning state */
|
||||
assert(setup->active_query[pq->type] == NULL);
|
||||
|
||||
setup->active_query[pq->type] = pq;
|
||||
assert(setup->active_binned_queries < LP_MAX_ACTIVE_BINNED_QUERIES);
|
||||
/* exceeding list size so just ignore the query */
|
||||
if (setup->active_binned_queries >= LP_MAX_ACTIVE_BINNED_QUERIES) {
|
||||
return;
|
||||
}
|
||||
assert(setup->active_queries[setup->active_binned_queries] == NULL);
|
||||
setup->active_queries[setup->active_binned_queries] = pq;
|
||||
setup->active_binned_queries++;
|
||||
|
||||
assert(setup->scene);
|
||||
if (setup->scene) {
|
||||
|
|
@ -1257,12 +1249,6 @@ 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_OCCLUSION_COUNTER ||
|
||||
pq->type == PIPE_QUERY_OCCLUSION_PREDICATE ||
|
||||
pq->type == PIPE_QUERY_PIPELINE_STATISTICS) {
|
||||
assert(setup->active_query[pq->type] == pq);
|
||||
}
|
||||
|
||||
assert(setup->scene);
|
||||
if (setup->scene) {
|
||||
/* pq->fence should be the fence of the *last* scene which
|
||||
|
|
@ -1296,7 +1282,23 @@ 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;
|
||||
if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER ||
|
||||
pq->type == PIPE_QUERY_OCCLUSION_PREDICATE ||
|
||||
pq->type == PIPE_QUERY_PIPELINE_STATISTICS) {
|
||||
unsigned i;
|
||||
|
||||
/* remove from active binned query list */
|
||||
for (i = 0; i < setup->active_binned_queries; i++) {
|
||||
if (setup->active_queries[i] == pq)
|
||||
break;
|
||||
}
|
||||
assert(i < setup->active_binned_queries);
|
||||
if (i == setup->active_binned_queries)
|
||||
return;
|
||||
setup->active_binned_queries--;
|
||||
setup->active_queries[i] = setup->active_queries[setup->active_binned_queries];
|
||||
setup->active_queries[setup->active_binned_queries] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,8 @@ struct lp_setup_context
|
|||
struct lp_scene *scene; /**< current scene being built */
|
||||
|
||||
struct lp_fence *last_fence;
|
||||
struct llvmpipe_query *active_query[PIPE_QUERY_TYPES];
|
||||
struct llvmpipe_query *active_queries[LP_MAX_ACTIVE_BINNED_QUERIES];
|
||||
unsigned active_binned_queries;
|
||||
|
||||
boolean subdivide_large_triangles;
|
||||
boolean flatshade_first;
|
||||
|
|
|
|||
|
|
@ -278,6 +278,7 @@ try_setup_line( struct lp_setup_context *setup,
|
|||
const float (*v1)[4],
|
||||
const float (*v2)[4])
|
||||
{
|
||||
struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
|
||||
struct lp_scene *scene = setup->scene;
|
||||
const struct lp_setup_variant_key *key = &setup->setup.variant->key;
|
||||
struct lp_rast_triangle *line;
|
||||
|
|
@ -596,8 +597,7 @@ try_setup_line( struct lp_setup_context *setup,
|
|||
|
||||
LP_COUNT(nr_tris);
|
||||
|
||||
if (setup->active_query[PIPE_QUERY_PIPELINE_STATISTICS]) {
|
||||
struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
|
||||
if (lp_context->active_statistics_queries) {
|
||||
lp_context->pipeline_statistics.c_primitives++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -303,6 +303,7 @@ static boolean
|
|||
try_setup_point( struct lp_setup_context *setup,
|
||||
const float (*v0)[4] )
|
||||
{
|
||||
struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
|
||||
/* x/y positions in fixed point */
|
||||
const struct lp_setup_variant_key *key = &setup->setup.variant->key;
|
||||
const int sizeAttr = setup->psize;
|
||||
|
|
@ -379,8 +380,7 @@ try_setup_point( struct lp_setup_context *setup,
|
|||
|
||||
LP_COUNT(nr_tris);
|
||||
|
||||
if (setup->active_query[PIPE_QUERY_PIPELINE_STATISTICS]) {
|
||||
struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
|
||||
if (lp_context->active_statistics_queries) {
|
||||
lp_context->pipeline_statistics.c_primitives++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -252,6 +252,7 @@ do_triangle_ccw(struct lp_setup_context *setup,
|
|||
const float (*v2)[4],
|
||||
boolean frontfacing )
|
||||
{
|
||||
struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
|
||||
struct lp_scene *scene = setup->scene;
|
||||
const struct lp_setup_variant_key *key = &setup->setup.variant->key;
|
||||
struct lp_rast_triangle *tri;
|
||||
|
|
@ -339,8 +340,7 @@ do_triangle_ccw(struct lp_setup_context *setup,
|
|||
|
||||
LP_COUNT(nr_tris);
|
||||
|
||||
if (setup->active_query[PIPE_QUERY_PIPELINE_STATISTICS]) {
|
||||
struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
|
||||
if (lp_context->active_statistics_queries) {
|
||||
lp_context->pipeline_statistics.c_primitives++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2630,7 +2630,7 @@ make_variant_key(struct llvmpipe_context *lp,
|
|||
/* alpha.ref_value is passed in jit_context */
|
||||
|
||||
key->flatshade = lp->rasterizer->flatshade;
|
||||
if (lp->active_occlusion_query) {
|
||||
if (lp->active_occlusion_queries) {
|
||||
key->occlusion_count = TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue