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 2709ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšákstatic bool r600_is_timer_query(unsigned type) 2809ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák{ 2909ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák return type == PIPE_QUERY_TIME_ELAPSED || 3009ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák type == PIPE_QUERY_TIMESTAMP || 3109ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák type == PIPE_QUERY_TIMESTAMP_DISJOINT; 3209ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák} 3309ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák 340018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšákstatic bool r600_query_needs_begin(unsigned type) 350018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák{ 360018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák return type != PIPE_QUERY_GPU_FINISHED && 370018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák type != PIPE_QUERY_TIMESTAMP; 380018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák} 390018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák 4083667acfd9feed932f6864092382e752466975edMarek Olšákstatic struct r600_resource *r600_new_query_buffer(struct r600_context *ctx, unsigned type) 4183667acfd9feed932f6864092382e752466975edMarek Olšák{ 4283667acfd9feed932f6864092382e752466975edMarek Olšák unsigned j, i, num_results, buf_size = 4096; 4383667acfd9feed932f6864092382e752466975edMarek Olšák uint32_t *results; 4483667acfd9feed932f6864092382e752466975edMarek Olšák /* Queries are normally read by the CPU after 4583667acfd9feed932f6864092382e752466975edMarek Olšák * being written by the gpu, hence staging is probably a good 4683667acfd9feed932f6864092382e752466975edMarek Olšák * usage pattern. 4783667acfd9feed932f6864092382e752466975edMarek Olšák */ 4883667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_resource *buf = (struct r600_resource*) 4983667acfd9feed932f6864092382e752466975edMarek Olšák pipe_buffer_create(&ctx->screen->screen, PIPE_BIND_CUSTOM, 5083667acfd9feed932f6864092382e752466975edMarek Olšák PIPE_USAGE_STAGING, buf_size); 5183667acfd9feed932f6864092382e752466975edMarek Olšák 5283667acfd9feed932f6864092382e752466975edMarek Olšák switch (type) { 5383667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_COUNTER: 5483667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_PREDICATE: 550a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák results = ctx->ws->buffer_map(buf->cs_buf, ctx->cs, PIPE_TRANSFER_WRITE); 5683667acfd9feed932f6864092382e752466975edMarek Olšák memset(results, 0, buf_size); 5783667acfd9feed932f6864092382e752466975edMarek Olšák 5883667acfd9feed932f6864092382e752466975edMarek Olšák /* Set top bits for unused backends. */ 5983667acfd9feed932f6864092382e752466975edMarek Olšák num_results = buf_size / (16 * ctx->max_db); 6083667acfd9feed932f6864092382e752466975edMarek Olšák for (j = 0; j < num_results; j++) { 6183667acfd9feed932f6864092382e752466975edMarek Olšák for (i = 0; i < ctx->max_db; i++) { 6283667acfd9feed932f6864092382e752466975edMarek Olšák if (!(ctx->backend_mask & (1<<i))) { 6383667acfd9feed932f6864092382e752466975edMarek Olšák results[(i * 4)+1] = 0x80000000; 6483667acfd9feed932f6864092382e752466975edMarek Olšák results[(i * 4)+3] = 0x80000000; 6583667acfd9feed932f6864092382e752466975edMarek Olšák } 6683667acfd9feed932f6864092382e752466975edMarek Olšák } 6783667acfd9feed932f6864092382e752466975edMarek Olšák results += 4 * ctx->max_db; 6883667acfd9feed932f6864092382e752466975edMarek Olšák } 690a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák ctx->ws->buffer_unmap(buf->cs_buf); 7083667acfd9feed932f6864092382e752466975edMarek Olšák break; 7183667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_TIME_ELAPSED: 7244f14ebd7b9ba7186342039d2602fdd6ea5077f5Marek Olšák case PIPE_QUERY_TIMESTAMP: 7383667acfd9feed932f6864092382e752466975edMarek Olšák break; 7483667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_EMITTED: 7583667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_GENERATED: 7683667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_STATISTICS: 7783667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_OVERFLOW_PREDICATE: 780a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák results = ctx->ws->buffer_map(buf->cs_buf, ctx->cs, PIPE_TRANSFER_WRITE); 7983667acfd9feed932f6864092382e752466975edMarek Olšák memset(results, 0, buf_size); 800a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák ctx->ws->buffer_unmap(buf->cs_buf); 8183667acfd9feed932f6864092382e752466975edMarek Olšák break; 8283667acfd9feed932f6864092382e752466975edMarek Olšák default: 8383667acfd9feed932f6864092382e752466975edMarek Olšák assert(0); 8483667acfd9feed932f6864092382e752466975edMarek Olšák } 8583667acfd9feed932f6864092382e752466975edMarek Olšák return buf; 8683667acfd9feed932f6864092382e752466975edMarek Olšák} 8783667acfd9feed932f6864092382e752466975edMarek Olšák 8883667acfd9feed932f6864092382e752466975edMarek Olšákstatic void r600_emit_query_begin(struct r600_context *ctx, struct r600_query *query) 8983667acfd9feed932f6864092382e752466975edMarek Olšák{ 9083667acfd9feed932f6864092382e752466975edMarek Olšák struct radeon_winsys_cs *cs = ctx->cs; 9183667acfd9feed932f6864092382e752466975edMarek Olšák uint64_t va; 9283667acfd9feed932f6864092382e752466975edMarek Olšák 9383667acfd9feed932f6864092382e752466975edMarek Olšák r600_need_cs_space(ctx, query->num_cs_dw * 2, TRUE); 9483667acfd9feed932f6864092382e752466975edMarek Olšák 9583667acfd9feed932f6864092382e752466975edMarek Olšák /* Get a new query buffer if needed. */ 96a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák if (query->buffer.results_end + query->result_size > query->buffer.buf->b.b.width0) { 9783667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query_buffer *qbuf = MALLOC_STRUCT(r600_query_buffer); 9883667acfd9feed932f6864092382e752466975edMarek Olšák *qbuf = query->buffer; 9983667acfd9feed932f6864092382e752466975edMarek Olšák query->buffer.buf = r600_new_query_buffer(ctx, query->type); 10083667acfd9feed932f6864092382e752466975edMarek Olšák query->buffer.results_end = 0; 10183667acfd9feed932f6864092382e752466975edMarek Olšák query->buffer.previous = qbuf; 10283667acfd9feed932f6864092382e752466975edMarek Olšák } 10383667acfd9feed932f6864092382e752466975edMarek Olšák 10483667acfd9feed932f6864092382e752466975edMarek Olšák /* emit begin query */ 10583667acfd9feed932f6864092382e752466975edMarek Olšák va = r600_resource_va(&ctx->screen->screen, (void*)query->buffer.buf); 10683667acfd9feed932f6864092382e752466975edMarek Olšák va += query->buffer.results_end; 10783667acfd9feed932f6864092382e752466975edMarek Olšák 10883667acfd9feed932f6864092382e752466975edMarek Olšák switch (query->type) { 10983667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_COUNTER: 11083667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_PREDICATE: 11183667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 2, 0); 11283667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1); 11383667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = va; 11483667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = (va >> 32UL) & 0xFF; 11583667acfd9feed932f6864092382e752466975edMarek Olšák break; 11683667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_EMITTED: 11783667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_GENERATED: 11883667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_STATISTICS: 11983667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_OVERFLOW_PREDICATE: 12083667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 2, 0); 12183667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_SAMPLE_STREAMOUTSTATS) | EVENT_INDEX(3); 12283667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = va; 12383667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = (va >> 32UL) & 0xFF; 12483667acfd9feed932f6864092382e752466975edMarek Olšák break; 12583667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_TIME_ELAPSED: 12683667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE_EOP, 4, 0); 12783667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5); 12883667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = va; 12983667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = (3 << 29) | ((va >> 32UL) & 0xFF); 13083667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = 0; 13183667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = 0; 13283667acfd9feed932f6864092382e752466975edMarek Olšák break; 13383667acfd9feed932f6864092382e752466975edMarek Olšák default: 13483667acfd9feed932f6864092382e752466975edMarek Olšák assert(0); 13583667acfd9feed932f6864092382e752466975edMarek Olšák } 13683667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0); 13783667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = r600_context_bo_reloc(ctx, query->buffer.buf, RADEON_USAGE_WRITE); 13883667acfd9feed932f6864092382e752466975edMarek Olšák 13909ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák if (r600_is_timer_query(query->type)) { 14009ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák ctx->num_cs_dw_timer_queries_suspend += query->num_cs_dw; 14109ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák } else { 14209ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák ctx->num_cs_dw_nontimer_queries_suspend += query->num_cs_dw; 14309ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák } 14483667acfd9feed932f6864092382e752466975edMarek Olšák} 14583667acfd9feed932f6864092382e752466975edMarek Olšák 14683667acfd9feed932f6864092382e752466975edMarek Olšákstatic void r600_emit_query_end(struct r600_context *ctx, struct r600_query *query) 14783667acfd9feed932f6864092382e752466975edMarek Olšák{ 14883667acfd9feed932f6864092382e752466975edMarek Olšák struct radeon_winsys_cs *cs = ctx->cs; 14983667acfd9feed932f6864092382e752466975edMarek Olšák uint64_t va; 15083667acfd9feed932f6864092382e752466975edMarek Olšák 1510018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák /* The queries which need begin already called this in begin_query. */ 1520018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák if (!r600_query_needs_begin(query->type)) { 1530018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák r600_need_cs_space(ctx, query->num_cs_dw, FALSE); 1540018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák } 1550018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák 15683667acfd9feed932f6864092382e752466975edMarek Olšák va = r600_resource_va(&ctx->screen->screen, (void*)query->buffer.buf); 15783667acfd9feed932f6864092382e752466975edMarek Olšák /* emit end query */ 15883667acfd9feed932f6864092382e752466975edMarek Olšák switch (query->type) { 15983667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_COUNTER: 16083667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_PREDICATE: 16183667acfd9feed932f6864092382e752466975edMarek Olšák va += query->buffer.results_end + 8; 16283667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 2, 0); 16383667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1); 16483667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = va; 16583667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = (va >> 32UL) & 0xFF; 16683667acfd9feed932f6864092382e752466975edMarek Olšák break; 16783667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_EMITTED: 16883667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_GENERATED: 16983667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_STATISTICS: 17083667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_OVERFLOW_PREDICATE: 17183667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 2, 0); 17283667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_SAMPLE_STREAMOUTSTATS) | EVENT_INDEX(3); 17383667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = query->buffer.results_end + query->result_size/2; 17483667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = 0; 17583667acfd9feed932f6864092382e752466975edMarek Olšák break; 17683667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_TIME_ELAPSED: 17783667acfd9feed932f6864092382e752466975edMarek Olšák va += query->buffer.results_end + query->result_size/2; 17844f14ebd7b9ba7186342039d2602fdd6ea5077f5Marek Olšák /* fall through */ 17944f14ebd7b9ba7186342039d2602fdd6ea5077f5Marek Olšák case PIPE_QUERY_TIMESTAMP: 18083667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE_EOP, 4, 0); 18183667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5); 18283667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = va; 18383667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = (3 << 29) | ((va >> 32UL) & 0xFF); 18483667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = 0; 18583667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = 0; 18683667acfd9feed932f6864092382e752466975edMarek Olšák break; 18783667acfd9feed932f6864092382e752466975edMarek Olšák default: 18883667acfd9feed932f6864092382e752466975edMarek Olšák assert(0); 18983667acfd9feed932f6864092382e752466975edMarek Olšák } 19083667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0); 19183667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = r600_context_bo_reloc(ctx, query->buffer.buf, RADEON_USAGE_WRITE); 19283667acfd9feed932f6864092382e752466975edMarek Olšák 19383667acfd9feed932f6864092382e752466975edMarek Olšák query->buffer.results_end += query->result_size; 19409ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák 1950018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák if (r600_query_needs_begin(query->type)) { 1960018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák if (r600_is_timer_query(query->type)) { 1970018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák ctx->num_cs_dw_timer_queries_suspend -= query->num_cs_dw; 1980018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák } else { 1990018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák ctx->num_cs_dw_nontimer_queries_suspend -= query->num_cs_dw; 2000018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák } 20109ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák } 20283667acfd9feed932f6864092382e752466975edMarek Olšák} 20383667acfd9feed932f6864092382e752466975edMarek Olšák 20483667acfd9feed932f6864092382e752466975edMarek Olšákstatic void r600_emit_query_predication(struct r600_context *ctx, struct r600_query *query, 20583667acfd9feed932f6864092382e752466975edMarek Olšák int operation, bool flag_wait) 20683667acfd9feed932f6864092382e752466975edMarek Olšák{ 20783667acfd9feed932f6864092382e752466975edMarek Olšák struct radeon_winsys_cs *cs = ctx->cs; 20883667acfd9feed932f6864092382e752466975edMarek Olšák 20983667acfd9feed932f6864092382e752466975edMarek Olšák if (operation == PREDICATION_OP_CLEAR) { 21083667acfd9feed932f6864092382e752466975edMarek Olšák r600_need_cs_space(ctx, 3, FALSE); 21183667acfd9feed932f6864092382e752466975edMarek Olšák 21283667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_SET_PREDICATION, 1, 0); 21383667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = 0; 21483667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PRED_OP(PREDICATION_OP_CLEAR); 21583667acfd9feed932f6864092382e752466975edMarek Olšák } else { 21683667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query_buffer *qbuf; 21783667acfd9feed932f6864092382e752466975edMarek Olšák unsigned count; 21883667acfd9feed932f6864092382e752466975edMarek Olšák uint32_t op; 21983667acfd9feed932f6864092382e752466975edMarek Olšák 22083667acfd9feed932f6864092382e752466975edMarek Olšák /* Find how many results there are. */ 22183667acfd9feed932f6864092382e752466975edMarek Olšák count = 0; 22283667acfd9feed932f6864092382e752466975edMarek Olšák for (qbuf = &query->buffer; qbuf; qbuf = qbuf->previous) { 22383667acfd9feed932f6864092382e752466975edMarek Olšák count += qbuf->results_end / query->result_size; 22483667acfd9feed932f6864092382e752466975edMarek Olšák } 22583667acfd9feed932f6864092382e752466975edMarek Olšák 22683667acfd9feed932f6864092382e752466975edMarek Olšák r600_need_cs_space(ctx, 5 * count, TRUE); 22783667acfd9feed932f6864092382e752466975edMarek Olšák 22883667acfd9feed932f6864092382e752466975edMarek Olšák op = PRED_OP(operation) | PREDICATION_DRAW_VISIBLE | 22983667acfd9feed932f6864092382e752466975edMarek Olšák (flag_wait ? PREDICATION_HINT_WAIT : PREDICATION_HINT_NOWAIT_DRAW); 23083667acfd9feed932f6864092382e752466975edMarek Olšák 23183667acfd9feed932f6864092382e752466975edMarek Olšák /* emit predicate packets for all data blocks */ 23283667acfd9feed932f6864092382e752466975edMarek Olšák for (qbuf = &query->buffer; qbuf; qbuf = qbuf->previous) { 23383667acfd9feed932f6864092382e752466975edMarek Olšák unsigned results_base = 0; 234a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák uint64_t va = r600_resource_va(&ctx->screen->screen, &qbuf->buf->b.b); 23583667acfd9feed932f6864092382e752466975edMarek Olšák 23683667acfd9feed932f6864092382e752466975edMarek Olšák while (results_base < qbuf->results_end) { 23783667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_SET_PREDICATION, 1, 0); 23883667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = (va + results_base) & 0xFFFFFFFFUL; 23983667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = op | (((va + results_base) >> 32UL) & 0xFF); 24083667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0); 24183667acfd9feed932f6864092382e752466975edMarek Olšák cs->buf[cs->cdw++] = r600_context_bo_reloc(ctx, qbuf->buf, RADEON_USAGE_READ); 24283667acfd9feed932f6864092382e752466975edMarek Olšák results_base += query->result_size; 24383667acfd9feed932f6864092382e752466975edMarek Olšák 24483667acfd9feed932f6864092382e752466975edMarek Olšák /* set CONTINUE bit for all packets except the first */ 24583667acfd9feed932f6864092382e752466975edMarek Olšák op |= PREDICATION_CONTINUE; 24683667acfd9feed932f6864092382e752466975edMarek Olšák } 24783667acfd9feed932f6864092382e752466975edMarek Olšák } while (qbuf); 24883667acfd9feed932f6864092382e752466975edMarek Olšák } 24983667acfd9feed932f6864092382e752466975edMarek Olšák} 2501235becaa1cf7e29f580900592563c3329d326deJerome Glisse 2511235becaa1cf7e29f580900592563c3329d326deJerome Glissestatic struct pipe_query *r600_create_query(struct pipe_context *ctx, unsigned query_type) 2521235becaa1cf7e29f580900592563c3329d326deJerome Glisse{ 253e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák struct r600_context *rctx = (struct r600_context *)ctx; 2541235becaa1cf7e29f580900592563c3329d326deJerome Glisse 25583667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query *query; 25683667acfd9feed932f6864092382e752466975edMarek Olšák 25783667acfd9feed932f6864092382e752466975edMarek Olšák query = CALLOC_STRUCT(r600_query); 25883667acfd9feed932f6864092382e752466975edMarek Olšák if (query == NULL) 25983667acfd9feed932f6864092382e752466975edMarek Olšák return NULL; 26083667acfd9feed932f6864092382e752466975edMarek Olšák 26183667acfd9feed932f6864092382e752466975edMarek Olšák query->type = query_type; 26283667acfd9feed932f6864092382e752466975edMarek Olšák 26383667acfd9feed932f6864092382e752466975edMarek Olšák switch (query_type) { 26483667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_COUNTER: 26583667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_PREDICATE: 26683667acfd9feed932f6864092382e752466975edMarek Olšák query->result_size = 16 * rctx->max_db; 26783667acfd9feed932f6864092382e752466975edMarek Olšák query->num_cs_dw = 6; 26883667acfd9feed932f6864092382e752466975edMarek Olšák break; 26983667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_TIME_ELAPSED: 27083667acfd9feed932f6864092382e752466975edMarek Olšák query->result_size = 16; 27183667acfd9feed932f6864092382e752466975edMarek Olšák query->num_cs_dw = 8; 27283667acfd9feed932f6864092382e752466975edMarek Olšák break; 27344f14ebd7b9ba7186342039d2602fdd6ea5077f5Marek Olšák case PIPE_QUERY_TIMESTAMP: 27444f14ebd7b9ba7186342039d2602fdd6ea5077f5Marek Olšák query->result_size = 8; 27544f14ebd7b9ba7186342039d2602fdd6ea5077f5Marek Olšák query->num_cs_dw = 8; 27644f14ebd7b9ba7186342039d2602fdd6ea5077f5Marek Olšák break; 27783667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_EMITTED: 27883667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_GENERATED: 27983667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_STATISTICS: 28083667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_OVERFLOW_PREDICATE: 28183667acfd9feed932f6864092382e752466975edMarek Olšák /* NumPrimitivesWritten, PrimitiveStorageNeeded. */ 28283667acfd9feed932f6864092382e752466975edMarek Olšák query->result_size = 32; 28383667acfd9feed932f6864092382e752466975edMarek Olšák query->num_cs_dw = 6; 28483667acfd9feed932f6864092382e752466975edMarek Olšák break; 28583667acfd9feed932f6864092382e752466975edMarek Olšák default: 28683667acfd9feed932f6864092382e752466975edMarek Olšák assert(0); 28783667acfd9feed932f6864092382e752466975edMarek Olšák FREE(query); 28883667acfd9feed932f6864092382e752466975edMarek Olšák return NULL; 28983667acfd9feed932f6864092382e752466975edMarek Olšák } 29083667acfd9feed932f6864092382e752466975edMarek Olšák 29183667acfd9feed932f6864092382e752466975edMarek Olšák query->buffer.buf = r600_new_query_buffer(rctx, query_type); 29283667acfd9feed932f6864092382e752466975edMarek Olšák if (!query->buffer.buf) { 29383667acfd9feed932f6864092382e752466975edMarek Olšák FREE(query); 29483667acfd9feed932f6864092382e752466975edMarek Olšák return NULL; 29583667acfd9feed932f6864092382e752466975edMarek Olšák } 29683667acfd9feed932f6864092382e752466975edMarek Olšák return (struct pipe_query*)query; 2971235becaa1cf7e29f580900592563c3329d326deJerome Glisse} 2981235becaa1cf7e29f580900592563c3329d326deJerome Glisse 2991235becaa1cf7e29f580900592563c3329d326deJerome Glissestatic void r600_destroy_query(struct pipe_context *ctx, struct pipe_query *query) 3001235becaa1cf7e29f580900592563c3329d326deJerome Glisse{ 30183667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query *rquery = (struct r600_query*)query; 302eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák struct r600_query_buffer *prev = rquery->buffer.previous; 303eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák 304eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák /* Release all query buffers. */ 305eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák while (prev) { 306eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák struct r600_query_buffer *qbuf = prev; 307eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák prev = prev->previous; 308eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák pipe_resource_reference((struct pipe_resource**)&qbuf->buf, NULL); 309eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák FREE(qbuf); 310eabcecc26baf225dc50f1d400a80ea4c78831390Marek Olšák } 3111235becaa1cf7e29f580900592563c3329d326deJerome Glisse 31283667acfd9feed932f6864092382e752466975edMarek Olšák pipe_resource_reference((struct pipe_resource**)&rquery->buffer.buf, NULL); 31383667acfd9feed932f6864092382e752466975edMarek Olšák FREE(query); 3141235becaa1cf7e29f580900592563c3329d326deJerome Glisse} 3151235becaa1cf7e29f580900592563c3329d326deJerome Glisse 316e2809849ecac69615ece294a55ee355afaac33d3Marek Olšákstatic void r600_update_occlusion_query_state(struct r600_context *rctx, 317e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák unsigned type, int diff) 318e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák{ 319e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák if (type == PIPE_QUERY_OCCLUSION_COUNTER || 320e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák type == PIPE_QUERY_OCCLUSION_PREDICATE) { 321e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák bool enable; 322e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák 323e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák rctx->num_occlusion_queries += diff; 324e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák assert(rctx->num_occlusion_queries >= 0); 325e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák 326e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák enable = rctx->num_occlusion_queries != 0; 327e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák 328e363dd5c7d8ba40984d937ad7487abbb5be439bcMarek Olšák if (rctx->db_misc_state.occlusion_query_enabled != enable) { 329e363dd5c7d8ba40984d937ad7487abbb5be439bcMarek Olšák rctx->db_misc_state.occlusion_query_enabled = enable; 330e363dd5c7d8ba40984d937ad7487abbb5be439bcMarek Olšák r600_atom_dirty(rctx, &rctx->db_misc_state.atom); 331e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák } 332e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák } 333e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák} 334e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák 33583667acfd9feed932f6864092382e752466975edMarek Olšákstatic void r600_begin_query(struct pipe_context *ctx, struct pipe_query *query) 336df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák{ 33783667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_context *rctx = (struct r600_context *)ctx; 33883667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query *rquery = (struct r600_query *)query; 33983667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query_buffer *prev = rquery->buffer.previous; 340df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák 3410018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák if (!r600_query_needs_begin(rquery->type)) { 3420018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák assert(0); 3430018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák return; 3440018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák } 3450018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák 3460018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák /* Discard the old query buffers. */ 347df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák while (prev) { 348df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák struct r600_query_buffer *qbuf = prev; 349df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák prev = prev->previous; 350df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák pipe_resource_reference((struct pipe_resource**)&qbuf->buf, NULL); 351df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák FREE(qbuf); 352df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák } 353df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák 354df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák /* Obtain a new buffer if the current one can't be mapped without a stall. */ 35529e55bc5f1b6d7375b6a86e24ca4ae58e399011eMarek Olšák if (rctx->ws->cs_is_buffer_referenced(rctx->cs, rquery->buffer.buf->cs_buf, RADEON_USAGE_READWRITE) || 35683667acfd9feed932f6864092382e752466975edMarek Olšák rctx->ws->buffer_is_busy(rquery->buffer.buf->buf, RADEON_USAGE_READWRITE)) { 35783667acfd9feed932f6864092382e752466975edMarek Olšák pipe_resource_reference((struct pipe_resource**)&rquery->buffer.buf, NULL); 35883667acfd9feed932f6864092382e752466975edMarek Olšák rquery->buffer.buf = r600_new_query_buffer(rctx, rquery->type); 359df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák } 360df00dc3c817771ac5034a44dff2b14cd7759b207Marek Olšák 36183667acfd9feed932f6864092382e752466975edMarek Olšák rquery->buffer.results_end = 0; 36283667acfd9feed932f6864092382e752466975edMarek Olšák rquery->buffer.previous = NULL; 3631235becaa1cf7e29f580900592563c3329d326deJerome Glisse 364e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák r600_update_occlusion_query_state(rctx, rquery->type, 1); 365e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák 36683667acfd9feed932f6864092382e752466975edMarek Olšák r600_emit_query_begin(rctx, rquery); 36709ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák 36809ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák if (r600_is_timer_query(rquery->type)) { 36909ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák LIST_ADDTAIL(&rquery->list, &rctx->active_timer_queries); 37009ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák } else { 37109ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák LIST_ADDTAIL(&rquery->list, &rctx->active_nontimer_queries); 37209ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák } 3731235becaa1cf7e29f580900592563c3329d326deJerome Glisse} 3741235becaa1cf7e29f580900592563c3329d326deJerome Glisse 3751235becaa1cf7e29f580900592563c3329d326deJerome Glissestatic void r600_end_query(struct pipe_context *ctx, struct pipe_query *query) 3761235becaa1cf7e29f580900592563c3329d326deJerome Glisse{ 377e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák struct r600_context *rctx = (struct r600_context *)ctx; 378e9b6f21a5054b2639a1dfc6401e4e9053dce5394Marek Olšák struct r600_query *rquery = (struct r600_query *)query; 3791235becaa1cf7e29f580900592563c3329d326deJerome Glisse 38083667acfd9feed932f6864092382e752466975edMarek Olšák r600_emit_query_end(rctx, rquery); 3810018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák 3820018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák if (r600_query_needs_begin(rquery->type)) { 3830018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák LIST_DELINIT(&rquery->list); 3840018db1126c443c4d70947010dcf1afa37e5fb16Marek Olšák } 385e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák 386e2809849ecac69615ece294a55ee355afaac33d3Marek Olšák r600_update_occlusion_query_state(rctx, rquery->type, -1); 3871235becaa1cf7e29f580900592563c3329d326deJerome Glisse} 3881235becaa1cf7e29f580900592563c3329d326deJerome Glisse 38983667acfd9feed932f6864092382e752466975edMarek Olšákstatic unsigned r600_query_read_result(char *map, unsigned start_index, unsigned end_index, 39083667acfd9feed932f6864092382e752466975edMarek Olšák bool test_status_bit) 39183667acfd9feed932f6864092382e752466975edMarek Olšák{ 39283667acfd9feed932f6864092382e752466975edMarek Olšák uint32_t *current_result = (uint32_t*)map; 39383667acfd9feed932f6864092382e752466975edMarek Olšák uint64_t start, end; 39483667acfd9feed932f6864092382e752466975edMarek Olšák 39583667acfd9feed932f6864092382e752466975edMarek Olšák start = (uint64_t)current_result[start_index] | 39683667acfd9feed932f6864092382e752466975edMarek Olšák (uint64_t)current_result[start_index+1] << 32; 39783667acfd9feed932f6864092382e752466975edMarek Olšák end = (uint64_t)current_result[end_index] | 39883667acfd9feed932f6864092382e752466975edMarek Olšák (uint64_t)current_result[end_index+1] << 32; 39983667acfd9feed932f6864092382e752466975edMarek Olšák 40083667acfd9feed932f6864092382e752466975edMarek Olšák if (!test_status_bit || 40183667acfd9feed932f6864092382e752466975edMarek Olšák ((start & 0x8000000000000000UL) && (end & 0x8000000000000000UL))) { 40283667acfd9feed932f6864092382e752466975edMarek Olšák return end - start; 40383667acfd9feed932f6864092382e752466975edMarek Olšák } 40483667acfd9feed932f6864092382e752466975edMarek Olšák return 0; 40583667acfd9feed932f6864092382e752466975edMarek Olšák} 40683667acfd9feed932f6864092382e752466975edMarek Olšák 40783667acfd9feed932f6864092382e752466975edMarek Olšákstatic boolean r600_get_query_buffer_result(struct r600_context *ctx, 40883667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query *query, 40983667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query_buffer *qbuf, 41083667acfd9feed932f6864092382e752466975edMarek Olšák boolean wait, 411ead0a89c9661135d66e086bbe524f9623b00af5bMarek Olšák union pipe_query_result *result) 41283667acfd9feed932f6864092382e752466975edMarek Olšák{ 41383667acfd9feed932f6864092382e752466975edMarek Olšák unsigned results_base = 0; 41483667acfd9feed932f6864092382e752466975edMarek Olšák char *map; 41583667acfd9feed932f6864092382e752466975edMarek Olšák 4160a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák map = ctx->ws->buffer_map(qbuf->buf->cs_buf, ctx->cs, 41783667acfd9feed932f6864092382e752466975edMarek Olšák PIPE_TRANSFER_READ | 41883667acfd9feed932f6864092382e752466975edMarek Olšák (wait ? 0 : PIPE_TRANSFER_DONTBLOCK)); 41983667acfd9feed932f6864092382e752466975edMarek Olšák if (!map) 42083667acfd9feed932f6864092382e752466975edMarek Olšák return FALSE; 42183667acfd9feed932f6864092382e752466975edMarek Olšák 42283667acfd9feed932f6864092382e752466975edMarek Olšák /* count all results across all data blocks */ 42383667acfd9feed932f6864092382e752466975edMarek Olšák switch (query->type) { 42483667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_COUNTER: 42583667acfd9feed932f6864092382e752466975edMarek Olšák while (results_base != qbuf->results_end) { 42683667acfd9feed932f6864092382e752466975edMarek Olšák result->u64 += 42783667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 0, 2, true); 42883667acfd9feed932f6864092382e752466975edMarek Olšák results_base += 16; 42983667acfd9feed932f6864092382e752466975edMarek Olšák } 43083667acfd9feed932f6864092382e752466975edMarek Olšák break; 43183667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_OCCLUSION_PREDICATE: 43283667acfd9feed932f6864092382e752466975edMarek Olšák while (results_base != qbuf->results_end) { 43383667acfd9feed932f6864092382e752466975edMarek Olšák result->b = result->b || 43483667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 0, 2, true) != 0; 43583667acfd9feed932f6864092382e752466975edMarek Olšák results_base += 16; 43683667acfd9feed932f6864092382e752466975edMarek Olšák } 43783667acfd9feed932f6864092382e752466975edMarek Olšák break; 43883667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_TIME_ELAPSED: 43983667acfd9feed932f6864092382e752466975edMarek Olšák while (results_base != qbuf->results_end) { 44083667acfd9feed932f6864092382e752466975edMarek Olšák result->u64 += 44183667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 0, 2, false); 44283667acfd9feed932f6864092382e752466975edMarek Olšák results_base += query->result_size; 44383667acfd9feed932f6864092382e752466975edMarek Olšák } 44483667acfd9feed932f6864092382e752466975edMarek Olšák break; 44544f14ebd7b9ba7186342039d2602fdd6ea5077f5Marek Olšák case PIPE_QUERY_TIMESTAMP: 44644f14ebd7b9ba7186342039d2602fdd6ea5077f5Marek Olšák { 44744f14ebd7b9ba7186342039d2602fdd6ea5077f5Marek Olšák uint32_t *current_result = (uint32_t*)map; 44844f14ebd7b9ba7186342039d2602fdd6ea5077f5Marek Olšák result->u64 = (uint64_t)current_result[0] | 44944f14ebd7b9ba7186342039d2602fdd6ea5077f5Marek Olšák (uint64_t)current_result[1] << 32; 45044f14ebd7b9ba7186342039d2602fdd6ea5077f5Marek Olšák break; 45144f14ebd7b9ba7186342039d2602fdd6ea5077f5Marek Olšák } 45283667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_EMITTED: 45383667acfd9feed932f6864092382e752466975edMarek Olšák /* SAMPLE_STREAMOUTSTATS stores this structure: 45483667acfd9feed932f6864092382e752466975edMarek Olšák * { 45583667acfd9feed932f6864092382e752466975edMarek Olšák * u64 NumPrimitivesWritten; 45683667acfd9feed932f6864092382e752466975edMarek Olšák * u64 PrimitiveStorageNeeded; 45783667acfd9feed932f6864092382e752466975edMarek Olšák * } 45883667acfd9feed932f6864092382e752466975edMarek Olšák * We only need NumPrimitivesWritten here. */ 45983667acfd9feed932f6864092382e752466975edMarek Olšák while (results_base != qbuf->results_end) { 46083667acfd9feed932f6864092382e752466975edMarek Olšák result->u64 += 46183667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 2, 6, true); 46283667acfd9feed932f6864092382e752466975edMarek Olšák results_base += query->result_size; 46383667acfd9feed932f6864092382e752466975edMarek Olšák } 46483667acfd9feed932f6864092382e752466975edMarek Olšák break; 46583667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_PRIMITIVES_GENERATED: 46683667acfd9feed932f6864092382e752466975edMarek Olšák /* Here we read PrimitiveStorageNeeded. */ 46783667acfd9feed932f6864092382e752466975edMarek Olšák while (results_base != qbuf->results_end) { 46883667acfd9feed932f6864092382e752466975edMarek Olšák result->u64 += 46983667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 0, 4, true); 47083667acfd9feed932f6864092382e752466975edMarek Olšák results_base += query->result_size; 47183667acfd9feed932f6864092382e752466975edMarek Olšák } 47283667acfd9feed932f6864092382e752466975edMarek Olšák break; 47383667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_STATISTICS: 47483667acfd9feed932f6864092382e752466975edMarek Olšák while (results_base != qbuf->results_end) { 475ead0a89c9661135d66e086bbe524f9623b00af5bMarek Olšák result->so_statistics.num_primitives_written += 47683667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 2, 6, true); 477ead0a89c9661135d66e086bbe524f9623b00af5bMarek Olšák result->so_statistics.primitives_storage_needed += 47883667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 0, 4, true); 47983667acfd9feed932f6864092382e752466975edMarek Olšák results_base += query->result_size; 48083667acfd9feed932f6864092382e752466975edMarek Olšák } 48183667acfd9feed932f6864092382e752466975edMarek Olšák break; 48283667acfd9feed932f6864092382e752466975edMarek Olšák case PIPE_QUERY_SO_OVERFLOW_PREDICATE: 48383667acfd9feed932f6864092382e752466975edMarek Olšák while (results_base != qbuf->results_end) { 48483667acfd9feed932f6864092382e752466975edMarek Olšák result->b = result->b || 48583667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 2, 6, true) != 48683667acfd9feed932f6864092382e752466975edMarek Olšák r600_query_read_result(map + results_base, 0, 4, true); 48783667acfd9feed932f6864092382e752466975edMarek Olšák results_base += query->result_size; 48883667acfd9feed932f6864092382e752466975edMarek Olšák } 48983667acfd9feed932f6864092382e752466975edMarek Olšák break; 49083667acfd9feed932f6864092382e752466975edMarek Olšák default: 49183667acfd9feed932f6864092382e752466975edMarek Olšák assert(0); 49283667acfd9feed932f6864092382e752466975edMarek Olšák } 49383667acfd9feed932f6864092382e752466975edMarek Olšák 4940a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák ctx->ws->buffer_unmap(qbuf->buf->cs_buf); 49583667acfd9feed932f6864092382e752466975edMarek Olšák return TRUE; 49683667acfd9feed932f6864092382e752466975edMarek Olšák} 49783667acfd9feed932f6864092382e752466975edMarek Olšák 4981235becaa1cf7e29f580900592563c3329d326deJerome Glissestatic boolean r600_get_query_result(struct pipe_context *ctx, 4991235becaa1cf7e29f580900592563c3329d326deJerome Glisse struct pipe_query *query, 500ead0a89c9661135d66e086bbe524f9623b00af5bMarek Olšák boolean wait, union pipe_query_result *result) 5011235becaa1cf7e29f580900592563c3329d326deJerome Glisse{ 502e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák struct r600_context *rctx = (struct r600_context *)ctx; 5031235becaa1cf7e29f580900592563c3329d326deJerome Glisse struct r600_query *rquery = (struct r600_query *)query; 50483667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query_buffer *qbuf; 50583667acfd9feed932f6864092382e752466975edMarek Olšák 506ead0a89c9661135d66e086bbe524f9623b00af5bMarek Olšák util_query_clear_result(result, rquery->type); 50783667acfd9feed932f6864092382e752466975edMarek Olšák 50883667acfd9feed932f6864092382e752466975edMarek Olšák for (qbuf = &rquery->buffer; qbuf; qbuf = qbuf->previous) { 509ead0a89c9661135d66e086bbe524f9623b00af5bMarek Olšák if (!r600_get_query_buffer_result(rctx, rquery, qbuf, wait, result)) { 51083667acfd9feed932f6864092382e752466975edMarek Olšák return FALSE; 51183667acfd9feed932f6864092382e752466975edMarek Olšák } 51283667acfd9feed932f6864092382e752466975edMarek Olšák } 5131235becaa1cf7e29f580900592563c3329d326deJerome Glisse 514ead0a89c9661135d66e086bbe524f9623b00af5bMarek Olšák /* Convert the time to expected units. */ 51544f14ebd7b9ba7186342039d2602fdd6ea5077f5Marek Olšák if (rquery->type == PIPE_QUERY_TIME_ELAPSED || 51644f14ebd7b9ba7186342039d2602fdd6ea5077f5Marek Olšák rquery->type == PIPE_QUERY_TIMESTAMP) { 517ead0a89c9661135d66e086bbe524f9623b00af5bMarek Olšák result->u64 = (1000000 * result->u64) / rctx->screen->info.r600_clock_crystal_freq; 51883667acfd9feed932f6864092382e752466975edMarek Olšák } 51983667acfd9feed932f6864092382e752466975edMarek Olšák return TRUE; 5201235becaa1cf7e29f580900592563c3329d326deJerome Glisse} 5211235becaa1cf7e29f580900592563c3329d326deJerome Glisse 522a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airliestatic void r600_render_condition(struct pipe_context *ctx, 523a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie struct pipe_query *query, 524a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie uint mode) 525a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie{ 526e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák struct r600_context *rctx = (struct r600_context *)ctx; 527a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie struct r600_query *rquery = (struct r600_query *)query; 52883667acfd9feed932f6864092382e752466975edMarek Olšák bool wait_flag = false; 529a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie 5306f243ec25d88589747c7a595903e201b90a4d767Marek Olšák rctx->current_render_cond = query; 5316f243ec25d88589747c7a595903e201b90a4d767Marek Olšák rctx->current_render_cond_mode = mode; 5326f243ec25d88589747c7a595903e201b90a4d767Marek Olšák 533ef29bfee031cdab3dbb0f9a79828c4b0d0405991Vadim Girlin if (query == NULL) { 534e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák if (rctx->predicate_drawing) { 535e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák rctx->predicate_drawing = false; 53683667acfd9feed932f6864092382e752466975edMarek Olšák r600_emit_query_predication(rctx, NULL, PREDICATION_OP_CLEAR, false); 537ef29bfee031cdab3dbb0f9a79828c4b0d0405991Vadim Girlin } 538a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie return; 539a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie } 540a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie 541a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie if (mode == PIPE_RENDER_COND_WAIT || 542a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie mode == PIPE_RENDER_COND_BY_REGION_WAIT) { 54383667acfd9feed932f6864092382e752466975edMarek Olšák wait_flag = true; 544a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie } 545a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie 546e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák rctx->predicate_drawing = true; 547543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák 548543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák switch (rquery->type) { 549543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák case PIPE_QUERY_OCCLUSION_COUNTER: 550543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák case PIPE_QUERY_OCCLUSION_PREDICATE: 55183667acfd9feed932f6864092382e752466975edMarek Olšák r600_emit_query_predication(rctx, rquery, PREDICATION_OP_ZPASS, wait_flag); 552543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák break; 553543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák case PIPE_QUERY_PRIMITIVES_EMITTED: 554543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák case PIPE_QUERY_PRIMITIVES_GENERATED: 555543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák case PIPE_QUERY_SO_STATISTICS: 556543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák case PIPE_QUERY_SO_OVERFLOW_PREDICATE: 55783667acfd9feed932f6864092382e752466975edMarek Olšák r600_emit_query_predication(rctx, rquery, PREDICATION_OP_PRIMCOUNT, wait_flag); 558543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák break; 559543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák default: 560543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák assert(0); 561543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák } 562a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie} 563a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie 56409ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšákvoid r600_suspend_nontimer_queries(struct r600_context *ctx) 56583667acfd9feed932f6864092382e752466975edMarek Olšák{ 56683667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query *query; 56783667acfd9feed932f6864092382e752466975edMarek Olšák 56809ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák LIST_FOR_EACH_ENTRY(query, &ctx->active_nontimer_queries, list) { 56983667acfd9feed932f6864092382e752466975edMarek Olšák r600_emit_query_end(ctx, query); 57083667acfd9feed932f6864092382e752466975edMarek Olšák } 57109ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák assert(ctx->num_cs_dw_nontimer_queries_suspend == 0); 57209ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák} 57309ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák 57409ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšákvoid r600_resume_nontimer_queries(struct r600_context *ctx) 57509ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák{ 57609ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák struct r600_query *query; 57709ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák 57809ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák assert(ctx->num_cs_dw_nontimer_queries_suspend == 0); 57909ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák 58009ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák LIST_FOR_EACH_ENTRY(query, &ctx->active_nontimer_queries, list) { 58109ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák r600_emit_query_begin(ctx, query); 58209ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák } 58309ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák} 58409ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák 58509ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšákvoid r600_suspend_timer_queries(struct r600_context *ctx) 58609ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák{ 58709ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák struct r600_query *query; 58809ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák 58909ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák LIST_FOR_EACH_ENTRY(query, &ctx->active_timer_queries, list) { 59009ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák r600_emit_query_end(ctx, query); 59109ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák } 59209ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák 59309ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák assert(ctx->num_cs_dw_timer_queries_suspend == 0); 59483667acfd9feed932f6864092382e752466975edMarek Olšák} 59583667acfd9feed932f6864092382e752466975edMarek Olšák 59609ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšákvoid r600_resume_timer_queries(struct r600_context *ctx) 59783667acfd9feed932f6864092382e752466975edMarek Olšák{ 59883667acfd9feed932f6864092382e752466975edMarek Olšák struct r600_query *query; 59983667acfd9feed932f6864092382e752466975edMarek Olšák 60009ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák assert(ctx->num_cs_dw_timer_queries_suspend == 0); 60183667acfd9feed932f6864092382e752466975edMarek Olšák 60209ec30f02830b3cbf9d6ac04d9497634dca86846Marek Olšák LIST_FOR_EACH_ENTRY(query, &ctx->active_timer_queries, list) { 60383667acfd9feed932f6864092382e752466975edMarek Olšák r600_emit_query_begin(ctx, query); 60483667acfd9feed932f6864092382e752466975edMarek Olšák } 60583667acfd9feed932f6864092382e752466975edMarek Olšák} 60683667acfd9feed932f6864092382e752466975edMarek Olšák 607e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšákvoid r600_init_query_functions(struct r600_context *rctx) 6081235becaa1cf7e29f580900592563c3329d326deJerome Glisse{ 6091235becaa1cf7e29f580900592563c3329d326deJerome Glisse rctx->context.create_query = r600_create_query; 6101235becaa1cf7e29f580900592563c3329d326deJerome Glisse rctx->context.destroy_query = r600_destroy_query; 6111235becaa1cf7e29f580900592563c3329d326deJerome Glisse rctx->context.begin_query = r600_begin_query; 6121235becaa1cf7e29f580900592563c3329d326deJerome Glisse rctx->context.end_query = r600_end_query; 6131235becaa1cf7e29f580900592563c3329d326deJerome Glisse rctx->context.get_query_result = r600_get_query_result; 614a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie 6151a532ca79a4a87bb86c641a6ca22da0301dc1f62Marek Olšák if (rctx->screen->info.r600_num_backends > 0) 616a44b65312e2cbba641652f4c78b8db9f24ba39b6Dave Airlie rctx->context.render_condition = r600_render_condition; 6171235becaa1cf7e29f580900592563c3329d326deJerome Glisse} 618