On Wed, 2017-09-13 at 18:53 +0200, Nicolai Hähnle wrote: > From: Nicolai Hähnle <nicolai.haeh...@amd.com> > > To be able to properly distinguish between GL_ANY_SAMPLES_PASSED > and GL_ANY_SAMPLES_PASSED_CONSERVATIVE. > > This patch goes through all drivers, having them treat the two > query types identically, except: > > 1. radeon incorrectly enabled conservative mode on > PIPE_QUERY_OCCLUSION_PREDICATE. We now do it correctly, only > on PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE. > 2. st/mesa uses the new query type. > > Fixes dEQP-GLES31.functional.fbo.no_attachments.* > --- > src/gallium/auxiliary/util/u_dump_defines.c | 1 + > src/gallium/auxiliary/util/u_inlines.h | 1 + > src/gallium/docs/source/context.rst | 6 ++++++ > src/gallium/drivers/freedreno/a3xx/fd3_query.c | 8 ++++++++ > src/gallium/drivers/freedreno/a4xx/fd4_query.c | 8 ++++++++ > src/gallium/drivers/freedreno/a5xx/fd5_query.c | 10 ++++++++++ > src/gallium/drivers/freedreno/freedreno_query.h | 1 + > src/gallium/drivers/llvmpipe/lp_query.c | 3 +++ > src/gallium/drivers/llvmpipe/lp_rast.c | 2 ++ > src/gallium/drivers/llvmpipe/lp_setup.c | 3 +++ > src/gallium/drivers/nouveau/nv30/nv30_query.c | 4 +++- > src/gallium/drivers/nouveau/nv50/nv50_query.c | 1 + > src/gallium/drivers/nouveau/nv50/nv50_query_hw.c | 4 ++++ > src/gallium/drivers/nouveau/nvc0/nvc0_query.c | 1 + > src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c | 7 ++++++- > src/gallium/drivers/r300/r300_query.c | 7 +++++-- > src/gallium/drivers/radeon/r600_pipe_common.c | 3 ++- > src/gallium/drivers/radeon/r600_query.c | 19 ++++++++++++++----- > src/gallium/drivers/softpipe/sp_query.c | 4 ++++ > src/gallium/drivers/svga/svga_pipe_query.c | 7 ++++++- > src/gallium/drivers/swr/swr_query.cpp | 1 + > src/gallium/drivers/trace/tr_dump_state.c | 1 + > src/gallium/include/pipe/p_defines.h | 2 ++ > src/mesa/state_tracker/st_cb_queryobj.c | 5 ++++- > 24 files changed, 97 insertions(+), 12 deletions(-) > > diff --git a/src/gallium/auxiliary/util/u_dump_defines.c > b/src/gallium/auxiliary/util/u_dump_defines.c > index 5032974a880..e87e5301600 100644 > --- a/src/gallium/auxiliary/util/u_dump_defines.c > +++ b/src/gallium/auxiliary/util/u_dump_defines.c > @@ -358,20 +358,21 @@ util_tex_filter_short_names[] = { > "linear" > }; > > DEFINE_UTIL_STR_CONTINUOUS(tex_filter) > > > static const char * > util_query_type_names[] = { > "PIPE_QUERY_OCCLUSION_COUNTER", > "PIPE_QUERY_OCCLUSION_PREDICATE", > + "PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE", > "PIPE_QUERY_TIMESTAMP", > "PIPE_QUERY_TIMESTAMP_DISJOINT", > "PIPE_QUERY_TIME_ELAPSED", > "PIPE_QUERY_PRIMITIVES_GENERATED", > "PIPE_QUERY_PRIMITIVES_EMITTED", > "PIPE_QUERY_SO_STATISTICS", > "PIPE_QUERY_SO_OVERFLOW_PREDICATE", > "PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE", > "PIPE_QUERY_GPU_FINISHED", > "PIPE_QUERY_PIPELINE_STATISTICS", > diff --git a/src/gallium/auxiliary/util/u_inlines.h > b/src/gallium/auxiliary/util/u_inlines.h > index e0ed594c9fe..79f62c32266 100644 > --- a/src/gallium/auxiliary/util/u_inlines.h > +++ b/src/gallium/auxiliary/util/u_inlines.h > @@ -529,20 +529,21 @@ util_get_min_point_size(const struct > pipe_rasterizer_state *state) > return !state->point_quad_rasterization && > !state->point_smooth && > !state->multisample ? 1.0f : 0.0f; > } > > static inline void > util_query_clear_result(union pipe_query_result *result, unsigned type) > { > switch (type) { > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > case PIPE_QUERY_SO_OVERFLOW_PREDICATE: > case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE: > case PIPE_QUERY_GPU_FINISHED: > result->b = FALSE; > break; > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_TIMESTAMP: > case PIPE_QUERY_TIME_ELAPSED: > case PIPE_QUERY_PRIMITIVES_GENERATED: > case PIPE_QUERY_PRIMITIVES_EMITTED: > diff --git a/src/gallium/docs/source/context.rst > b/src/gallium/docs/source/context.rst > index 6ac45819a66..ba7fef8301d 100644 > --- a/src/gallium/docs/source/context.rst > +++ b/src/gallium/docs/source/context.rst > @@ -387,20 +387,26 @@ are written to the framebuffer without being culled by > The result is an unsigned 64-bit integer. > This query can be used with ``render_condition``. > > In cases where a boolean result of an occlusion query is enough, > ``PIPE_QUERY_OCCLUSION_PREDICATE`` should be used. It is just like > ``PIPE_QUERY_OCCLUSION_COUNTER`` except that the result is a boolean > value of FALSE for cases where COUNTER would result in 0 and TRUE > for all other cases. > This query can be used with ``render_condition``. > > +In cases where a conservative approximation of an occlusion query is enough, > +``PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE`` should be used. It behaves > +like ``PIPE_QUERY_OCCLUSION_PREDICATE``, except that it may return TRUE in > +additional, implementation-dependent cases. > +This query can be used with ``render_condition``. > + > ``PIPE_QUERY_TIME_ELAPSED`` returns the amount of time, in nanoseconds, > the context takes to perform operations. > The result is an unsigned 64-bit integer. > > ``PIPE_QUERY_TIMESTAMP`` returns a device/driver internal timestamp, > scaled to nanoseconds, recorded after all commands issued prior to > ``end_query`` have been processed. > This query does not require a call to ``begin_query``. > The result is an unsigned 64-bit integer. > > diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_query.c > b/src/gallium/drivers/freedreno/a3xx/fd3_query.c > index cde42c37313..97a95b21546 100644 > --- a/src/gallium/drivers/freedreno/a3xx/fd3_query.c > +++ b/src/gallium/drivers/freedreno/a3xx/fd3_query.c > @@ -124,22 +124,30 @@ static const struct fd_hw_sample_provider > occlusion_counter = { > .accumulate_result = occlusion_counter_accumulate_result, > }; > > static const struct fd_hw_sample_provider occlusion_predicate = { > .query_type = PIPE_QUERY_OCCLUSION_PREDICATE, > .active = FD_STAGE_DRAW, > .get_sample = occlusion_get_sample, > .accumulate_result = occlusion_predicate_accumulate_result, > }; > > +static const struct fd_hw_sample_provider occlusion_predicate_conservative = > { > + .query_type = PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE, > + .active = FD_STAGE_DRAW, > + .get_sample = occlusion_get_sample, > + .accumulate_result = occlusion_predicate_accumulate_result, > +}; > + > void fd3_query_context_init(struct pipe_context *pctx) > { > struct fd_context *ctx = fd_context(pctx); > > ctx->create_query = fd_hw_create_query; > ctx->query_prepare = fd_hw_query_prepare; > ctx->query_prepare_tile = fd_hw_query_prepare_tile; > ctx->query_set_stage = fd_hw_query_set_stage; > > fd_hw_query_register_provider(pctx, &occlusion_counter); > fd_hw_query_register_provider(pctx, &occlusion_predicate); > + fd_hw_query_register_provider(pctx, &occlusion_predicate_conservative); > } > diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_query.c > b/src/gallium/drivers/freedreno/a4xx/fd4_query.c > index f7b385d552d..809e7570b48 100644 > --- a/src/gallium/drivers/freedreno/a4xx/fd4_query.c > +++ b/src/gallium/drivers/freedreno/a4xx/fd4_query.c > @@ -244,20 +244,27 @@ static const struct fd_hw_sample_provider > occlusion_counter = { > .accumulate_result = occlusion_counter_accumulate_result, > }; > > static const struct fd_hw_sample_provider occlusion_predicate = { > .query_type = PIPE_QUERY_OCCLUSION_PREDICATE, > .active = FD_STAGE_DRAW, > .get_sample = occlusion_get_sample, > .accumulate_result = occlusion_predicate_accumulate_result, > }; > > +static const struct fd_hw_sample_provider occlusion_predicate = {
Guess this should have been 'fd_hw_sample_provider occlusion_predicate_conservative' ? Otherwise it is the same struct name as above and breaks build. Jan > + .query_type = PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE, > + .active = FD_STAGE_DRAW, > + .get_sample = occlusion_get_sample, > + .accumulate_result = occlusion_predicate_accumulate_result, > +}; > + > static const struct fd_hw_sample_provider time_elapsed = { > .query_type = PIPE_QUERY_TIME_ELAPSED, > .active = FD_STAGE_DRAW | FD_STAGE_CLEAR, > .enable = time_elapsed_enable, > .get_sample = time_elapsed_get_sample, > .accumulate_result = time_elapsed_accumulate_result, > }; > > /* NOTE: timestamp query isn't going to give terribly sensible results > * on a tiler. But it is needed by qapitrace profile heatmap. If you > @@ -277,13 +284,14 @@ void fd4_query_context_init(struct pipe_context *pctx) > { > struct fd_context *ctx = fd_context(pctx); > > ctx->create_query = fd_hw_create_query; > ctx->query_prepare = fd_hw_query_prepare; > ctx->query_prepare_tile = fd_hw_query_prepare_tile; > ctx->query_set_stage = fd_hw_query_set_stage; > > fd_hw_query_register_provider(pctx, &occlusion_counter); > fd_hw_query_register_provider(pctx, &occlusion_predicate); > + fd_hw_query_register_provider(pctx, &occlusion_predicate_conservative); > fd_hw_query_register_provider(pctx, &time_elapsed); > fd_hw_query_register_provider(pctx, ×tamp); > } > diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_query.c > b/src/gallium/drivers/freedreno/a5xx/fd5_query.c > index 80b84ce54ba..87417f1f96e 100644 > --- a/src/gallium/drivers/freedreno/a5xx/fd5_query.c > +++ b/src/gallium/drivers/freedreno/a5xx/fd5_query.c > @@ -137,20 +137,29 @@ static const struct fd_acc_sample_provider > occlusion_counter = { > > static const struct fd_acc_sample_provider occlusion_predicate = { > .query_type = PIPE_QUERY_OCCLUSION_PREDICATE, > .active = FD_STAGE_DRAW, > .size = sizeof(struct fd5_query_sample), > .resume = occlusion_resume, > .pause = occlusion_pause, > .result = occlusion_predicate_result, > }; > > +static const struct fd_acc_sample_provider occlusion_predicate_conservative > = { > + .query_type = PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE, > + .active = FD_STAGE_DRAW, > + .size = sizeof(struct fd5_query_sample), > + .resume = occlusion_resume, > + .pause = occlusion_pause, > + .result = occlusion_predicate_result, > +}; > + > /* > * Timestamp Queries: > */ > > static void > timestamp_resume(struct fd_acc_query *aq, struct fd_batch *batch) > { > struct fd_ringbuffer *ring = batch->draw; > > OUT_PKT7(ring, CP_EVENT_WRITE, 4); > @@ -240,14 +249,15 @@ static const struct fd_acc_sample_provider timestamp = { > void > fd5_query_context_init(struct pipe_context *pctx) > { > struct fd_context *ctx = fd_context(pctx); > > ctx->create_query = fd_acc_create_query; > ctx->query_set_stage = fd_acc_query_set_stage; > > fd_acc_query_register_provider(pctx, &occlusion_counter); > fd_acc_query_register_provider(pctx, &occlusion_predicate); > + fd_acc_query_register_provider(pctx, &occlusion_predicate_conservative); > > fd_acc_query_register_provider(pctx, &time_elapsed); > fd_acc_query_register_provider(pctx, ×tamp); > } > diff --git a/src/gallium/drivers/freedreno/freedreno_query.h > b/src/gallium/drivers/freedreno/freedreno_query.h > index 49a86803c4d..b8fa0951ded 100644 > --- a/src/gallium/drivers/freedreno/freedreno_query.h > +++ b/src/gallium/drivers/freedreno/freedreno_query.h > @@ -78,20 +78,21 @@ skip_begin_query(int type) > } > > /* maps query_type to sample provider idx: */ > static inline > int pidx(unsigned query_type) > { > switch (query_type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > return 0; > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > return 1; > /* TODO currently queries only emitted in main pass (not in binning > pass).. > * which is fine for occlusion query, but pretty much not anything else. > */ > case PIPE_QUERY_TIME_ELAPSED: > return 2; > case PIPE_QUERY_TIMESTAMP: > return 3; > default: > return -1; > diff --git a/src/gallium/drivers/llvmpipe/lp_query.c > b/src/gallium/drivers/llvmpipe/lp_query.c > index 6f8ce94e5d8..7b81903b413 100644 > --- a/src/gallium/drivers/llvmpipe/lp_query.c > +++ b/src/gallium/drivers/llvmpipe/lp_query.c > @@ -118,20 +118,21 @@ llvmpipe_get_query_result(struct pipe_context *pipe, > */ > *result = 0; > > switch (pq->type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > for (i = 0; i < num_threads; i++) { > *result += pq->end[i]; > } > break; > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > for (i = 0; i < num_threads; i++) { > /* safer (still not guaranteed) when there's an overflow */ > vresult->b = vresult->b || pq->end[i]; > } > break; > case PIPE_QUERY_TIMESTAMP: > for (i = 0; i < num_threads; i++) { > if (pq->end[i] > *result) { > *result = pq->end[i]; > } > @@ -224,20 +225,21 @@ llvmpipe_begin_query(struct pipe_context *pipe, struct > pipe_query *q) > /* reset our cache */ > if (llvmpipe->active_statistics_queries == 0) { > memset(&llvmpipe->pipeline_statistics, 0, > sizeof(llvmpipe->pipeline_statistics)); > } > memcpy(&pq->stats, &llvmpipe->pipeline_statistics, sizeof(pq->stats)); > llvmpipe->active_statistics_queries++; > break; > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > llvmpipe->active_occlusion_queries++; > llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY; > break; > default: > break; > } > return true; > } > > > @@ -287,20 +289,21 @@ llvmpipe_end_query(struct pipe_context *pipe, struct > pipe_query *q) > llvmpipe->pipeline_statistics.c_invocations - > pq->stats.c_invocations; > pq->stats.c_primitives = > llvmpipe->pipeline_statistics.c_primitives - pq->stats.c_primitives; > pq->stats.ps_invocations = > llvmpipe->pipeline_statistics.ps_invocations - > pq->stats.ps_invocations; > > llvmpipe->active_statistics_queries--; > break; > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > assert(llvmpipe->active_occlusion_queries); > llvmpipe->active_occlusion_queries--; > llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY; > break; > default: > break; > } > > return true; > } > diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c > b/src/gallium/drivers/llvmpipe/lp_rast.c > index b25ade3d2ec..0050655d9e3 100644 > --- a/src/gallium/drivers/llvmpipe/lp_rast.c > +++ b/src/gallium/drivers/llvmpipe/lp_rast.c > @@ -479,20 +479,21 @@ lp_rast_shade_quads_mask(struct lp_rasterizer_task > *task, > */ > static void > lp_rast_begin_query(struct lp_rasterizer_task *task, > const union lp_rast_cmd_arg arg) > { > struct llvmpipe_query *pq = arg.query_obj; > > switch (pq->type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > pq->start[task->thread_index] = task->thread_data.vis_counter; > break; > case PIPE_QUERY_PIPELINE_STATISTICS: > pq->start[task->thread_index] = task->ps_invocations; > break; > default: > assert(0); > break; > } > } > @@ -505,20 +506,21 @@ lp_rast_begin_query(struct lp_rasterizer_task *task, > */ > static void > lp_rast_end_query(struct lp_rasterizer_task *task, > const union lp_rast_cmd_arg arg) > { > struct llvmpipe_query *pq = arg.query_obj; > > switch (pq->type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > pq->end[task->thread_index] += > task->thread_data.vis_counter - pq->start[task->thread_index]; > pq->start[task->thread_index] = 0; > break; > case PIPE_QUERY_TIMESTAMP: > pq->end[task->thread_index] = os_time_get_nano(); > break; > case PIPE_QUERY_PIPELINE_STATISTICS: > pq->end[task->thread_index] += > task->ps_invocations - pq->start[task->thread_index]; > diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c > b/src/gallium/drivers/llvmpipe/lp_setup.c > index 32387ab5532..2be6fc033d1 100644 > --- a/src/gallium/drivers/llvmpipe/lp_setup.c > +++ b/src/gallium/drivers/llvmpipe/lp_setup.c > @@ -1373,20 +1373,21 @@ no_setup: > */ > void > lp_setup_begin_query(struct lp_setup_context *setup, > struct llvmpipe_query *pq) > { > > set_scene_state(setup, SETUP_ACTIVE, "begin_query"); > > if (!(pq->type == PIPE_QUERY_OCCLUSION_COUNTER || > pq->type == PIPE_QUERY_OCCLUSION_PREDICATE || > + pq->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE || > pq->type == PIPE_QUERY_PIPELINE_STATISTICS)) > return; > > /* init the query to its beginning state */ > 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); > @@ -1423,20 +1424,21 @@ lp_setup_end_query(struct lp_setup_context *setup, > struct llvmpipe_query *pq) > > 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 (pq->type == PIPE_QUERY_OCCLUSION_COUNTER || > pq->type == PIPE_QUERY_OCCLUSION_PREDICATE || > + pq->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE || > pq->type == PIPE_QUERY_PIPELINE_STATISTICS || > pq->type == PIPE_QUERY_TIMESTAMP) { > if (pq->type == PIPE_QUERY_TIMESTAMP && > !(setup->scene->tiles_x | setup->scene->tiles_y)) { > /* > * If there's a zero width/height framebuffer, there's no bins > and > * hence no rast task is ever run. So fill in something here > instead. > */ > pq->end[0] = os_time_get_nano(); > } > @@ -1459,20 +1461,21 @@ lp_setup_end_query(struct lp_setup_context *setup, > struct llvmpipe_query *pq) > 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. > */ > if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER || > pq->type == PIPE_QUERY_OCCLUSION_PREDICATE || > + pq->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE || > 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) > diff --git a/src/gallium/drivers/nouveau/nv30/nv30_query.c > b/src/gallium/drivers/nouveau/nv30/nv30_query.c > index 83ea3afec02..f26728868af 100644 > --- a/src/gallium/drivers/nouveau/nv30/nv30_query.c > +++ b/src/gallium/drivers/nouveau/nv30/nv30_query.c > @@ -114,20 +114,21 @@ nv30_query_create(struct pipe_context *pipe, unsigned > type, unsigned index) > q->type = type; > > switch (q->type) { > case PIPE_QUERY_TIMESTAMP: > case PIPE_QUERY_TIME_ELAPSED: > q->enable = 0x0000; > q->report = 1; > break; > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > q->enable = NV30_3D_QUERY_ENABLE; > q->report = 1; > break; > case NV30_QUERY_ZCULL_0: > case NV30_QUERY_ZCULL_1: > case NV30_QUERY_ZCULL_2: > case NV30_QUERY_ZCULL_3: > q->enable = 0x1804; > q->report = 2 + (q->type - NV30_QUERY_ZCULL_0); > break; > @@ -221,21 +222,22 @@ nv30_query_result(struct pipe_context *pipe, struct > pipe_query *pq, > break; > default: > q->result = ntfy1[2]; > break; > } > > nv30_query_object_del(screen, &q->qo[0]); > nv30_query_object_del(screen, &q->qo[1]); > } > > - if (q->type == PIPE_QUERY_OCCLUSION_PREDICATE) > + if (q->type == PIPE_QUERY_OCCLUSION_PREDICATE || > + q->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) > result->b = !!q->result; > else > result->u64 = q->result; > return true; > } > > static void > nv40_query_render_condition(struct pipe_context *pipe, > struct pipe_query *pq, > boolean condition, enum pipe_render_cond_flag > mode) > diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query.c > b/src/gallium/drivers/nouveau/nv50/nv50_query.c > index ec6ee0f5eb3..e30380cd84d 100644 > --- a/src/gallium/drivers/nouveau/nv50/nv50_query.c > +++ b/src/gallium/drivers/nouveau/nv50/nv50_query.c > @@ -90,20 +90,21 @@ nv50_render_condition(struct pipe_context *pipe, > else { > /* NOTE: comparison of 2 queries only works if both have completed */ > switch (q->type) { > case PIPE_QUERY_SO_OVERFLOW_PREDICATE: > cond = condition ? NV50_3D_COND_MODE_EQUAL : > NV50_3D_COND_MODE_NOT_EQUAL; > wait = true; > break; > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > if (likely(!condition)) { > if (unlikely(hq->nesting)) > cond = wait ? NV50_3D_COND_MODE_NOT_EQUAL : > NV50_3D_COND_MODE_ALWAYS; > else > cond = NV50_3D_COND_MODE_RES_NON_ZERO; > } else { > cond = wait ? NV50_3D_COND_MODE_EQUAL : NV50_3D_COND_MODE_ALWAYS; > } > break; > diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c > b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c > index 727b509372d..ac3e409b2d5 100644 > --- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c > +++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c > @@ -150,20 +150,21 @@ nv50_hw_begin_query(struct nv50_context *nv50, struct > nv50_query *q) > hq->data[1] = 1; /* initial render condition = true */ > hq->data[4] = hq->sequence + 1; /* for comparison COND_MODE */ > hq->data[5] = 0; > } > if (!hq->is64bit) > hq->data[0] = hq->sequence++; /* the previously used one */ > > switch (q->type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > hq->nesting = nv50->screen->num_occlusion_queries_active++; > if (hq->nesting) { > nv50_hw_query_get(push, q, 0x10, 0x0100f002); > } else { > PUSH_SPACE(push, 4); > BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1); > PUSH_DATA (push, NV50_3D_COUNTER_RESET_SAMPLECNT); > BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1); > PUSH_DATA (push, 1); > } > @@ -208,20 +209,21 @@ nv50_hw_end_query(struct nv50_context *nv50, struct > nv50_query *q) > if (hq->funcs && hq->funcs->end_query) { > hq->funcs->end_query(nv50, hq); > return; > } > > hq->state = NV50_HW_QUERY_STATE_ENDED; > > switch (q->type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > nv50_hw_query_get(push, q, 0, 0x0100f002); > if (--nv50->screen->num_occlusion_queries_active == 0) { > PUSH_SPACE(push, 2); > BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1); > PUSH_DATA (push, 0); > } > break; > case PIPE_QUERY_PRIMITIVES_GENERATED: > nv50_hw_query_get(push, q, 0, 0x06805002); > break; > @@ -300,20 +302,21 @@ nv50_hw_get_query_result(struct nv50_context *nv50, > struct nv50_query *q, > hq->state = NV50_HW_QUERY_STATE_READY; > > switch (q->type) { > case PIPE_QUERY_GPU_FINISHED: > res8[0] = true; > break; > case PIPE_QUERY_OCCLUSION_COUNTER: /* u32 sequence, u32 count, u64 time */ > res64[0] = hq->data[1] - hq->data[5]; > break; > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > res8[0] = hq->data[1] != hq->data[5]; > break; > case PIPE_QUERY_PRIMITIVES_GENERATED: /* u64 count, u64 time */ > case PIPE_QUERY_PRIMITIVES_EMITTED: /* u64 count, u64 time */ > res64[0] = data64[0] - data64[2]; > break; > case PIPE_QUERY_SO_STATISTICS: > res64[0] = data64[0] - data64[4]; > res64[1] = data64[2] - data64[6]; > break; > @@ -371,20 +374,21 @@ nv50_hw_create_query(struct nv50_context *nv50, > unsigned type, unsigned index) > if (!hq) > return NULL; > > q = &hq->base; > q->funcs = &hw_query_funcs; > q->type = type; > > switch (q->type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > hq->rotate = 32; > break; > case PIPE_QUERY_PRIMITIVES_GENERATED: > case PIPE_QUERY_PRIMITIVES_EMITTED: > case PIPE_QUERY_SO_STATISTICS: > case PIPE_QUERY_PIPELINE_STATISTICS: > hq->is64bit = true; > break; > case PIPE_QUERY_TIME_ELAPSED: > case PIPE_QUERY_TIMESTAMP: > diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query.c > b/src/gallium/drivers/nouveau/nvc0/nvc0_query.c > index e3090745e3b..d0a9e0c2c04 100644 > --- a/src/gallium/drivers/nouveau/nvc0/nvc0_query.c > +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query.c > @@ -112,20 +112,21 @@ nvc0_render_condition(struct pipe_context *pipe, > else { > /* NOTE: comparison of 2 queries only works if both have completed */ > switch (q->type) { > case PIPE_QUERY_SO_OVERFLOW_PREDICATE: > cond = condition ? NVC0_3D_COND_MODE_EQUAL : > NVC0_3D_COND_MODE_NOT_EQUAL; > wait = true; > break; > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > if (likely(!condition)) { > if (unlikely(hq->nesting)) > cond = wait ? NVC0_3D_COND_MODE_NOT_EQUAL : > NVC0_3D_COND_MODE_ALWAYS; > else > cond = NVC0_3D_COND_MODE_RES_NON_ZERO; > } else { > cond = wait ? NVC0_3D_COND_MODE_EQUAL : NVC0_3D_COND_MODE_ALWAYS; > } > break; > diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c > b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c > index d8d82de8650..f2fdb0cd999 100644 > --- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c > +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c > @@ -150,20 +150,21 @@ nvc0_hw_begin_query(struct nvc0_context *nvc0, struct > nvc0_query *q) > hq->data[0] = hq->sequence; /* initialize sequence */ > hq->data[1] = 1; /* initial render condition = true */ > hq->data[4] = hq->sequence + 1; /* for comparison COND_MODE */ > hq->data[5] = 0; > } > hq->sequence++; > > switch (q->type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > hq->nesting = nvc0->screen->num_occlusion_queries_active++; > if (hq->nesting) { > nvc0_hw_query_get(push, q, 0x10, 0x0100f002); > } else { > PUSH_SPACE(push, 3); > BEGIN_NVC0(push, NVC0_3D(COUNTER_RESET), 1); > PUSH_DATA (push, NVC0_3D_COUNTER_RESET_SAMPLECNT); > IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 1); > } > break; > @@ -217,20 +218,21 @@ nvc0_hw_end_query(struct nvc0_context *nvc0, struct > nvc0_query *q) > /* some queries don't require 'begin' to be called (e.g. GPU_FINISHED) > */ > if (hq->rotate) > nvc0_hw_query_rotate(nvc0, q); > hq->sequence++; > } > hq->state = NVC0_HW_QUERY_STATE_ENDED; > > switch (q->type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > nvc0_hw_query_get(push, q, 0, 0x0100f002); > if (--nvc0->screen->num_occlusion_queries_active == 0) { > PUSH_SPACE(push, 1); > IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 0); > } > break; > case PIPE_QUERY_PRIMITIVES_GENERATED: > nvc0_hw_query_get(push, q, 0, 0x09005002 | (q->index << 5)); > break; > case PIPE_QUERY_PRIMITIVES_EMITTED: > @@ -313,20 +315,21 @@ nvc0_hw_get_query_result(struct nvc0_context *nvc0, > struct nvc0_query *q, > hq->state = NVC0_HW_QUERY_STATE_READY; > > switch (q->type) { > case PIPE_QUERY_GPU_FINISHED: > res8[0] = true; > break; > case PIPE_QUERY_OCCLUSION_COUNTER: /* u32 sequence, u32 count, u64 time */ > res64[0] = hq->data[1] - hq->data[5]; > break; > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > res8[0] = hq->data[1] != hq->data[5]; > break; > case PIPE_QUERY_PRIMITIVES_GENERATED: /* u64 count, u64 time */ > case PIPE_QUERY_PRIMITIVES_EMITTED: /* u64 count, u64 time */ > res64[0] = data64[0] - data64[2]; > break; > case PIPE_QUERY_SO_STATISTICS: > res64[0] = data64[0] - data64[4]; > res64[1] = data64[2] - data64[6]; > break; > @@ -401,21 +404,22 @@ nvc0_hw_get_query_result_resource(struct nvc0_context > *nvc0, > if (hq->state != NVC0_HW_QUERY_STATE_READY) > nvc0_hw_query_update(nvc0->screen->base.client, q); > > if (wait && hq->state != NVC0_HW_QUERY_STATE_READY) > nvc0_hw_query_fifo_wait(nvc0, q); > > nouveau_pushbuf_space(push, 32, 2, 0); > PUSH_REFN (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD); > PUSH_REFN (push, buf->bo, buf->domain | NOUVEAU_BO_WR); > BEGIN_1IC0(push, NVC0_3D(MACRO_QUERY_BUFFER_WRITE), 9); > - if (q->type == PIPE_QUERY_OCCLUSION_PREDICATE) /* XXX what if 64-bit? */ > + if (q->type == PIPE_QUERY_OCCLUSION_PREDICATE || > + q->type ++ PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) /* XXX what > if 64-bit? */ > PUSH_DATA(push, 0x00000001); > else if (result_type == PIPE_QUERY_TYPE_I32) > PUSH_DATA(push, 0x7fffffff); > else if (result_type == PIPE_QUERY_TYPE_U32) > PUSH_DATA(push, 0xffffffff); > else > PUSH_DATA(push, 0x00000000); > > switch (q->type) { > case PIPE_QUERY_SO_STATISTICS: > @@ -506,20 +510,21 @@ nvc0_hw_create_query(struct nvc0_context *nvc0, > unsigned type, unsigned index) > if (!hq) > return NULL; > > q = &hq->base; > q->funcs = &hw_query_funcs; > q->type = type; > > switch (q->type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > hq->rotate = 32; > space = NVC0_HW_QUERY_ALLOC_SPACE; > break; > case PIPE_QUERY_PIPELINE_STATISTICS: > hq->is64bit = true; > space = 512; > break; > case PIPE_QUERY_SO_STATISTICS: > case PIPE_QUERY_SO_OVERFLOW_PREDICATE: > hq->is64bit = true; > diff --git a/src/gallium/drivers/r300/r300_query.c > b/src/gallium/drivers/r300/r300_query.c > index d2dc7b73c05..a84c941768f 100644 > --- a/src/gallium/drivers/r300/r300_query.c > +++ b/src/gallium/drivers/r300/r300_query.c > @@ -32,20 +32,21 @@ > static struct pipe_query *r300_create_query(struct pipe_context *pipe, > unsigned query_type, > unsigned index) > { > struct r300_context *r300 = r300_context(pipe); > struct r300_screen *r300screen = r300->screen; > struct r300_query *q; > > if (query_type != PIPE_QUERY_OCCLUSION_COUNTER && > query_type != PIPE_QUERY_OCCLUSION_PREDICATE && > + query_type != PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE && > query_type != PIPE_QUERY_GPU_FINISHED) { > return NULL; > } > > q = CALLOC_STRUCT(r300_query); > if (!q) > return NULL; > > q->type = query_type; > > @@ -164,21 +165,22 @@ static boolean r300_get_query_result(struct > pipe_context* pipe, > return FALSE; > > /* Sum up the results. */ > temp = 0; > for (i = 0; i < q->num_results; i++) { > /* Convert little endian values written by GPU to CPU byte order */ > temp += util_le32_to_cpu(*map); > map++; > } > > - if (q->type == PIPE_QUERY_OCCLUSION_PREDICATE) { > + if (q->type == PIPE_QUERY_OCCLUSION_PREDICATE || > + q->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) { > vresult->b = temp != 0; > } else { > vresult->u64 = temp; > } > return TRUE; > } > > static void r300_render_condition(struct pipe_context *pipe, > struct pipe_query *query, > boolean condition, > @@ -188,21 +190,22 @@ static void r300_render_condition(struct pipe_context > *pipe, > union pipe_query_result result; > boolean wait; > > r300->skip_rendering = FALSE; > > if (query) { > wait = mode == PIPE_RENDER_COND_WAIT || > mode == PIPE_RENDER_COND_BY_REGION_WAIT; > > if (r300_get_query_result(pipe, query, wait, &result)) { > - if (r300_query(query)->type == PIPE_QUERY_OCCLUSION_PREDICATE) { > + if (r300_query(query)->type == PIPE_QUERY_OCCLUSION_PREDICATE || > + r300_query(query)->type == > PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) { > r300->skip_rendering = condition == result.b; > } else { > r300->skip_rendering = condition == !!result.u64; > } > } > } > } > > static void > r300_set_active_query_state(struct pipe_context *pipe, boolean enable) > diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c > b/src/gallium/drivers/radeon/r600_pipe_common.c > index b283bc65b5b..1183e181a82 100644 > --- a/src/gallium/drivers/radeon/r600_pipe_common.c > +++ b/src/gallium/drivers/radeon/r600_pipe_common.c > @@ -119,21 +119,22 @@ void r600_gfx_write_event_eop(struct > r600_common_context *ctx, > if (ctx->chip_class >= GFX9) { > /* A ZPASS_DONE or PIXEL_STAT_DUMP_EVENT (of the DB occlusion > * counters) must immediately precede every timestamp event to > * prevent a GPU hang on GFX9. > * > * Occlusion queries don't need to do it here, because they > * always do ZPASS_DONE before the timestamp. > */ > if (ctx->chip_class == GFX9 && > query_type != PIPE_QUERY_OCCLUSION_COUNTER && > - query_type != PIPE_QUERY_OCCLUSION_PREDICATE) { > + query_type != PIPE_QUERY_OCCLUSION_PREDICATE && > + query_type != PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) { > struct r600_resource *scratch = ctx->eop_bug_scratch; > > assert(16 * ctx->screen->info.num_render_backends <= > scratch->b.b.width0); > radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 2, 0)); > radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | > EVENT_INDEX(1)); > radeon_emit(cs, scratch->gpu_address); > radeon_emit(cs, scratch->gpu_address >> 32); > > radeon_add_to_buffer_list(ctx, &ctx->gfx, scratch, > diff --git a/src/gallium/drivers/radeon/r600_query.c > b/src/gallium/drivers/radeon/r600_query.c > index 76307ca0662..e655bbdaa23 100644 > --- a/src/gallium/drivers/radeon/r600_query.c > +++ b/src/gallium/drivers/radeon/r600_query.c > @@ -544,21 +544,22 @@ static bool r600_query_hw_prepare_buffer(struct > r600_common_screen *rscreen, > /* Callers ensure that the buffer is currently unused by the GPU. */ > uint32_t *results = rscreen->ws->buffer_map(buffer->buf, NULL, > PIPE_TRANSFER_WRITE | > > PIPE_TRANSFER_UNSYNCHRONIZED); > if (!results) > return false; > > memset(results, 0, buffer->b.b.width0); > > if (query->b.type == PIPE_QUERY_OCCLUSION_COUNTER || > - query->b.type == PIPE_QUERY_OCCLUSION_PREDICATE) { > + query->b.type == PIPE_QUERY_OCCLUSION_PREDICATE || > + query->b.type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) { > unsigned max_rbs = rscreen->info.num_render_backends; > unsigned enabled_rb_mask = rscreen->info.enabled_rb_mask; > unsigned num_results; > unsigned i, j; > > /* Set top bits for unused backends. */ > num_results = buffer->b.b.width0 / query->result_size; > for (j = 0; j < num_results; j++) { > for (i = 0; i < max_rbs; i++) { > if (!(enabled_rb_mask & (1<<i))) { > @@ -629,20 +630,21 @@ static struct pipe_query *r600_query_hw_create(struct > r600_common_screen *rscree > if (!query) > return NULL; > > query->b.type = query_type; > query->b.ops = &query_hw_ops; > query->ops = &query_hw_default_hw_ops; > > switch (query_type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > query->result_size = 16 * rscreen->info.num_render_backends; > query->result_size += 16; /* for the fence + alignment */ > query->num_cs_dw_begin = 6; > query->num_cs_dw_end = 6 + r600_gfx_write_fence_dwords(rscreen); > break; > case PIPE_QUERY_TIME_ELAPSED: > query->result_size = 24; > query->num_cs_dw_begin = 8; > query->num_cs_dw_end = 8 + r600_gfx_write_fence_dwords(rscreen); > break; > @@ -685,30 +687,31 @@ static struct pipe_query *r600_query_hw_create(struct > r600_common_screen *rscree > return NULL; > } > > return (struct pipe_query *)query; > } > > static void r600_update_occlusion_query_state(struct r600_common_context > *rctx, > unsigned type, int diff) > { > if (type == PIPE_QUERY_OCCLUSION_COUNTER || > - type == PIPE_QUERY_OCCLUSION_PREDICATE) { > + type == PIPE_QUERY_OCCLUSION_PREDICATE || > + type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) { > bool old_enable = rctx->num_occlusion_queries != 0; > bool old_perfect_enable = > rctx->num_perfect_occlusion_queries != 0; > bool enable, perfect_enable; > > rctx->num_occlusion_queries += diff; > assert(rctx->num_occlusion_queries >= 0); > > - if (type == PIPE_QUERY_OCCLUSION_COUNTER) { > + if (type != PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) { > rctx->num_perfect_occlusion_queries += diff; > assert(rctx->num_perfect_occlusion_queries >= 0); > } > > enable = rctx->num_occlusion_queries != 0; > perfect_enable = rctx->num_perfect_occlusion_queries != 0; > > if (enable != old_enable || perfect_enable != > old_perfect_enable) { > rctx->set_occlusion_query_state(&rctx->b, enable); > } > @@ -738,20 +741,21 @@ static void emit_sample_streamout(struct > radeon_winsys_cs *cs, uint64_t va, > static void r600_query_hw_do_emit_start(struct r600_common_context *ctx, > struct r600_query_hw *query, > struct r600_resource *buffer, > uint64_t va) > { > struct radeon_winsys_cs *cs = ctx->gfx.cs; > > switch (query->b.type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 2, 0)); > radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | > EVENT_INDEX(1)); > radeon_emit(cs, va); > radeon_emit(cs, va >> 32); > break; > case PIPE_QUERY_PRIMITIVES_EMITTED: > case PIPE_QUERY_PRIMITIVES_GENERATED: > case PIPE_QUERY_SO_STATISTICS: > case PIPE_QUERY_SO_OVERFLOW_PREDICATE: > emit_sample_streamout(cs, va, query->stream); > @@ -832,20 +836,21 @@ static void r600_query_hw_do_emit_stop(struct > r600_common_context *ctx, > struct r600_query_hw *query, > struct r600_resource *buffer, > uint64_t va) > { > struct radeon_winsys_cs *cs = ctx->gfx.cs; > uint64_t fence_va = 0; > > switch (query->b.type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > va += 8; > radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 2, 0)); > radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | > EVENT_INDEX(1)); > radeon_emit(cs, va); > radeon_emit(cs, va >> 32); > > fence_va = va + ctx->screen->info.num_render_backends * 16 - 8; > break; > case PIPE_QUERY_PRIMITIVES_EMITTED: > case PIPE_QUERY_PRIMITIVES_GENERATED: > @@ -954,20 +959,21 @@ static void r600_emit_query_predication(struct > r600_common_context *ctx, > invert = ctx->render_cond_invert; > flag_wait = ctx->render_cond_mode == PIPE_RENDER_COND_WAIT || > ctx->render_cond_mode == PIPE_RENDER_COND_BY_REGION_WAIT; > > if (query->workaround_buf) { > op = PRED_OP(PREDICATION_OP_BOOL64); > } else { > switch (query->b.type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > op = PRED_OP(PREDICATION_OP_ZPASS); > break; > case PIPE_QUERY_SO_OVERFLOW_PREDICATE: > case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE: > op = PRED_OP(PREDICATION_OP_PRIMCOUNT); > invert = !invert; > break; > default: > assert(0); > return; > @@ -1132,20 +1138,21 @@ static void r600_get_hw_query_params(struct > r600_common_context *rctx, > struct r600_hw_query_params *params) > { > unsigned max_rbs = rctx->screen->info.num_render_backends; > > params->pair_stride = 0; > params->pair_count = 1; > > switch (rquery->b.type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > params->start_offset = 0; > params->end_offset = 8; > params->fence_offset = max_rbs * 16; > params->pair_stride = 16; > params->pair_count = max_rbs; > break; > case PIPE_QUERY_TIME_ELAPSED: > params->start_offset = 0; > params->end_offset = 8; > params->fence_offset = 16; > @@ -1224,21 +1231,22 @@ static void r600_query_hw_add_result(struct > r600_common_screen *rscreen, > > switch (query->b.type) { > case PIPE_QUERY_OCCLUSION_COUNTER: { > for (unsigned i = 0; i < max_rbs; ++i) { > unsigned results_base = i * 16; > result->u64 += > r600_query_read_result(buffer + results_base, > 0, 2, true); > } > break; > } > - case PIPE_QUERY_OCCLUSION_PREDICATE: { > + case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: { > for (unsigned i = 0; i < max_rbs; ++i) { > unsigned results_base = i * 16; > result->b = result->b || > r600_query_read_result(buffer + results_base, > 0, 2, true) != 0; > } > break; > } > case PIPE_QUERY_TIME_ELAPSED: > result->u64 += r600_query_read_result(buffer, 0, 2, false); > break; > @@ -1704,21 +1712,22 @@ static void r600_query_hw_get_result_resource(struct > r600_common_context *rctx, > grid.block[0] = 1; > grid.block[1] = 1; > grid.block[2] = 1; > grid.grid[0] = 1; > grid.grid[1] = 1; > grid.grid[2] = 1; > > consts.config = 0; > if (index < 0) > consts.config |= 4; > - if (query->b.type == PIPE_QUERY_OCCLUSION_PREDICATE) > + if (query->b.type == PIPE_QUERY_OCCLUSION_PREDICATE || > + query->b.type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) > consts.config |= 8; > else if (query->b.type == PIPE_QUERY_SO_OVERFLOW_PREDICATE || > query->b.type == PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE) > consts.config |= 8 | 256; > else if (query->b.type == PIPE_QUERY_TIMESTAMP || > query->b.type == PIPE_QUERY_TIME_ELAPSED) > consts.config |= 32; > > switch (result_type) { > case PIPE_QUERY_TYPE_U64: > diff --git a/src/gallium/drivers/softpipe/sp_query.c > b/src/gallium/drivers/softpipe/sp_query.c > index 63f6c4be042..267c99977fe 100644 > --- a/src/gallium/drivers/softpipe/sp_query.c > +++ b/src/gallium/drivers/softpipe/sp_query.c > @@ -53,20 +53,21 @@ static struct softpipe_query *softpipe_query( struct > pipe_query *p ) > > static struct pipe_query * > softpipe_create_query(struct pipe_context *pipe, > unsigned type, > unsigned index) > { > struct softpipe_query* sq; > > assert(type == PIPE_QUERY_OCCLUSION_COUNTER || > type == PIPE_QUERY_OCCLUSION_PREDICATE || > + type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE || > type == PIPE_QUERY_TIME_ELAPSED || > type == PIPE_QUERY_SO_STATISTICS || > type == PIPE_QUERY_SO_OVERFLOW_PREDICATE || > type == PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE || > type == PIPE_QUERY_PRIMITIVES_EMITTED || > type == PIPE_QUERY_PRIMITIVES_GENERATED || > type == PIPE_QUERY_PIPELINE_STATISTICS || > type == PIPE_QUERY_GPU_FINISHED || > type == PIPE_QUERY_TIMESTAMP || > type == PIPE_QUERY_TIMESTAMP_DISJOINT); > @@ -86,20 +87,21 @@ softpipe_destroy_query(struct pipe_context *pipe, struct > pipe_query *q) > > static boolean > softpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q) > { > struct softpipe_context *softpipe = softpipe_context( pipe ); > struct softpipe_query *sq = softpipe_query(q); > > switch (sq->type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > sq->start = softpipe->occlusion_count; > break; > case PIPE_QUERY_TIME_ELAPSED: > sq->start = os_time_get_nano(); > break; > case PIPE_QUERY_SO_STATISTICS: > sq->so.num_primitives_written = > softpipe->so_stats.num_primitives_written; > sq->so.primitives_storage_needed = > softpipe->so_stats.primitives_storage_needed; > break; > case PIPE_QUERY_SO_OVERFLOW_PREDICATE: > @@ -140,20 +142,21 @@ softpipe_begin_query(struct pipe_context *pipe, struct > pipe_query *q) > static bool > softpipe_end_query(struct pipe_context *pipe, struct pipe_query *q) > { > struct softpipe_context *softpipe = softpipe_context( pipe ); > struct softpipe_query *sq = softpipe_query(q); > > softpipe->active_query_count--; > switch (sq->type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > sq->end = softpipe->occlusion_count; > break; > case PIPE_QUERY_TIMESTAMP: > sq->start = 0; > /* fall through */ > case PIPE_QUERY_TIME_ELAPSED: > sq->end = os_time_get_nano(); > break; > case PIPE_QUERY_SO_OVERFLOW_PREDICATE: > case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE: > @@ -245,20 +248,21 @@ softpipe_get_query_result(struct pipe_context *pipe, > td->disjoint = FALSE; > } > break; > case PIPE_QUERY_PRIMITIVES_EMITTED: > *result = sq->so.num_primitives_written; > break; > case PIPE_QUERY_PRIMITIVES_GENERATED: > *result = sq->so.primitives_storage_needed; > break; > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > vresult->b = sq->end - sq->start != 0; > break; > default: > *result = sq->end - sq->start; > break; > } > return TRUE; > } > > > diff --git a/src/gallium/drivers/svga/svga_pipe_query.c > b/src/gallium/drivers/svga/svga_pipe_query.c > index 0490a4ab5fc..26924524372 100644 > --- a/src/gallium/drivers/svga/svga_pipe_query.c > +++ b/src/gallium/drivers/svga/svga_pipe_query.c > @@ -700,20 +700,21 @@ svga_create_query(struct pipe_context *pipe, > * query of occlusion predicate type will be used > * in the SetPredication command. > */ > sq->predicate = svga_create_query(pipe, > PIPE_QUERY_OCCLUSION_PREDICATE, index); > > } else { > define_query_vgpu9(svga, sq); > } > break; > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > if (svga_have_vgpu10(svga)) { > sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSIONPREDICATE; > define_query_vgpu10(svga, sq, > sizeof(SVGADXOcclusionPredicateQueryResult)); > } else { > sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSION; > define_query_vgpu9(svga, sq); > } > break; > case PIPE_QUERY_PRIMITIVES_GENERATED: > case PIPE_QUERY_PRIMITIVES_EMITTED: > @@ -782,20 +783,21 @@ svga_destroy_query(struct pipe_context *pipe, struct > pipe_query *q) > } > > sq = svga_query(q); > > SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d\n", __FUNCTION__, > sq, sq->id); > > switch (sq->type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > if (svga_have_vgpu10(svga)) { > /* make sure to also destroy any associated predicate query */ > if (sq->predicate) > svga_destroy_query(pipe, sq->predicate); > destroy_query_vgpu10(svga, sq); > } else { > sws->buffer_destroy(sws, sq->hwbuf); > } > sws->fence_reference(sws, &sq->fence, NULL); > break; > @@ -857,20 +859,21 @@ svga_begin_query(struct pipe_context *pipe, struct > pipe_query *q) > sq, sq->id); > > /* Need to flush out buffered drawing commands so that they don't > * get counted in the query results. > */ > svga_hwtnl_flush_retry(svga); > > switch (sq->type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > if (svga_have_vgpu10(svga)) { > ret = begin_query_vgpu10(svga, sq); > /* also need to start the associated occlusion predicate query */ > if (sq->predicate) { > enum pipe_error status; > status = begin_query_vgpu10(svga, svga_query(sq->predicate)); > assert(status == PIPE_OK); > (void) status; > } > } else { > @@ -970,20 +973,21 @@ svga_end_query(struct pipe_context *pipe, struct > pipe_query *q) > if (sq->type == PIPE_QUERY_TIMESTAMP && svga->sq[sq->type] != sq) > svga_begin_query(pipe, q); > > svga_hwtnl_flush_retry(svga); > > assert(svga->sq[sq->type] == sq); > > switch (sq->type) { > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > if (svga_have_vgpu10(svga)) { > ret = end_query_vgpu10(svga, sq); > /* also need to end the associated occlusion predicate query */ > if (sq->predicate) { > enum pipe_error status; > status = end_query_vgpu10(svga, svga_query(sq->predicate)); > assert(status == PIPE_OK); > (void) status; > } > } else { > @@ -1086,21 +1090,22 @@ svga_get_query_result(struct pipe_context *pipe, > case PIPE_QUERY_OCCLUSION_COUNTER: > if (svga_have_vgpu10(svga)) { > SVGADXOcclusionQueryResult occResult; > ret = get_query_result_vgpu10(svga, sq, wait, > (void *)&occResult, > sizeof(occResult)); > *result = (uint64_t)occResult.samplesRendered; > } else { > ret = get_query_result_vgpu9(svga, sq, wait, result); > } > break; > - case PIPE_QUERY_OCCLUSION_PREDICATE: { > + case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: { > if (svga_have_vgpu10(svga)) { > SVGADXOcclusionPredicateQueryResult occResult; > ret = get_query_result_vgpu10(svga, sq, wait, > (void *)&occResult, > sizeof(occResult)); > vresult->b = occResult.anySamplesRendered != 0; > } else { > uint64_t count = 0; > ret = get_query_result_vgpu9(svga, sq, wait, &count); > vresult->b = count != 0; > } > diff --git a/src/gallium/drivers/swr/swr_query.cpp > b/src/gallium/drivers/swr/swr_query.cpp > index 4c14c5206b0..e3697304e05 100644 > --- a/src/gallium/drivers/swr/swr_query.cpp > +++ b/src/gallium/drivers/swr/swr_query.cpp > @@ -87,20 +87,21 @@ swr_get_query_result(struct pipe_context *pipe, > > swr_fence_finish(pipe->screen, NULL, pq->fence, 0); > swr_fence_reference(pipe->screen, &pq->fence, NULL); > } > > /* All values are reset to 0 at swr_begin_query, except starting > timestamp. > * Counters become simply end values. */ > switch (pq->type) { > /* Booleans */ > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > result->b = pq->result.core.DepthPassCount != 0; > break; > case PIPE_QUERY_GPU_FINISHED: > result->b = TRUE; > break; > /* Counters */ > case PIPE_QUERY_OCCLUSION_COUNTER: > result->u64 = pq->result.core.DepthPassCount; > break; > case PIPE_QUERY_TIMESTAMP: > diff --git a/src/gallium/drivers/trace/tr_dump_state.c > b/src/gallium/drivers/trace/tr_dump_state.c > index 0650f63d266..e7e32237c4c 100644 > --- a/src/gallium/drivers/trace/tr_dump_state.c > +++ b/src/gallium/drivers/trace/tr_dump_state.c > @@ -871,20 +871,21 @@ trace_dump_query_result(unsigned query_type, > if (!trace_dumping_enabled_locked()) > return; > > if (!result) { > trace_dump_null(); > return; > } > > switch (query_type) { > case PIPE_QUERY_OCCLUSION_PREDICATE: > + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: > case PIPE_QUERY_SO_OVERFLOW_PREDICATE: > case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE: > case PIPE_QUERY_GPU_FINISHED: > trace_dump_bool(result->b); > break; > > case PIPE_QUERY_OCCLUSION_COUNTER: > case PIPE_QUERY_TIMESTAMP: > case PIPE_QUERY_TIME_ELAPSED: > case PIPE_QUERY_PRIMITIVES_GENERATED: > diff --git a/src/gallium/include/pipe/p_defines.h > b/src/gallium/include/pipe/p_defines.h > index da7d5da7347..9b428a6ad76 100644 > --- a/src/gallium/include/pipe/p_defines.h > +++ b/src/gallium/include/pipe/p_defines.h > @@ -523,20 +523,21 @@ enum pipe_tess_spacing { > PIPE_TESS_SPACING_FRACTIONAL_EVEN, > PIPE_TESS_SPACING_EQUAL, > }; > > /** > * Query object types > */ > enum pipe_query_type { > PIPE_QUERY_OCCLUSION_COUNTER, > PIPE_QUERY_OCCLUSION_PREDICATE, > + PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE, > PIPE_QUERY_TIMESTAMP, > PIPE_QUERY_TIMESTAMP_DISJOINT, > PIPE_QUERY_TIME_ELAPSED, > PIPE_QUERY_PRIMITIVES_GENERATED, > PIPE_QUERY_PRIMITIVES_EMITTED, > PIPE_QUERY_SO_STATISTICS, > PIPE_QUERY_SO_OVERFLOW_PREDICATE, > PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE, > PIPE_QUERY_GPU_FINISHED, > PIPE_QUERY_PIPELINE_STATISTICS, > @@ -938,20 +939,21 @@ union pipe_numeric_type_union > uint32_t u32; > float f; > }; > > /** > * Query result (returned by pipe_context::get_query_result). > */ > union pipe_query_result > { > /* PIPE_QUERY_OCCLUSION_PREDICATE */ > + /* PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE */ > /* PIPE_QUERY_SO_OVERFLOW_PREDICATE */ > /* PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE */ > /* PIPE_QUERY_GPU_FINISHED */ > boolean b; > > /* PIPE_QUERY_OCCLUSION_COUNTER */ > /* PIPE_QUERY_TIMESTAMP */ > /* PIPE_QUERY_TIME_ELAPSED */ > /* PIPE_QUERY_PRIMITIVES_GENERATED */ > /* PIPE_QUERY_PRIMITIVES_EMITTED */ > diff --git a/src/mesa/state_tracker/st_cb_queryobj.c > b/src/mesa/state_tracker/st_cb_queryobj.c > index 4c25724b5dc..a470ff6b8b5 100644 > --- a/src/mesa/state_tracker/st_cb_queryobj.c > +++ b/src/mesa/state_tracker/st_cb_queryobj.c > @@ -95,23 +95,25 @@ st_BeginQuery(struct gl_context *ctx, struct > gl_query_object *q) > 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: > - case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: > 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: > @@ -253,20 +255,21 @@ get_query_result(struct pipe_context *pipe, > 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: > switch (stq->type) { > 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; > } > break; > }
signature.asc
Description: This is a digitally signed message part
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev