<div dir="auto"><div>Feel free to revert the commit if it's not difficult.</div><div dir="auto"><br></div><div dir="auto">Marek<br><br><div class="gmail_quote" dir="auto"><div dir="ltr">On Thu, Jan 31, 2019, 11:25 PM Timothy Arceri <<a href="mailto:tarceri@itsqueeze.com">tarceri@itsqueeze.com</a> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 26/1/19 11:56 am, Marek Olšák wrote:<br>
> Timothy, can you please test the attached fix?<br>
<br>
I'm having trouble compiling 32bit mesa on my machine at the moment so <br>
haven't been able to test Batman. But this commit also causes No Mans <br>
Sky to lock up my machine and the attached patch does not fix it.<br>
<br>
> <br>
> Thanks,<br>
> Marek<br>
> <br>
> On Wed, Jan 2, 2019 at 10:58 PM Timothy Arceri <<a href="mailto:tarceri@itsqueeze.com" target="_blank" rel="noreferrer">tarceri@itsqueeze.com</a> <br>
> <mailto:<a href="mailto:tarceri@itsqueeze.com" target="_blank" rel="noreferrer">tarceri@itsqueeze.com</a>>> wrote:<br>
> <br>
> This commit seems to cause bad stuttering in the Batman Arkham City<br>
> benchmark.<br>
> <br>
> On 7/12/18 1:00 am, Nicolai Hähnle wrote:<br>
> > From: Nicolai Hähnle <<a href="mailto:nicolai.haehnle@amd.com" target="_blank" rel="noreferrer">nicolai.haehnle@amd.com</a><br>
> <mailto:<a href="mailto:nicolai.haehnle@amd.com" target="_blank" rel="noreferrer">nicolai.haehnle@amd.com</a>>><br>
> ><br>
> > This is a move towards using composition instead of inheritance for<br>
> > different query types.<br>
> ><br>
> > This change weakens out-of-memory error reporting somewhat,<br>
> though this<br>
> > should be acceptable since we didn't consistently report such<br>
> errors in<br>
> > the first place.<br>
> > ---<br>
> > src/gallium/drivers/radeonsi/si_perfcounter.c | 8 +-<br>
> > src/gallium/drivers/radeonsi/si_query.c | 177<br>
> +++++++++---------<br>
> > src/gallium/drivers/radeonsi/si_query.h | 17 +-<br>
> > src/gallium/drivers/radeonsi/si_texture.c | 7 +-<br>
> > 4 files changed, 99 insertions(+), 110 deletions(-)<br>
> ><br>
> > diff --git a/src/gallium/drivers/radeonsi/si_perfcounter.c<br>
> b/src/gallium/drivers/radeonsi/si_perfcounter.c<br>
> > index 0b3d8f89273..f0d10c054c4 100644<br>
> > --- a/src/gallium/drivers/radeonsi/si_perfcounter.c<br>
> > +++ b/src/gallium/drivers/radeonsi/si_perfcounter.c<br>
> > @@ -761,23 +761,22 @@ static void si_pc_query_destroy(struct<br>
> si_screen *sscreen,<br>
> > struct si_query_group *group = query->groups;<br>
> > query->groups = group->next;<br>
> > FREE(group);<br>
> > }<br>
> ><br>
> > FREE(query->counters);<br>
> ><br>
> > si_query_hw_destroy(sscreen, rquery);<br>
> > }<br>
> ><br>
> > -static bool si_pc_query_prepare_buffer(struct si_screen *screen,<br>
> > - struct si_query_hw *hwquery,<br>
> > - struct r600_resource *buffer)<br>
> > +static bool si_pc_query_prepare_buffer(struct si_context *ctx,<br>
> > + struct si_query_buffer *qbuf)<br>
> > {<br>
> > /* no-op */<br>
> > return true;<br>
> > }<br>
> ><br>
> > static void si_pc_query_emit_start(struct si_context *sctx,<br>
> > struct si_query_hw *hwquery,<br>
> > struct r600_resource *buffer,<br>
> uint64_t va)<br>
> > {<br>
> > struct si_query_pc *query = (struct si_query_pc *)hwquery;<br>
> > @@ -1055,23 +1054,20 @@ struct pipe_query<br>
> *si_create_batch_query(struct pipe_context *ctx,<br>
> > counter->base = group->result_base + j;<br>
> > counter->stride = group->num_counters;<br>
> ><br>
> > counter->qwords = 1;<br>
> > if ((block->b->b->flags & SI_PC_BLOCK_SE) &&<br>
> group->se < 0)<br>
> > counter->qwords = screen->info.max_se;<br>
> > if (group->instance < 0)<br>
> > counter->qwords *= block->num_instances;<br>
> > }<br>
> ><br>
> > - if (!si_query_hw_init(screen, &query->b))<br>
> > - goto error;<br>
> > -<br>
> > return (struct pipe_query *)query;<br>
> ><br>
> > error:<br>
> > si_pc_query_destroy(screen, &query->b.b);<br>
> > return NULL;<br>
> > }<br>
> ><br>
> > static bool si_init_block_names(struct si_screen *screen,<br>
> > struct si_pc_block *block)<br>
> > {<br>
> > diff --git a/src/gallium/drivers/radeonsi/si_query.c<br>
> b/src/gallium/drivers/radeonsi/si_query.c<br>
> > index 479a1bbf2c4..5b0fba0ed92 100644<br>
> > --- a/src/gallium/drivers/radeonsi/si_query.c<br>
> > +++ b/src/gallium/drivers/radeonsi/si_query.c<br>
> > @@ -514,86 +514,129 @@ static struct pipe_query<br>
> *si_query_sw_create(unsigned query_type)<br>
> > query = CALLOC_STRUCT(si_query_sw);<br>
> > if (!query)<br>
> > return NULL;<br>
> ><br>
> > query->b.type = query_type;<br>
> > query->b.ops = &sw_query_ops;<br>
> ><br>
> > return (struct pipe_query *)query;<br>
> > }<br>
> ><br>
> > -void si_query_hw_destroy(struct si_screen *sscreen,<br>
> > - struct si_query *rquery)<br>
> > +void si_query_buffer_destroy(struct si_screen *sscreen, struct<br>
> si_query_buffer *buffer)<br>
> > {<br>
> > - struct si_query_hw *query = (struct si_query_hw *)rquery;<br>
> > - struct si_query_buffer *prev = query->buffer.previous;<br>
> > + struct si_query_buffer *prev = buffer->previous;<br>
> ><br>
> > /* Release all query buffers. */<br>
> > while (prev) {<br>
> > struct si_query_buffer *qbuf = prev;<br>
> > prev = prev->previous;<br>
> > r600_resource_reference(&qbuf->buf, NULL);<br>
> > FREE(qbuf);<br>
> > }<br>
> ><br>
> > - r600_resource_reference(&query->buffer.buf, NULL);<br>
> > - r600_resource_reference(&query->workaround_buf, NULL);<br>
> > - FREE(rquery);<br>
> > + r600_resource_reference(&buffer->buf, NULL);<br>
> > +}<br>
> > +<br>
> > +void si_query_buffer_reset(struct si_context *sctx, struct<br>
> si_query_buffer *buffer)<br>
> > +{<br>
> > + /* Discard all query buffers except for the oldest. */<br>
> > + while (buffer->previous) {<br>
> > + struct si_query_buffer *qbuf = buffer->previous;<br>
> > + buffer->previous = qbuf->previous;<br>
> > +<br>
> > + r600_resource_reference(&buffer->buf, NULL);<br>
> > + buffer->buf = qbuf->buf; /* move ownership */<br>
> > + FREE(qbuf);<br>
> > + }<br>
> > + buffer->results_end = 0;<br>
> > +<br>
> > + /* Discard even the oldest buffer if it can't be mapped<br>
> without a stall. */<br>
> > + if (buffer->buf &&<br>
> > + (si_rings_is_buffer_referenced(sctx, buffer->buf->buf,<br>
> RADEON_USAGE_READWRITE) ||<br>
> > + !sctx->ws->buffer_wait(buffer->buf->buf, 0,<br>
> RADEON_USAGE_READWRITE))) {<br>
> > + r600_resource_reference(&buffer->buf, NULL);<br>
> > + }<br>
> > }<br>
> ><br>
> > -static struct r600_resource *si_new_query_buffer(struct<br>
> si_screen *sscreen,<br>
> > - struct si_query_hw<br>
> *query)<br>
> > +bool si_query_buffer_alloc(struct si_context *sctx, struct<br>
> si_query_buffer *buffer,<br>
> > + bool (*prepare_buffer)(struct si_context<br>
> *, struct si_query_buffer*),<br>
> > + unsigned size)<br>
> > {<br>
> > - unsigned buf_size = MAX2(query->result_size,<br>
> > - sscreen->info.min_alloc_size);<br>
> > + if (buffer->buf && buffer->results_end + size >=<br>
> buffer->buf->b.b.width0)<br>
> > + return true;<br>
> > +<br>
> > + if (buffer->buf) {<br>
> > + struct si_query_buffer *qbuf =<br>
> MALLOC_STRUCT(si_query_buffer);<br>
> > + memcpy(qbuf, buffer, sizeof(*qbuf));<br>
> > + buffer->previous = qbuf;<br>
> > + }<br>
> > +<br>
> > + buffer->results_end = 0;<br>
> ><br>
> > /* Queries are normally read by the CPU after<br>
> > * being written by the gpu, hence staging is probably a good<br>
> > * usage pattern.<br>
> > */<br>
> > - struct r600_resource *buf = r600_resource(<br>
> > - pipe_buffer_create(&sscreen->b, 0,<br>
> > - PIPE_USAGE_STAGING, buf_size));<br>
> > - if (!buf)<br>
> > - return NULL;<br>
> > + struct si_screen *screen = sctx->screen;<br>
> > + unsigned buf_size = MAX2(size, screen->info.min_alloc_size);<br>
> > + buffer->buf = r600_resource(<br>
> > + pipe_buffer_create(&screen->b, 0,<br>
> PIPE_USAGE_STAGING, buf_size));<br>
> > + if (unlikely(!buffer->buf))<br>
> > + return false;<br>
> ><br>
> > - if (!query->ops->prepare_buffer(sscreen, query, buf)) {<br>
> > - r600_resource_reference(&buf, NULL);<br>
> > - return NULL;<br>
> > + if (prepare_buffer) {<br>
> > + if (unlikely(!prepare_buffer(sctx, buffer))) {<br>
> > + r600_resource_reference(&buffer->buf, NULL);<br>
> > + return false;<br>
> > + }<br>
> > }<br>
> ><br>
> > - return buf;<br>
> > + return true;<br>
> > }<br>
> ><br>
> > -static bool si_query_hw_prepare_buffer(struct si_screen *sscreen,<br>
> > - struct si_query_hw *query,<br>
> > - struct r600_resource *buffer)<br>
> > +<br>
> > +void si_query_hw_destroy(struct si_screen *sscreen,<br>
> > + struct si_query *rquery)<br>
> > +{<br>
> > + struct si_query_hw *query = (struct si_query_hw *)rquery;<br>
> > +<br>
> > + si_query_buffer_destroy(sscreen, &query->buffer);<br>
> > + r600_resource_reference(&query->workaround_buf, NULL);<br>
> > + FREE(rquery);<br>
> > +}<br>
> > +<br>
> > +static bool si_query_hw_prepare_buffer(struct si_context *sctx,<br>
> > + struct si_query_buffer *qbuf)<br>
> > {<br>
> > - /* Callers ensure that the buffer is currently unused by<br>
> the GPU. */<br>
> > - uint32_t *results = sscreen->ws->buffer_map(buffer->buf, NULL,<br>
> > + static const struct si_query_hw si_query_hw_s;<br>
> > + struct si_query_hw *query = container_of(qbuf,<br>
> &si_query_hw_s, buffer);<br>
> > + struct si_screen *screen = sctx->screen;<br>
> > +<br>
> > + /* The caller ensures that the buffer is currently unused<br>
> by the GPU. */<br>
> > + uint32_t *results = screen->ws->buffer_map(qbuf->buf->buf,<br>
> NULL,<br>
> > <br>
> PIPE_TRANSFER_WRITE |<br>
> > <br>
> PIPE_TRANSFER_UNSYNCHRONIZED);<br>
> > if (!results)<br>
> > return false;<br>
> ><br>
> > - memset(results, 0, buffer->b.b.width0);<br>
> > + memset(results, 0, qbuf->buf->b.b.width0);<br>
> ><br>
> > if (query->b.type == PIPE_QUERY_OCCLUSION_COUNTER ||<br>
> > query->b.type == PIPE_QUERY_OCCLUSION_PREDICATE ||<br>
> > query->b.type ==<br>
> PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) {<br>
> > - unsigned max_rbs = sscreen->info.num_render_backends;<br>
> > - unsigned enabled_rb_mask =<br>
> sscreen->info.enabled_rb_mask;<br>
> > + unsigned max_rbs = screen->info.num_render_backends;<br>
> > + unsigned enabled_rb_mask =<br>
> screen->info.enabled_rb_mask;<br>
> > unsigned num_results;<br>
> > unsigned i, j;<br>
> ><br>
> > /* Set top bits for unused backends. */<br>
> > - num_results = buffer->b.b.width0 / query->result_size;<br>
> > + num_results = qbuf->buf->b.b.width0 /<br>
> query->result_size;<br>
> > for (j = 0; j < num_results; j++) {<br>
> > for (i = 0; i < max_rbs; i++) {<br>
> > if (!(enabled_rb_mask & (1<<i))) {<br>
> > results[(i * 4)+1] =<br>
> 0x80000000;<br>
> > results[(i * 4)+3] =<br>
> 0x80000000;<br>
> > }<br>
> > }<br>
> > results += 4 * max_rbs;<br>
> > }<br>
> > }<br>
> > @@ -624,30 +667,20 @@ static void si_query_hw_clear_result(struct<br>
> si_query_hw *,<br>
> > union pipe_query_result *);<br>
> ><br>
> > static struct si_query_hw_ops query_hw_default_hw_ops = {<br>
> > .prepare_buffer = si_query_hw_prepare_buffer,<br>
> > .emit_start = si_query_hw_do_emit_start,<br>
> > .emit_stop = si_query_hw_do_emit_stop,<br>
> > .clear_result = si_query_hw_clear_result,<br>
> > .add_result = si_query_hw_add_result,<br>
> > };<br>
> ><br>
> > -bool si_query_hw_init(struct si_screen *sscreen,<br>
> > - struct si_query_hw *query)<br>
> > -{<br>
> > - query->buffer.buf = si_new_query_buffer(sscreen, query);<br>
> > - if (!query->buffer.buf)<br>
> > - return false;<br>
> > -<br>
> > - return true;<br>
> > -}<br>
> > -<br>
> > static struct pipe_query *si_query_hw_create(struct si_screen<br>
> *sscreen,<br>
> > unsigned query_type,<br>
> > unsigned index)<br>
> > {<br>
> > struct si_query_hw *query = CALLOC_STRUCT(si_query_hw);<br>
> > if (!query)<br>
> > return NULL;<br>
> ><br>
> > query->b.type = query_type;<br>
> > query->b.ops = &query_hw_ops;<br>
> > @@ -693,25 +726,20 @@ static struct pipe_query<br>
> *si_query_hw_create(struct si_screen *sscreen,<br>
> > query->result_size = 11 * 16;<br>
> > query->result_size += 8; /* for the fence +<br>
> alignment */<br>
> > query->b.num_cs_dw_suspend = 6 +<br>
> si_cp_write_fence_dwords(sscreen);<br>
> > break;<br>
> > default:<br>
> > assert(0);<br>
> > FREE(query);<br>
> > return NULL;<br>
> > }<br>
> ><br>
> > - if (!si_query_hw_init(sscreen, query)) {<br>
> > - FREE(query);<br>
> > - return NULL;<br>
> > - }<br>
> > -<br>
> > return (struct pipe_query *)query;<br>
> > }<br>
> ><br>
> > static void si_update_occlusion_query_state(struct si_context<br>
> *sctx,<br>
> > unsigned type, int diff)<br>
> > {<br>
> > if (type == PIPE_QUERY_OCCLUSION_COUNTER ||<br>
> > type == PIPE_QUERY_OCCLUSION_PREDICATE ||<br>
> > type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) {<br>
> > bool old_enable = sctx->num_occlusion_queries != 0;<br>
> > @@ -802,43 +830,31 @@ static void<br>
> si_query_hw_do_emit_start(struct si_context *sctx,<br>
> > }<br>
> > radeon_add_to_buffer_list(sctx, sctx->gfx_cs,<br>
> query->buffer.buf, RADEON_USAGE_WRITE,<br>
> > RADEON_PRIO_QUERY);<br>
> > }<br>
> ><br>
> > static void si_query_hw_emit_start(struct si_context *sctx,<br>
> > struct si_query_hw *query)<br>
> > {<br>
> > uint64_t va;<br>
> ><br>
> > - if (!query->buffer.buf)<br>
> > - return; // previous buffer allocation failure<br>
> > + if (!si_query_buffer_alloc(sctx, &query->buffer,<br>
> query->ops->prepare_buffer,<br>
> > + query->result_size))<br>
> > + return;<br>
> ><br>
> > si_update_occlusion_query_state(sctx, query->b.type, 1);<br>
> > si_update_prims_generated_query_state(sctx, query->b.type, 1);<br>
> ><br>
> > if (query->b.type != SI_QUERY_TIME_ELAPSED_SDMA)<br>
> > si_need_gfx_cs_space(sctx);<br>
> ><br>
> > - /* Get a new query buffer if needed. */<br>
> > - if (query->buffer.results_end + query->result_size ><br>
> query->buffer.buf->b.b.width0) {<br>
> > - struct si_query_buffer *qbuf =<br>
> MALLOC_STRUCT(si_query_buffer);<br>
> > - *qbuf = query->buffer;<br>
> > - query->buffer.results_end = 0;<br>
> > - query->buffer.previous = qbuf;<br>
> > - query->buffer.buf =<br>
> si_new_query_buffer(sctx->screen, query);<br>
> > - if (!query->buffer.buf)<br>
> > - return;<br>
> > - }<br>
> > -<br>
> > - /* emit begin query */<br>
> > va = query->buffer.buf->gpu_address +<br>
> query->buffer.results_end;<br>
> > -<br>
> > query->ops->emit_start(sctx, query, query->buffer.buf, va);<br>
> > }<br>
> ><br>
> > static void si_query_hw_do_emit_stop(struct si_context *sctx,<br>
> > struct si_query_hw *query,<br>
> > struct r600_resource *buffer,<br>
> > uint64_t va)<br>
> > {<br>
> > struct radeon_cmdbuf *cs = sctx->gfx_cs;<br>
> > uint64_t fence_va = 0;<br>
> > @@ -905,26 +921,30 @@ static void si_query_hw_do_emit_stop(struct<br>
> si_context *sctx,<br>
> > query->buffer.buf, fence_va,<br>
> 0x80000000,<br>
> > query->b.type);<br>
> > }<br>
> > }<br>
> ><br>
> > static void si_query_hw_emit_stop(struct si_context *sctx,<br>
> > struct si_query_hw *query)<br>
> > {<br>
> > uint64_t va;<br>
> ><br>
> > - if (!query->buffer.buf)<br>
> > - return; // previous buffer allocation failure<br>
> > -<br>
> > /* The queries which need begin already called this in<br>
> begin_query. */<br>
> > - if (query->flags & SI_QUERY_HW_FLAG_NO_START)<br>
> > + if (query->flags & SI_QUERY_HW_FLAG_NO_START) {<br>
> > si_need_gfx_cs_space(sctx);<br>
> > + if (!si_query_buffer_alloc(sctx, &query->buffer,<br>
> query->ops->prepare_buffer,<br>
> > + query->result_size))<br>
> > + return;<br>
> > + }<br>
> > +<br>
> > + if (!query->buffer.buf)<br>
> > + return; // previous buffer allocation failure<br>
> ><br>
> > /* emit end query */<br>
> > va = query->buffer.buf->gpu_address +<br>
> query->buffer.results_end;<br>
> ><br>
> > query->ops->emit_stop(sctx, query, query->buffer.buf, va);<br>
> ><br>
> > query->buffer.results_end += query->result_size;<br>
> ><br>
> > si_update_occlusion_query_state(sctx, query->b.type, -1);<br>
> > si_update_prims_generated_query_state(sctx, query->b.type, -1);<br>
> > @@ -1054,59 +1074,32 @@ static void si_destroy_query(struct<br>
> pipe_context *ctx, struct pipe_query *query)<br>
> ><br>
> > static boolean si_begin_query(struct pipe_context *ctx,<br>
> > struct pipe_query *query)<br>
> > {<br>
> > struct si_context *sctx = (struct si_context *)ctx;<br>
> > struct si_query *rquery = (struct si_query *)query;<br>
> ><br>
> > return rquery->ops->begin(sctx, rquery);<br>
> > }<br>
> ><br>
> > -void si_query_hw_reset_buffers(struct si_context *sctx,<br>
> > - struct si_query_hw *query)<br>
> > -{<br>
> > - struct si_query_buffer *prev = query->buffer.previous;<br>
> > -<br>
> > - /* Discard the old query buffers. */<br>
> > - while (prev) {<br>
> > - struct si_query_buffer *qbuf = prev;<br>
> > - prev = prev->previous;<br>
> > - r600_resource_reference(&qbuf->buf, NULL);<br>
> > - FREE(qbuf);<br>
> > - }<br>
> > -<br>
> > - query->buffer.results_end = 0;<br>
> > - query->buffer.previous = NULL;<br>
> > -<br>
> > - /* Obtain a new buffer if the current one can't be mapped<br>
> without a stall. */<br>
> > - if (si_rings_is_buffer_referenced(sctx,<br>
> query->buffer.buf->buf, RADEON_USAGE_READWRITE) ||<br>
> > - !sctx->ws->buffer_wait(query->buffer.buf->buf, 0,<br>
> RADEON_USAGE_READWRITE)) {<br>
> > - r600_resource_reference(&query->buffer.buf, NULL);<br>
> > - query->buffer.buf =<br>
> si_new_query_buffer(sctx->screen, query);<br>
> > - } else {<br>
> > - if (!query->ops->prepare_buffer(sctx->screen,<br>
> query, query->buffer.buf))<br>
> > - r600_resource_reference(&query->buffer.buf,<br>
> NULL);<br>
> > - }<br>
> > -}<br>
> > -<br>
> > bool si_query_hw_begin(struct si_context *sctx,<br>
> > struct si_query *rquery)<br>
> > {<br>
> > struct si_query_hw *query = (struct si_query_hw *)rquery;<br>
> ><br>
> > if (query->flags & SI_QUERY_HW_FLAG_NO_START) {<br>
> > assert(0);<br>
> > return false;<br>
> > }<br>
> ><br>
> > if (!(query->flags & SI_QUERY_HW_FLAG_BEGIN_RESUMES))<br>
> > - si_query_hw_reset_buffers(sctx, query);<br>
> > + si_query_buffer_reset(sctx, &query->buffer);<br>
> ><br>
> > r600_resource_reference(&query->workaround_buf, NULL);<br>
> ><br>
> > si_query_hw_emit_start(sctx, query);<br>
> > if (!query->buffer.buf)<br>
> > return false;<br>
> ><br>
> > LIST_ADDTAIL(&query->b.active_list, &sctx->active_queries);<br>
> > sctx->num_cs_dw_queries_suspend += query->b.num_cs_dw_suspend;<br>
> > return true;<br>
> > @@ -1119,21 +1112,21 @@ static bool si_end_query(struct<br>
> pipe_context *ctx, struct pipe_query *query)<br>
> ><br>
> > return rquery->ops->end(sctx, rquery);<br>
> > }<br>
> ><br>
> > bool si_query_hw_end(struct si_context *sctx,<br>
> > struct si_query *rquery)<br>
> > {<br>
> > struct si_query_hw *query = (struct si_query_hw *)rquery;<br>
> ><br>
> > if (query->flags & SI_QUERY_HW_FLAG_NO_START)<br>
> > - si_query_hw_reset_buffers(sctx, query);<br>
> > + si_query_buffer_reset(sctx, &query->buffer);<br>
> ><br>
> > si_query_hw_emit_stop(sctx, query);<br>
> ><br>
> > if (!(query->flags & SI_QUERY_HW_FLAG_NO_START)) {<br>
> > LIST_DELINIT(&query->b.active_list);<br>
> > sctx->num_cs_dw_queries_suspend -=<br>
> query->b.num_cs_dw_suspend;<br>
> > }<br>
> ><br>
> > if (!query->buffer.buf)<br>
> > return false;<br>
> > diff --git a/src/gallium/drivers/radeonsi/si_query.h<br>
> b/src/gallium/drivers/radeonsi/si_query.h<br>
> > index ebd965a004f..63af760a271 100644<br>
> > --- a/src/gallium/drivers/radeonsi/si_query.h<br>
> > +++ b/src/gallium/drivers/radeonsi/si_query.h<br>
> > @@ -27,20 +27,21 @@<br>
> ><br>
> > #include "util/u_threaded_context.h"<br>
> ><br>
> > struct pipe_context;<br>
> > struct pipe_query;<br>
> > struct pipe_resource;<br>
> ><br>
> > struct si_screen;<br>
> > struct si_context;<br>
> > struct si_query;<br>
> > +struct si_query_buffer;<br>
> > struct si_query_hw;<br>
> > struct r600_resource;<br>
> ><br>
> > enum {<br>
> > SI_QUERY_DRAW_CALLS = PIPE_QUERY_DRIVER_SPECIFIC,<br>
> > SI_QUERY_DECOMPRESS_CALLS,<br>
> > SI_QUERY_MRT_DRAW_CALLS,<br>
> > SI_QUERY_PRIM_RESTART_CALLS,<br>
> > SI_QUERY_SPILL_DRAW_CALLS,<br>
> > SI_QUERY_COMPUTE_CALLS,<br>
> > @@ -153,23 +154,21 @@ struct si_query {<br>
> > };<br>
> ><br>
> > enum {<br>
> > SI_QUERY_HW_FLAG_NO_START = (1 << 0),<br>
> > /* gap */<br>
> > /* whether begin_query doesn't clear the result */<br>
> > SI_QUERY_HW_FLAG_BEGIN_RESUMES = (1 << 2),<br>
> > };<br>
> ><br>
> > struct si_query_hw_ops {<br>
> > - bool (*prepare_buffer)(struct si_screen *,<br>
> > - struct si_query_hw *,<br>
> > - struct r600_resource *);<br>
> > + bool (*prepare_buffer)(struct si_context *, struct<br>
> si_query_buffer *);<br>
> > void (*emit_start)(struct si_context *,<br>
> > struct si_query_hw *,<br>
> > struct r600_resource *buffer, uint64_t va);<br>
> > void (*emit_stop)(struct si_context *,<br>
> > struct si_query_hw *,<br>
> > struct r600_resource *buffer, uint64_t va);<br>
> > void (*clear_result)(struct si_query_hw *, union<br>
> pipe_query_result *);<br>
> > void (*add_result)(struct si_screen *screen,<br>
> > struct si_query_hw *, void *buffer,<br>
> > union pipe_query_result *result);<br>
> > @@ -179,40 +178,45 @@ struct si_query_buffer {<br>
> > /* The buffer where query results are stored. */<br>
> > struct r600_resource *buf;<br>
> > /* Offset of the next free result after current query data */<br>
> > unsigned results_end;<br>
> > /* If a query buffer is full, a new buffer is created and<br>
> the old one<br>
> > * is put in here. When we calculate the result, we sum up<br>
> the samples<br>
> > * from all buffers. */<br>
> > struct si_query_buffer *previous;<br>
> > };<br>
> ><br>
> > +void si_query_buffer_destroy(struct si_screen *sctx, struct<br>
> si_query_buffer *buffer);<br>
> > +void si_query_buffer_reset(struct si_context *sctx, struct<br>
> si_query_buffer *buffer);<br>
> > +bool si_query_buffer_alloc(struct si_context *sctx, struct<br>
> si_query_buffer *buffer,<br>
> > + bool (*prepare_buffer)(struct si_context<br>
> *, struct si_query_buffer*),<br>
> > + unsigned size);<br>
> > +<br>
> > +<br>
> > struct si_query_hw {<br>
> > struct si_query b;<br>
> > struct si_query_hw_ops *ops;<br>
> > unsigned flags;<br>
> ><br>
> > /* The query buffer and how many results are in it. */<br>
> > struct si_query_buffer buffer;<br>
> > /* Size of the result in memory for both begin_query and<br>
> end_query,<br>
> > * this can be one or two numbers, or it could even be a<br>
> size of a structure. */<br>
> > unsigned result_size;<br>
> > /* For transform feedback: which stream the query is for */<br>
> > unsigned stream;<br>
> ><br>
> > /* Workaround via compute shader */<br>
> > struct r600_resource *workaround_buf;<br>
> > unsigned workaround_offset;<br>
> > };<br>
> ><br>
> > -bool si_query_hw_init(struct si_screen *sscreen,<br>
> > - struct si_query_hw *query);<br>
> > void si_query_hw_destroy(struct si_screen *sscreen,<br>
> > struct si_query *rquery);<br>
> > bool si_query_hw_begin(struct si_context *sctx,<br>
> > struct si_query *rquery);<br>
> > bool si_query_hw_end(struct si_context *sctx,<br>
> > struct si_query *rquery);<br>
> > bool si_query_hw_get_result(struct si_context *sctx,<br>
> > struct si_query *rquery,<br>
> > bool wait,<br>
> > union pipe_query_result *result);<br>
> > @@ -237,20 +241,17 @@ struct pipe_query<br>
> *si_create_batch_query(struct pipe_context *ctx,<br>
> > unsigned num_queries,<br>
> > unsigned *query_types);<br>
> ><br>
> > int si_get_perfcounter_info(struct si_screen *,<br>
> > unsigned index,<br>
> > struct pipe_driver_query_info *info);<br>
> > int si_get_perfcounter_group_info(struct si_screen *,<br>
> > unsigned index,<br>
> > struct<br>
> pipe_driver_query_group_info *info);<br>
> ><br>
> > -void si_query_hw_reset_buffers(struct si_context *sctx,<br>
> > - struct si_query_hw *query);<br>
> > -<br>
> > struct si_qbo_state {<br>
> > void *saved_compute;<br>
> > struct pipe_constant_buffer saved_const0;<br>
> > struct pipe_shader_buffer saved_ssbo[3];<br>
> > };<br>
> ><br>
> > #endif /* SI_QUERY_H */<br>
> > diff --git a/src/gallium/drivers/radeonsi/si_texture.c<br>
> b/src/gallium/drivers/radeonsi/si_texture.c<br>
> > index ac1a0aa6097..9df12e0f5bd 100644<br>
> > --- a/src/gallium/drivers/radeonsi/si_texture.c<br>
> > +++ b/src/gallium/drivers/radeonsi/si_texture.c<br>
> > @@ -2276,25 +2276,24 @@ void<br>
> vi_separate_dcc_process_and_reset_stats(struct pipe_context *ctx,<br>
> > struct si_context *sctx = (struct si_context*)ctx;<br>
> > struct pipe_query *tmp;<br>
> > unsigned i = vi_get_context_dcc_stats_index(sctx, tex);<br>
> > bool query_active = sctx->dcc_stats[i].query_active;<br>
> > bool disable = false;<br>
> ><br>
> > if (sctx->dcc_stats[i].ps_stats[2]) {<br>
> > union pipe_query_result result;<br>
> ><br>
> > /* Read the results. */<br>
> > - ctx->get_query_result(ctx,<br>
> sctx->dcc_stats[i].ps_stats[2],<br>
> > + struct pipe_query *query =<br>
> sctx->dcc_stats[i].ps_stats[2];<br>
> > + ctx->get_query_result(ctx, query,<br>
> > true, &result);<br>
> > - si_query_hw_reset_buffers(sctx,<br>
> > - (struct si_query_hw*)<br>
> > - <br>
> sctx->dcc_stats[i].ps_stats[2]);<br>
> > + si_query_buffer_reset(sctx, &((struct<br>
> si_query_hw*)query)->buffer);<br>
> ><br>
> > /* Compute the approximate number of fullscreen<br>
> draws. */<br>
> > tex->ps_draw_ratio =<br>
> > result.pipeline_statistics.ps_invocations /<br>
> > (tex->buffer.b.b.width0 *<br>
> tex->buffer.b.b.height0);<br>
> > sctx->last_tex_ps_draw_ratio = tex->ps_draw_ratio;<br>
> ><br>
> > disable = tex->dcc_separate_buffer &&<br>
> > !vi_should_enable_separate_dcc(tex);<br>
> > }<br>
> ><br>
> _______________________________________________<br>
> mesa-dev mailing list<br>
> <a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank" rel="noreferrer">mesa-dev@lists.freedesktop.org</a> <mailto:<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank" rel="noreferrer">mesa-dev@lists.freedesktop.org</a>><br>
> <a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
> <br>
</blockquote></div></div></div>