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