r600_query.c revision eabcecc26baf225dc50f1d400a80ea4c78831390
11235becaa1cf7e29f580900592563c3329d326deJerome Glisse/* 21235becaa1cf7e29f580900592563c3329d326deJerome Glisse * Copyright 2010 Jerome Glisse <glisse@freedesktop.org> 31235becaa1cf7e29f580900592563c3329d326deJerome Glisse * 41235becaa1cf7e29f580900592563c3329d326deJerome Glisse * Permission is hereby granted, free of charge, to any person obtaining a 51235becaa1cf7e29f580900592563c3329d326deJerome Glisse * copy of this software and associated documentation files (the "Software"), 61235becaa1cf7e29f580900592563c3329d326deJerome Glisse * to deal in the Software without restriction, including without limitation 71235becaa1cf7e29f580900592563c3329d326deJerome Glisse * on the rights to use, copy, modify, merge, publish, distribute, sub 81235becaa1cf7e29f580900592563c3329d326deJerome Glisse * license, and/or sell copies of the Software, and to permit persons to whom 91235becaa1cf7e29f580900592563c3329d326deJerome Glisse * the Software is furnished to do so, subject to the following conditions: 101235becaa1cf7e29f580900592563c3329d326deJerome Glisse * 111235becaa1cf7e29f580900592563c3329d326deJerome Glisse * The above copyright notice and this permission notice (including the next 121235becaa1cf7e29f580900592563c3329d326deJerome Glisse * paragraph) shall be included in all copies or substantial portions of the 131235becaa1cf7e29f580900592563c3329d326deJerome Glisse * Software. 141235becaa1cf7e29f580900592563c3329d326deJerome Glisse * 151235becaa1cf7e29f580900592563c3329d326deJerome Glisse * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 161235becaa1cf7e29f580900592563c3329d326deJerome Glisse * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 171235becaa1cf7e29f580900592563c3329d326deJerome Glisse * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 181235becaa1cf7e29f580900592563c3329d326deJerome Glisse * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 191235becaa1cf7e29f580900592563c3329d326deJerome Glisse * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 201235becaa1cf7e29f580900592563c3329d326deJerome Glisse * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 211235becaa1cf7e29f580900592563c3329d326deJerome Glisse * USE OR OTHER DEALINGS IN THE SOFTWARE. 221235becaa1cf7e29f580900592563c3329d326deJerome Glisse */ 231235becaa1cf7e29f580900592563c3329d326deJerome Glisse#include "r600_pipe.h" 24a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie#include "r600d.h" 25df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák#include "util/u_memory.h" 2683667acfd9feed932f6864092382e752466975edMarek Olšák#include "r600_hw_context_priv.h" 2783667acfd9feed932f6864092382e752466975edMarek Olšák 2883667acfd9feed932f6864092382e752466975edMarek Olšákstatic struct r600_resource *r600_new_query_buffer(struct r600_context *ctx, unsigned type) 2983667acfd9feed932f6864092382e752466975edMarek Olšák{ 3083667acfd9feed932f6864092382e752466975edMarek Olšák unsigned j, i, num_results, buf_size = 4096; 3183667acfd9feed932f6864092382e752466975edMarek Olšák uint32_t *results; 3283667acfd9feed932f6864092382e752466975edMarek Olšák /* Queries are normally read by the CPU after 3383667acfd9feed932f6864092382e752466975edMarek Olšák * being written by the gpu, hence staging is probably a good 3483667acfd9feed932f6864092382e752466975edMarek Olšák * usage pattern. 3583667acfd9feed932f6864092382e752466975edMarek Olšák */ 3683667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_resource *buf = (struct r600_resource*) 3783667acfd9feed932f6864092382e752466975edMarek Olšák pipe_buffer_create(&ctx->screen->screen, PIPE_BIND_CUSTOM, 3883667acfd9feed932f6864092382e752466975edMarek Olšák PIPE_USAGE_STAGING, buf_size); 3983667acfd9feed932f6864092382e752466975edMarek Olšák 4083667acfd9feed932f6864092382e752466975edMarek Olšák switch (type) { 4183667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_COUNTER: 4283667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_PREDICATE: 4383667acfd9feed932f6864092382e752466975edMarek Olšák results = ctx->ws->buffer_map(buf->buf, ctx->cs, PIPE_TRANSFER_WRITE); 4483667acfd9feed932f6864092382e752466975edMarek Olšák memset(results, 0, buf_size); 4583667acfd9feed932f6864092382e752466975edMarek Olšák 4683667acfd9feed932f6864092382e752466975edMarek Olšák /* Set top bits for unused backends. */ 4783667acfd9feed932f6864092382e752466975edMarek Olšák num_results = buf_size / (16 * ctx->max_db); 4883667acfd9feed932f6864092382e752466975edMarek Olšák for (j = 0; j < num_results; j++) { 4983667acfd9feed932f6864092382e752466975edMarek Olšák for (i = 0; i < ctx->max_db; i++) { 5083667acfd9feed932f6864092382e752466975edMarek Olšák if (!(ctx->backend_mask & (1<<i))) { 5183667acfd9feed932f6864092382e752466975edMarek Olšák results[(i * 4)+1] = 0x80000000; 5283667acfd9feed932f6864092382e752466975edMarek Olšák results[(i * 4)+3] = 0x80000000; 5383667acfd9feed932f6864092382e752466975edMarek Olšák } 5483667acfd9feed932f6864092382e752466975edMarek Olšák } 5583667acfd9feed932f6864092382e752466975edMarek Olšák results += 4 * ctx->max_db; 5683667acfd9feed932f6864092382e752466975edMarek Olšák } 5783667acfd9feed932f6864092382e752466975edMarek Olšák ctx->ws->buffer_unmap(buf->buf); 5883667acfd9feed932f6864092382e752466975edMarek Olšák break; 5983667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_TIME_ELAPSED: 6083667acfd9feed932f6864092382e752466975edMarek Olšák break; 6183667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_EMITTED: 6283667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_GENERATED: 6383667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_STATISTICS: 6483667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_OVERFLOW_PREDICATE: 6583667acfd9feed932f6864092382e752466975edMarek Olšák results = ctx->ws->buffer_map(buf->buf, ctx->cs, PIPE_TRANSFER_WRITE); 6683667acfd9feed932f6864092382e752466975edMarek Olšák memset(results, 0, buf_size); 6783667acfd9feed932f6864092382e752466975edMarek Olšák ctx->ws->buffer_unmap(buf->buf); 6883667acfd9feed932f6864092382e752466975edMarek Olšák break; 6983667acfd9feed932f6864092382e752466975edMarek Olšák default: 7083667acfd9feed932f6864092382e752466975edMarek Olšák assert(0); 7183667acfd9feed932f6864092382e752466975edMarek Olšák } 7283667acfd9feed932f6864092382e752466975edMarek Olšák return buf; 7383667acfd9feed932f6864092382e752466975edMarek Olšák} 7483667acfd9feed932f6864092382e752466975edMarek Olšák 7583667acfd9feed932f6864092382e752466975edMarek Olšákstatic void r600_emit_query_begin(struct r600_context *ctx, struct r600_query *query) 7683667acfd9feed932f6864092382e752466975edMarek Olšák{ 7783667acfd9feed932f6864092382e752466975edMarek Olšák struct radeon_winsys_cs *cs = ctx->cs; 7883667acfd9feed932f6864092382e752466975edMarek Olšák uint64_t va; 7983667acfd9feed932f6864092382e752466975edMarek Olšák 8083667acfd9feed932f6864092382e752466975edMarek Olšák r600_need_cs_space(ctx, query->num_cs_dw * 2, TRUE); 8183667acfd9feed932f6864092382e752466975edMarek Olšák 8283667acfd9feed932f6864092382e752466975edMarek Olšák /* Get a new query buffer if needed. */ 8383667acfd9feed932f6864092382e752466975edMarek Olšák if (query->buffer.results_end + query->result_size > query->buffer.buf->b.b.b.width0) { 8483667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query_buffer *qbuf = MALLOC_STRUCT(r600_query_buffer); 8583667acfd9feed932f6864092382e752466975edMarek Olšák *qbuf = query->buffer; 8683667acfd9feed932f6864092382e752466975edMarek Olšák query->buffer.buf = r600_new_query_buffer(ctx, query->type); 8783667acfd9feed932f6864092382e752466975edMarek Olšák query->buffer.results_end = 0; 8883667acfd9feed932f6864092382e752466975edMarek Olšák query->buffer.previous = qbuf; 8983667acfd9feed932f6864092382e752466975edMarek Olšák } 9083667acfd9feed932f6864092382e752466975edMarek Olšák 9183667acfd9feed932f6864092382e752466975edMarek Olšák /* emit begin query */ 9283667acfd9feed932f6864092382e752466975edMarek Olšák va = r600_resource_va(&ctx->screen->screen, (void*)query->buffer.buf); 9383667acfd9feed932f6864092382e752466975edMarek Olšák va += query->buffer.results_end; 9483667acfd9feed932f6864092382e752466975edMarek Olšák 9583667acfd9feed932f6864092382e752466975edMarek Olšák switch (query->type) { 9683667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_COUNTER: 9783667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_PREDICATE: 9883667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 2, 0); 9983667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1); 10083667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = va; 10183667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = (va >> 32UL) & 0xFF; 10283667acfd9feed932f6864092382e752466975edMarek Olšák break; 10383667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_EMITTED: 10483667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_GENERATED: 10583667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_STATISTICS: 10683667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_OVERFLOW_PREDICATE: 10783667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 2, 0); 10883667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_SAMPLE_STREAMOUTSTATS) | EVENT_INDEX(3); 10983667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = va; 11083667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = (va >> 32UL) & 0xFF; 11183667acfd9feed932f6864092382e752466975edMarek Olšák break; 11283667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_TIME_ELAPSED: 11383667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE_EOP, 4, 0); 11483667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5); 11583667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = va; 11683667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = (3 << 29) | ((va >> 32UL) & 0xFF); 11783667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = 0; 11883667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = 0; 11983667acfd9feed932f6864092382e752466975edMarek Olšák break; 12083667acfd9feed932f6864092382e752466975edMarek Olšák default: 12183667acfd9feed932f6864092382e752466975edMarek Olšák assert(0); 12283667acfd9feed932f6864092382e752466975edMarek Olšák } 12383667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0); 12483667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = r600_context_bo_reloc(ctx, query->buffer.buf, RADEON_USAGE_WRITE); 12583667acfd9feed932f6864092382e752466975edMarek Olšák 12683667acfd9feed932f6864092382e752466975edMarek Olšák ctx->num_cs_dw_queries_suspend += query->num_cs_dw; 12783667acfd9feed932f6864092382e752466975edMarek Olšák} 12883667acfd9feed932f6864092382e752466975edMarek Olšák 12983667acfd9feed932f6864092382e752466975edMarek Olšákstatic void r600_emit_query_end(struct r600_context *ctx, struct r600_query *query) 13083667acfd9feed932f6864092382e752466975edMarek Olšák{ 13183667acfd9feed932f6864092382e752466975edMarek Olšák struct radeon_winsys_cs *cs = ctx->cs; 13283667acfd9feed932f6864092382e752466975edMarek Olšák uint64_t va; 13383667acfd9feed932f6864092382e752466975edMarek Olšák 13483667acfd9feed932f6864092382e752466975edMarek Olšák va = r600_resource_va(&ctx->screen->screen, (void*)query->buffer.buf); 13583667acfd9feed932f6864092382e752466975edMarek Olšák /* emit end query */ 13683667acfd9feed932f6864092382e752466975edMarek Olšák switch (query->type) { 13783667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_COUNTER: 13883667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_PREDICATE: 13983667acfd9feed932f6864092382e752466975edMarek Olšák va += query->buffer.results_end + 8; 14083667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 2, 0); 14183667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1); 14283667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = va; 14383667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = (va >> 32UL) & 0xFF; 14483667acfd9feed932f6864092382e752466975edMarek Olšák break; 14583667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_EMITTED: 14683667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_GENERATED: 14783667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_STATISTICS: 14883667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_OVERFLOW_PREDICATE: 14983667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 2, 0); 15083667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_SAMPLE_STREAMOUTSTATS) | EVENT_INDEX(3); 15183667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = query->buffer.results_end + query->result_size/2; 15283667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = 0; 15383667acfd9feed932f6864092382e752466975edMarek Olšák break; 15483667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_TIME_ELAPSED: 15583667acfd9feed932f6864092382e752466975edMarek Olšák va += query->buffer.results_end + query->result_size/2; 15683667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE_EOP, 4, 0); 15783667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5); 15883667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = va; 15983667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = (3 << 29) | ((va >> 32UL) & 0xFF); 16083667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = 0; 16183667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = 0; 16283667acfd9feed932f6864092382e752466975edMarek Olšák break; 16383667acfd9feed932f6864092382e752466975edMarek Olšák default: 16483667acfd9feed932f6864092382e752466975edMarek Olšák assert(0); 16583667acfd9feed932f6864092382e752466975edMarek Olšák } 16683667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0); 16783667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = r600_context_bo_reloc(ctx, query->buffer.buf, RADEON_USAGE_WRITE); 16883667acfd9feed932f6864092382e752466975edMarek Olšák 16983667acfd9feed932f6864092382e752466975edMarek Olšák query->buffer.results_end += query->result_size; 17083667acfd9feed932f6864092382e752466975edMarek Olšák ctx->num_cs_dw_queries_suspend -= query->num_cs_dw; 17183667acfd9feed932f6864092382e752466975edMarek Olšák} 17283667acfd9feed932f6864092382e752466975edMarek Olšák 17383667acfd9feed932f6864092382e752466975edMarek Olšákstatic void r600_emit_query_predication(struct r600_context *ctx, struct r600_query *query, 17483667acfd9feed932f6864092382e752466975edMarek Olšák int operation, bool flag_wait) 17583667acfd9feed932f6864092382e752466975edMarek Olšák{ 17683667acfd9feed932f6864092382e752466975edMarek Olšák struct radeon_winsys_cs *cs = ctx->cs; 17783667acfd9feed932f6864092382e752466975edMarek Olšák 17883667acfd9feed932f6864092382e752466975edMarek Olšák if (operation == PREDICATION_OP_CLEAR) { 17983667acfd9feed932f6864092382e752466975edMarek Olšák r600_need_cs_space(ctx, 3, FALSE); 18083667acfd9feed932f6864092382e752466975edMarek Olšák 18183667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_SET_PREDICATION, 1, 0); 18283667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = 0; 18383667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PRED_OP(PREDICATION_OP_CLEAR); 18483667acfd9feed932f6864092382e752466975edMarek Olšák } else { 18583667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query_buffer *qbuf; 18683667acfd9feed932f6864092382e752466975edMarek Olšák unsigned count; 18783667acfd9feed932f6864092382e752466975edMarek Olšák uint32_t op; 18883667acfd9feed932f6864092382e752466975edMarek Olšák 18983667acfd9feed932f6864092382e752466975edMarek Olšák /* Find how many results there are. */ 19083667acfd9feed932f6864092382e752466975edMarek Olšák count = 0; 19183667acfd9feed932f6864092382e752466975edMarek Olšák for (qbuf = &query->buffer; qbuf; qbuf = qbuf->previous) { 19283667acfd9feed932f6864092382e752466975edMarek Olšák count += qbuf->results_end / query->result_size; 19383667acfd9feed932f6864092382e752466975edMarek Olšák } 19483667acfd9feed932f6864092382e752466975edMarek Olšák 19583667acfd9feed932f6864092382e752466975edMarek Olšák r600_need_cs_space(ctx, 5 * count, TRUE); 19683667acfd9feed932f6864092382e752466975edMarek Olšák 19783667acfd9feed932f6864092382e752466975edMarek Olšák op = PRED_OP(operation) | PREDICATION_DRAW_VISIBLE | 19883667acfd9feed932f6864092382e752466975edMarek Olšák (flag_wait ? PREDICATION_HINT_WAIT : PREDICATION_HINT_NOWAIT_DRAW); 19983667acfd9feed932f6864092382e752466975edMarek Olšák 20083667acfd9feed932f6864092382e752466975edMarek Olšák /* emit predicate packets for all data blocks */ 20183667acfd9feed932f6864092382e752466975edMarek Olšák for (qbuf = &query->buffer; qbuf; qbuf = qbuf->previous) { 20283667acfd9feed932f6864092382e752466975edMarek Olšák unsigned results_base = 0; 20383667acfd9feed932f6864092382e752466975edMarek Olšák uint64_t va = r600_resource_va(&ctx->screen->screen, &qbuf->buf->b.b.b); 20483667acfd9feed932f6864092382e752466975edMarek Olšák 20583667acfd9feed932f6864092382e752466975edMarek Olšák while (results_base < qbuf->results_end) { 20683667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_SET_PREDICATION, 1, 0); 20783667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = (va + results_base) & 0xFFFFFFFFUL; 20883667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = op | (((va + results_base) >> 32UL) & 0xFF); 20983667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0); 21083667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = r600_context_bo_reloc(ctx, qbuf->buf, RADEON_USAGE_READ); 21183667acfd9feed932f6864092382e752466975edMarek Olšák results_base += query->result_size; 21283667acfd9feed932f6864092382e752466975edMarek Olšák 21383667acfd9feed932f6864092382e752466975edMarek Olšák /* set CONTINUE bit for all packets except the first */ 21483667acfd9feed932f6864092382e752466975edMarek Olšák op |= PREDICATION_CONTINUE; 21583667acfd9feed932f6864092382e752466975edMarek Olšák } 21683667acfd9feed932f6864092382e752466975edMarek Olšák } while (qbuf); 21783667acfd9feed932f6864092382e752466975edMarek Olšák } 21883667acfd9feed932f6864092382e752466975edMarek Olšák} 2191235becaa1cf7e29f580900592563c3329d326deJerome Glisse 2201235becaa1cf7e29f580900592563c3329d326deJerome Glissestatic struct pipe_query *r600_create_query(struct pipe_context *ctx, unsigned query_type) 2211235becaa1cf7e29f580900592563c3329d326deJerome Glisse{ 222e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák struct r600_context *rctx = (struct r600_context *)ctx; 2231235becaa1cf7e29f580900592563c3329d326deJerome Glisse 22483667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query *query; 22583667acfd9feed932f6864092382e752466975edMarek Olšák 22683667acfd9feed932f6864092382e752466975edMarek Olšák query = CALLOC_STRUCT(r600_query); 22783667acfd9feed932f6864092382e752466975edMarek Olšák if (query == NULL) 22883667acfd9feed932f6864092382e752466975edMarek Olšák return NULL; 22983667acfd9feed932f6864092382e752466975edMarek Olšák 23083667acfd9feed932f6864092382e752466975edMarek Olšák query->type = query_type; 23183667acfd9feed932f6864092382e752466975edMarek Olšák 23283667acfd9feed932f6864092382e752466975edMarek Olšák switch (query_type) { 23383667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_COUNTER: 23483667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_PREDICATE: 23583667acfd9feed932f6864092382e752466975edMarek Olšák query->result_size = 16 * rctx->max_db; 23683667acfd9feed932f6864092382e752466975edMarek Olšák query->num_cs_dw = 6; 23783667acfd9feed932f6864092382e752466975edMarek Olšák break; 23883667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_TIME_ELAPSED: 23983667acfd9feed932f6864092382e752466975edMarek Olšák query->result_size = 16; 24083667acfd9feed932f6864092382e752466975edMarek Olšák query->num_cs_dw = 8; 24183667acfd9feed932f6864092382e752466975edMarek Olšák break; 24283667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_EMITTED: 24383667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_GENERATED: 24483667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_STATISTICS: 24583667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_OVERFLOW_PREDICATE: 24683667acfd9feed932f6864092382e752466975edMarek Olšák /* NumPrimitivesWritten, PrimitiveStorageNeeded. */ 24783667acfd9feed932f6864092382e752466975edMarek Olšák query->result_size = 32; 24883667acfd9feed932f6864092382e752466975edMarek Olšák query->num_cs_dw = 6; 24983667acfd9feed932f6864092382e752466975edMarek Olšák break; 25083667acfd9feed932f6864092382e752466975edMarek Olšák default: 25183667acfd9feed932f6864092382e752466975edMarek Olšák assert(0); 25283667acfd9feed932f6864092382e752466975edMarek Olšák FREE(query); 25383667acfd9feed932f6864092382e752466975edMarek Olšák return NULL; 25483667acfd9feed932f6864092382e752466975edMarek Olšák } 25583667acfd9feed932f6864092382e752466975edMarek Olšák 25683667acfd9feed932f6864092382e752466975edMarek Olšák query->buffer.buf = r600_new_query_buffer(rctx, query_type); 25783667acfd9feed932f6864092382e752466975edMarek Olšák if (!query->buffer.buf) { 25883667acfd9feed932f6864092382e752466975edMarek Olšák FREE(query); 25983667acfd9feed932f6864092382e752466975edMarek Olšák return NULL; 26083667acfd9feed932f6864092382e752466975edMarek Olšák } 26183667acfd9feed932f6864092382e752466975edMarek Olšák return (struct pipe_query*)query; 2621235becaa1cf7e29f580900592563c3329d326deJerome Glisse} 2631235becaa1cf7e29f580900592563c3329d326deJerome Glisse 2641235becaa1cf7e29f580900592563c3329d326deJerome Glissestatic void r600_destroy_query(struct pipe_context *ctx, struct pipe_query *query) 2651235becaa1cf7e29f580900592563c3329d326deJerome Glisse{ 26683667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query *rquery = (struct r600_query*)query; 267eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák struct r600_query_buffer *prev = rquery->buffer.previous; 268eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák 269eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák /* Release all query buffers. */ 270eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák while (prev) { 271eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák struct r600_query_buffer *qbuf = prev; 272eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák prev = prev->previous; 273eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák pipe_resource_reference((struct pipe_resource**)&qbuf->buf, NULL); 274eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák FREE(qbuf); 275eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák } 2761235becaa1cf7e29f580900592563c3329d326deJerome Glisse 27783667acfd9feed932f6864092382e752466975edMarek Olšák pipe_resource_reference((struct pipe_resource**)&rquery->buffer.buf, NULL); 27883667acfd9feed932f6864092382e752466975edMarek Olšák FREE(query); 2791235becaa1cf7e29f580900592563c3329d326deJerome Glisse} 2801235becaa1cf7e29f580900592563c3329d326deJerome Glisse 281e2809849ecac69615ece294a55ee355afaac33d3Marek Olšákstatic void r600_update_occlusion_query_state(struct r600_context *rctx, 282e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák unsigned type, int diff) 283e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák{ 284e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák if (type == PIPE_QUERY_OCCLUSION_COUNTER || 285e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák type == PIPE_QUERY_OCCLUSION_PREDICATE) { 286e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák bool enable; 287e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák 288e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák rctx->num_occlusion_queries += diff; 289e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák assert(rctx->num_occlusion_queries >= 0); 290e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák 291e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák enable = rctx->num_occlusion_queries != 0; 292e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák 293e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák if (rctx->atom_db_misc_state.occlusion_query_enabled != enable) { 294e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák rctx->atom_db_misc_state.occlusion_query_enabled = enable; 295e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák r600_atom_dirty(rctx, &rctx->atom_db_misc_state.atom); 296e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák } 297e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák } 298e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák} 299e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák 30083667acfd9feed932f6864092382e752466975edMarek Olšákstatic void r600_begin_query(struct pipe_context *ctx, struct pipe_query *query) 301df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák{ 30283667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_context *rctx = (struct r600_context *)ctx; 30383667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query *rquery = (struct r600_query *)query; 304df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák /* Discard the old query buffers. */ 30583667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query_buffer *prev = rquery->buffer.previous; 306df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák 307df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák while (prev) { 308df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák struct r600_query_buffer *qbuf = prev; 309df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák prev = prev->previous; 310df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák pipe_resource_reference((struct pipe_resource**)&qbuf->buf, NULL); 311df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák FREE(qbuf); 312df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák } 313df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák 314df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák /* Obtain a new buffer if the current one can't be mapped without a stall. */ 31583667acfd9feed932f6864092382e752466975edMarek Olšák if (rctx->ws->cs_is_buffer_referenced(rctx->cs, rquery->buffer.buf->cs_buf) || 31683667acfd9feed932f6864092382e752466975edMarek Olšák rctx->ws->buffer_is_busy(rquery->buffer.buf->buf, RADEON_USAGE_READWRITE)) { 31783667acfd9feed932f6864092382e752466975edMarek Olšák pipe_resource_reference((struct pipe_resource**)&rquery->buffer.buf, NULL); 31883667acfd9feed932f6864092382e752466975edMarek Olšák rquery->buffer.buf = r600_new_query_buffer(rctx, rquery->type); 319df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák } 320df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák 32183667acfd9feed932f6864092382e752466975edMarek Olšák rquery->buffer.results_end = 0; 32283667acfd9feed932f6864092382e752466975edMarek Olšák rquery->buffer.previous = NULL; 3231235becaa1cf7e29f580900592563c3329d326deJerome Glisse 324e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák r600_update_occlusion_query_state(rctx, rquery->type, 1); 325e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák 32683667acfd9feed932f6864092382e752466975edMarek Olšák r600_emit_query_begin(rctx, rquery); 327e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák LIST_ADDTAIL(&rquery->list, &rctx->active_query_list); 3281235becaa1cf7e29f580900592563c3329d326deJerome Glisse} 3291235becaa1cf7e29f580900592563c3329d326deJerome Glisse 3301235becaa1cf7e29f580900592563c3329d326deJerome Glissestatic void r600_end_query(struct pipe_context *ctx, struct pipe_query *query) 3311235becaa1cf7e29f580900592563c3329d326deJerome Glisse{ 332e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák struct r600_context *rctx = (struct r600_context *)ctx; 333e9b6f21a5054b2639a1dfc6401e4e9053dce5394Marek Olšák struct r600_query *rquery = (struct r600_query *)query; 3341235becaa1cf7e29f580900592563c3329d326deJerome Glisse 33583667acfd9feed932f6864092382e752466975edMarek Olšák r600_emit_query_end(rctx, rquery); 336e9b6f21a5054b2639a1dfc6401e4e9053dce5394Marek Olšák LIST_DELINIT(&rquery->list); 337e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák 338e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák r600_update_occlusion_query_state(rctx, rquery->type, -1); 3391235becaa1cf7e29f580900592563c3329d326deJerome Glisse} 3401235becaa1cf7e29f580900592563c3329d326deJerome Glisse 34183667acfd9feed932f6864092382e752466975edMarek Olšákstatic unsigned r600_query_read_result(char *map, unsigned start_index, unsigned end_index, 34283667acfd9feed932f6864092382e752466975edMarek Olšák bool test_status_bit) 34383667acfd9feed932f6864092382e752466975edMarek Olšák{ 34483667acfd9feed932f6864092382e752466975edMarek Olšák uint32_t *current_result = (uint32_t*)map; 34583667acfd9feed932f6864092382e752466975edMarek Olšák uint64_t start, end; 34683667acfd9feed932f6864092382e752466975edMarek Olšák 34783667acfd9feed932f6864092382e752466975edMarek Olšák start = (uint64_t)current_result[start_index] | 34883667acfd9feed932f6864092382e752466975edMarek Olšák (uint64_t)current_result[start_index+1] << 32; 34983667acfd9feed932f6864092382e752466975edMarek Olšák end = (uint64_t)current_result[end_index] | 35083667acfd9feed932f6864092382e752466975edMarek Olšák (uint64_t)current_result[end_index+1] << 32; 35183667acfd9feed932f6864092382e752466975edMarek Olšák 35283667acfd9feed932f6864092382e752466975edMarek Olšák if (!test_status_bit || 35383667acfd9feed932f6864092382e752466975edMarek Olšák ((start & 0x8000000000000000UL) && (end & 0x8000000000000000UL))) { 35483667acfd9feed932f6864092382e752466975edMarek Olšák return end - start; 35583667acfd9feed932f6864092382e752466975edMarek Olšák } 35683667acfd9feed932f6864092382e752466975edMarek Olšák return 0; 35783667acfd9feed932f6864092382e752466975edMarek Olšák} 35883667acfd9feed932f6864092382e752466975edMarek Olšák 35983667acfd9feed932f6864092382e752466975edMarek Olšákstatic boolean r600_get_query_buffer_result(struct r600_context *ctx, 36083667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query *query, 36183667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query_buffer *qbuf, 36283667acfd9feed932f6864092382e752466975edMarek Olšák boolean wait, 36383667acfd9feed932f6864092382e752466975edMarek Olšák union r600_query_result *result) 36483667acfd9feed932f6864092382e752466975edMarek Olšák{ 36583667acfd9feed932f6864092382e752466975edMarek Olšák unsigned results_base = 0; 36683667acfd9feed932f6864092382e752466975edMarek Olšák char *map; 36783667acfd9feed932f6864092382e752466975edMarek Olšák 36883667acfd9feed932f6864092382e752466975edMarek Olšák map = ctx->ws->buffer_map(qbuf->buf->buf, ctx->cs, 36983667acfd9feed932f6864092382e752466975edMarek Olšák PIPE_TRANSFER_READ | 37083667acfd9feed932f6864092382e752466975edMarek Olšák (wait ? 0 : PIPE_TRANSFER_DONTBLOCK)); 37183667acfd9feed932f6864092382e752466975edMarek Olšák if (!map) 37283667acfd9feed932f6864092382e752466975edMarek Olšák return FALSE; 37383667acfd9feed932f6864092382e752466975edMarek Olšák 37483667acfd9feed932f6864092382e752466975edMarek Olšák /* count all results across all data blocks */ 37583667acfd9feed932f6864092382e752466975edMarek Olšák switch (query->type) { 37683667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_COUNTER: 37783667acfd9feed932f6864092382e752466975edMarek Olšák while (results_base != qbuf->results_end) { 37883667acfd9feed932f6864092382e752466975edMarek Olšák result->u64 += 37983667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 0, 2, true); 38083667acfd9feed932f6864092382e752466975edMarek Olšák results_base += 16; 38183667acfd9feed932f6864092382e752466975edMarek Olšák } 38283667acfd9feed932f6864092382e752466975edMarek Olšák break; 38383667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_PREDICATE: 38483667acfd9feed932f6864092382e752466975edMarek Olšák while (results_base != qbuf->results_end) { 38583667acfd9feed932f6864092382e752466975edMarek Olšák result->b = result->b || 38683667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 0, 2, true) != 0; 38783667acfd9feed932f6864092382e752466975edMarek Olšák results_base += 16; 38883667acfd9feed932f6864092382e752466975edMarek Olšák } 38983667acfd9feed932f6864092382e752466975edMarek Olšák break; 39083667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_TIME_ELAPSED: 39183667acfd9feed932f6864092382e752466975edMarek Olšák while (results_base != qbuf->results_end) { 39283667acfd9feed932f6864092382e752466975edMarek Olšák result->u64 += 39383667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 0, 2, false); 39483667acfd9feed932f6864092382e752466975edMarek Olšák results_base += query->result_size; 39583667acfd9feed932f6864092382e752466975edMarek Olšák } 39683667acfd9feed932f6864092382e752466975edMarek Olšák break; 39783667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_EMITTED: 39883667acfd9feed932f6864092382e752466975edMarek Olšák /* SAMPLE_STREAMOUTSTATS stores this structure: 39983667acfd9feed932f6864092382e752466975edMarek Olšák * { 40083667acfd9feed932f6864092382e752466975edMarek Olšák * u64 NumPrimitivesWritten; 40183667acfd9feed932f6864092382e752466975edMarek Olšák * u64 PrimitiveStorageNeeded; 40283667acfd9feed932f6864092382e752466975edMarek Olšák * } 40383667acfd9feed932f6864092382e752466975edMarek Olšák * We only need NumPrimitivesWritten here. */ 40483667acfd9feed932f6864092382e752466975edMarek Olšák while (results_base != qbuf->results_end) { 40583667acfd9feed932f6864092382e752466975edMarek Olšák result->u64 += 40683667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 2, 6, true); 40783667acfd9feed932f6864092382e752466975edMarek Olšák results_base += query->result_size; 40883667acfd9feed932f6864092382e752466975edMarek Olšák } 40983667acfd9feed932f6864092382e752466975edMarek Olšák break; 41083667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_GENERATED: 41183667acfd9feed932f6864092382e752466975edMarek Olšák /* Here we read PrimitiveStorageNeeded. */ 41283667acfd9feed932f6864092382e752466975edMarek Olšák while (results_base != qbuf->results_end) { 41383667acfd9feed932f6864092382e752466975edMarek Olšák result->u64 += 41483667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 0, 4, true); 41583667acfd9feed932f6864092382e752466975edMarek Olšák results_base += query->result_size; 41683667acfd9feed932f6864092382e752466975edMarek Olšák } 41783667acfd9feed932f6864092382e752466975edMarek Olšák break; 41883667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_STATISTICS: 41983667acfd9feed932f6864092382e752466975edMarek Olšák while (results_base != qbuf->results_end) { 42083667acfd9feed932f6864092382e752466975edMarek Olšák result->so.num_primitives_written += 42183667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 2, 6, true); 42283667acfd9feed932f6864092382e752466975edMarek Olšák result->so.primitives_storage_needed += 42383667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 0, 4, true); 42483667acfd9feed932f6864092382e752466975edMarek Olšák results_base += query->result_size; 42583667acfd9feed932f6864092382e752466975edMarek Olšák } 42683667acfd9feed932f6864092382e752466975edMarek Olšák break; 42783667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_OVERFLOW_PREDICATE: 42883667acfd9feed932f6864092382e752466975edMarek Olšák while (results_base != qbuf->results_end) { 42983667acfd9feed932f6864092382e752466975edMarek Olšák result->b = result->b || 43083667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 2, 6, true) != 43183667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 0, 4, true); 43283667acfd9feed932f6864092382e752466975edMarek Olšák results_base += query->result_size; 43383667acfd9feed932f6864092382e752466975edMarek Olšák } 43483667acfd9feed932f6864092382e752466975edMarek Olšák break; 43583667acfd9feed932f6864092382e752466975edMarek Olšák default: 43683667acfd9feed932f6864092382e752466975edMarek Olšák assert(0); 43783667acfd9feed932f6864092382e752466975edMarek Olšák } 43883667acfd9feed932f6864092382e752466975edMarek Olšák 43983667acfd9feed932f6864092382e752466975edMarek Olšák ctx->ws->buffer_unmap(qbuf->buf->buf); 44083667acfd9feed932f6864092382e752466975edMarek Olšák return TRUE; 44183667acfd9feed932f6864092382e752466975edMarek Olšák} 44283667acfd9feed932f6864092382e752466975edMarek Olšák 4431235becaa1cf7e29f580900592563c3329d326deJerome Glissestatic boolean r600_get_query_result(struct pipe_context *ctx, 4441235becaa1cf7e29f580900592563c3329d326deJerome Glisse struct pipe_query *query, 4451235becaa1cf7e29f580900592563c3329d326deJerome Glisse boolean wait, void *vresult) 4461235becaa1cf7e29f580900592563c3329d326deJerome Glisse{ 447e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák struct r600_context *rctx = (struct r600_context *)ctx; 4481235becaa1cf7e29f580900592563c3329d326deJerome Glisse struct r600_query *rquery = (struct r600_query *)query; 44983667acfd9feed932f6864092382e752466975edMarek Olšák boolean *result_b = (boolean*)vresult; 45083667acfd9feed932f6864092382e752466975edMarek Olšák uint64_t *result_u64 = (uint64_t*)vresult; 45183667acfd9feed932f6864092382e752466975edMarek Olšák union r600_query_result result; 45283667acfd9feed932f6864092382e752466975edMarek Olšák struct pipe_query_data_so_statistics *result_so = 45383667acfd9feed932f6864092382e752466975edMarek Olšák (struct pipe_query_data_so_statistics*)vresult; 45483667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query_buffer *qbuf; 45583667acfd9feed932f6864092382e752466975edMarek Olšák 45683667acfd9feed932f6864092382e752466975edMarek Olšák memset(&result, 0, sizeof(result)); 45783667acfd9feed932f6864092382e752466975edMarek Olšák 45883667acfd9feed932f6864092382e752466975edMarek Olšák for (qbuf = &rquery->buffer; qbuf; qbuf = qbuf->previous) { 45983667acfd9feed932f6864092382e752466975edMarek Olšák if (!r600_get_query_buffer_result(rctx, rquery, qbuf, wait, &result)) { 46083667acfd9feed932f6864092382e752466975edMarek Olšák return FALSE; 46183667acfd9feed932f6864092382e752466975edMarek Olšák } 46283667acfd9feed932f6864092382e752466975edMarek Olšák } 4631235becaa1cf7e29f580900592563c3329d326deJerome Glisse 46483667acfd9feed932f6864092382e752466975edMarek Olšák switch (rquery->type) { 46583667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_COUNTER: 46683667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_EMITTED: 46783667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_GENERATED: 46883667acfd9feed932f6864092382e752466975edMarek Olšák *result_u64 = result.u64; 46983667acfd9feed932f6864092382e752466975edMarek Olšák break; 47083667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_PREDICATE: 47183667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_OVERFLOW_PREDICATE: 47283667acfd9feed932f6864092382e752466975edMarek Olšák *result_b = result.b; 47383667acfd9feed932f6864092382e752466975edMarek Olšák break; 47483667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_TIME_ELAPSED: 47583667acfd9feed932f6864092382e752466975edMarek Olšák *result_u64 = (1000000 * result.u64) / rctx->screen->info.r600_clock_crystal_freq; 47683667acfd9feed932f6864092382e752466975edMarek Olšák break; 47783667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_STATISTICS: 47883667acfd9feed932f6864092382e752466975edMarek Olšák *result_so = result.so; 47983667acfd9feed932f6864092382e752466975edMarek Olšák break; 48083667acfd9feed932f6864092382e752466975edMarek Olšák default: 48183667acfd9feed932f6864092382e752466975edMarek Olšák assert(0); 48283667acfd9feed932f6864092382e752466975edMarek Olšák } 48383667acfd9feed932f6864092382e752466975edMarek Olšák return TRUE; 4841235becaa1cf7e29f580900592563c3329d326deJerome Glisse} 4851235becaa1cf7e29f580900592563c3329d326deJerome Glisse 486a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airliestatic void r600_render_condition(struct pipe_context *ctx, 487a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie struct pipe_query *query, 488a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie uint mode) 489a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie{ 490e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák struct r600_context *rctx = (struct r600_context *)ctx; 491a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie struct r600_query *rquery = (struct r600_query *)query; 49283667acfd9feed932f6864092382e752466975edMarek Olšák bool wait_flag = false; 493a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie 4946f243ec25d88589747c7a595903e201b90a4d767Marek Olšák rctx->current_render_cond = query; 4956f243ec25d88589747c7a595903e201b90a4d767Marek Olšák rctx->current_render_cond_mode = mode; 4966f243ec25d88589747c7a595903e201b90a4d767Marek Olšák 497ef29bfee031cdab3dbb0f9a79828c4b0d0405991Vadim Girlin if (query == NULL) { 498e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák if (rctx->predicate_drawing) { 499e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák rctx->predicate_drawing = false; 50083667acfd9feed932f6864092382e752466975edMarek Olšák r600_emit_query_predication(rctx, NULL, PREDICATION_OP_CLEAR, false); 501ef29bfee031cdab3dbb0f9a79828c4b0d0405991Vadim Girlin } 502a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie return; 503a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie } 504a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie 505a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie if (mode == PIPE_RENDER_COND_WAIT || 506a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie mode == PIPE_RENDER_COND_BY_REGION_WAIT) { 50783667acfd9feed932f6864092382e752466975edMarek Olšák wait_flag = true; 508a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie } 509a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie 510e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák rctx->predicate_drawing = true; 511543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák 512543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák switch (rquery->type) { 513543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák case PIPE_QUERY_OCCLUSION_COUNTER: 514543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák case PIPE_QUERY_OCCLUSION_PREDICATE: 51583667acfd9feed932f6864092382e752466975edMarek Olšák r600_emit_query_predication(rctx, rquery, PREDICATION_OP_ZPASS, wait_flag); 516543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák break; 517543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák case PIPE_QUERY_PRIMITIVES_EMITTED: 518543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák case PIPE_QUERY_PRIMITIVES_GENERATED: 519543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák case PIPE_QUERY_SO_STATISTICS: 520543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák case PIPE_QUERY_SO_OVERFLOW_PREDICATE: 52183667acfd9feed932f6864092382e752466975edMarek Olšák r600_emit_query_predication(rctx, rquery, PREDICATION_OP_PRIMCOUNT, wait_flag); 522543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák break; 523543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák default: 524543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák assert(0); 525543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák } 526a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie} 527a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie 52883667acfd9feed932f6864092382e752466975edMarek Olšákvoid r600_suspend_queries(struct r600_context *ctx) 52983667acfd9feed932f6864092382e752466975edMarek Olšák{ 53083667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query *query; 53183667acfd9feed932f6864092382e752466975edMarek Olšák 53283667acfd9feed932f6864092382e752466975edMarek Olšák LIST_FOR_EACH_ENTRY(query, &ctx->active_query_list, list) { 53383667acfd9feed932f6864092382e752466975edMarek Olšák r600_emit_query_end(ctx, query); 53483667acfd9feed932f6864092382e752466975edMarek Olšák } 53583667acfd9feed932f6864092382e752466975edMarek Olšák assert(ctx->num_cs_dw_queries_suspend == 0); 53683667acfd9feed932f6864092382e752466975edMarek Olšák} 53783667acfd9feed932f6864092382e752466975edMarek Olšák 53883667acfd9feed932f6864092382e752466975edMarek Olšákvoid r600_resume_queries(struct r600_context *ctx) 53983667acfd9feed932f6864092382e752466975edMarek Olšák{ 54083667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query *query; 54183667acfd9feed932f6864092382e752466975edMarek Olšák 54283667acfd9feed932f6864092382e752466975edMarek Olšák assert(ctx->num_cs_dw_queries_suspend == 0); 54383667acfd9feed932f6864092382e752466975edMarek Olšák 54483667acfd9feed932f6864092382e752466975edMarek Olšák LIST_FOR_EACH_ENTRY(query, &ctx->active_query_list, list) { 54583667acfd9feed932f6864092382e752466975edMarek Olšák r600_emit_query_begin(ctx, query); 54683667acfd9feed932f6864092382e752466975edMarek Olšák } 54783667acfd9feed932f6864092382e752466975edMarek Olšák} 54883667acfd9feed932f6864092382e752466975edMarek Olšák 549e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšákvoid r600_init_query_functions(struct r600_context *rctx) 5501235becaa1cf7e29f580900592563c3329d326deJerome Glisse{ 5511235becaa1cf7e29f580900592563c3329d326deJerome Glisse rctx->context.create_query = r600_create_query; 5521235becaa1cf7e29f580900592563c3329d326deJerome Glisse rctx->context.destroy_query = r600_destroy_query; 5531235becaa1cf7e29f580900592563c3329d326deJerome Glisse rctx->context.begin_query = r600_begin_query; 5541235becaa1cf7e29f580900592563c3329d326deJerome Glisse rctx->context.end_query = r600_end_query; 5551235becaa1cf7e29f580900592563c3329d326deJerome Glisse rctx->context.get_query_result = r600_get_query_result; 556a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie 5571a532ca79a4a87bb86c641a6ca22da0301dc1f62Marek Olšák if (rctx->screen->info.r600_num_backends > 0) 558a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie rctx->context.render_condition = r600_render_condition; 5591235becaa1cf7e29f580900592563c3329d326deJerome Glisse} 560