1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * on the rights to use, copy, modify, merge, publish, distribute, sub
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * license, and/or sell copies of the Software, and to permit persons to whom
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the Software is furnished to do so, subject to the following conditions:
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software.
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * USE OR OTHER DEALINGS IN THE SOFTWARE.
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Authors:
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *      Jerome Glisse
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "r600_hw_context_priv.h"
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeonsi_pm4.h"
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeonsi_pipe.h"
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "sid.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <errno.h>
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define GROUP_FORCE_NEW_BLOCK	0
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Get backends mask */
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid si_get_backend_mask(struct r600_context *ctx)
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_winsys_cs *cs = ctx->cs;
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct si_resource *buffer;
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint32_t *results;
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned num_backends = ctx->screen->info.r600_num_backends;
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned i, mask = 0;
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* if backend_map query is supported by the kernel */
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (ctx->screen->info.r600_backend_map_valid) {
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned num_tile_pipes = ctx->screen->info.r600_num_tile_pipes;
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned backend_map = ctx->screen->info.r600_backend_map;
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned item_width, item_mask;
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (ctx->chip_class >= CAYMAN) {
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			item_width = 4;
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			item_mask = 0x7;
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		while(num_tile_pipes--) {
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			i = backend_map & item_mask;
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			mask |= (1<<i);
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			backend_map >>= item_width;
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (mask != 0) {
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			ctx->backend_mask = mask;
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return;
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* otherwise backup path for older kernels */
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* create buffer for event data */
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	buffer = si_resource_create_custom(&ctx->screen->screen,
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   PIPE_USAGE_STAGING,
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   ctx->max_db*16);
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!buffer)
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		goto err;
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* initialize buffer with zeroes */
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	results = ctx->ws->buffer_map(buffer->cs_buf, ctx->cs, PIPE_TRANSFER_WRITE);
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (results) {
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		uint64_t va = 0;
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(results, 0, ctx->max_db * 4 * 4);
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ctx->ws->buffer_unmap(buffer->cs_buf);
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* emit EVENT_WRITE for ZPASS_DONE */
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		va = r600_resource_va(&ctx->screen->screen, (void *)buffer);
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 2, 0);
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1);
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = va;
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = va >> 32;
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0);
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = r600_context_bo_reloc(ctx, buffer, RADEON_USAGE_WRITE);
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* analyze results */
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		results = ctx->ws->buffer_map(buffer->cs_buf, ctx->cs, PIPE_TRANSFER_READ);
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (results) {
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(i = 0; i < ctx->max_db; i++) {
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				/* at least highest bit will be set if backend is used */
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				if (results[i*4 + 1])
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					mask |= (1<<i);
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			ctx->ws->buffer_unmap(buffer->cs_buf);
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	si_resource_reference(&buffer, NULL);
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (mask != 0) {
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ctx->backend_mask = mask;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return;
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgerr:
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* fallback to old method - set num_backends lower bits to 1 */
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->backend_mask = (~((uint32_t)0))>>(32-num_backends);
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* initialize */
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid si_need_cs_space(struct r600_context *ctx, unsigned num_dw,
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			boolean count_draw_in)
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* The number of dwords we already used in the CS so far. */
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	num_dw += ctx->cs->cdw;
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (count_draw_in) {
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* The number of dwords all the dirty states would take. */
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		num_dw += ctx->pm4_dirty_cdwords;
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* The upper-bound of how much a draw command would take. */
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		num_dw += SI_MAX_DRAW_CS_DWORDS;
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Count in queries_suspend. */
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	num_dw += ctx->num_cs_dw_queries_suspend;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Count in streamout_end at the end of CS. */
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	num_dw += ctx->num_cs_dw_streamout_end;
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Count in render_condition(NULL) at the end of CS. */
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (ctx->predicate_drawing) {
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		num_dw += 3;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Count in framebuffer cache flushes at the end of CS. */
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	num_dw += 7; /* one SURFACE_SYNC and CACHE_FLUSH_AND_INV (r6xx-only) */
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Save 16 dwords for the fence mechanism. */
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	num_dw += 16;
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Flush if there's not enough space. */
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (num_dw > RADEON_MAX_CMDBUF_DWORDS) {
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		radeonsi_flush(&ctx->context, NULL, RADEON_FLUSH_ASYNC);
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void r600_flush_framebuffer(struct r600_context *ctx)
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct si_pm4_state *pm4;
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!(ctx->flags & R600_CONTEXT_DST_CACHES_DIRTY))
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return;
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pm4 = CALLOC_STRUCT(si_pm4_state);
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	si_cmd_surface_sync(pm4, S_0085F0_CB0_DEST_BASE_ENA(1) |
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				S_0085F0_CB1_DEST_BASE_ENA(1) |
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				S_0085F0_CB2_DEST_BASE_ENA(1) |
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				S_0085F0_CB3_DEST_BASE_ENA(1) |
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				S_0085F0_CB4_DEST_BASE_ENA(1) |
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				S_0085F0_CB5_DEST_BASE_ENA(1) |
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				S_0085F0_CB6_DEST_BASE_ENA(1) |
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				S_0085F0_CB7_DEST_BASE_ENA(1) |
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				S_0085F0_DB_ACTION_ENA(1) |
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				S_0085F0_DB_DEST_BASE_ENA(1));
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	si_pm4_emit(ctx, pm4);
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	si_pm4_free_state(ctx, pm4, ~0);
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->flags &= ~R600_CONTEXT_DST_CACHES_DIRTY;
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid si_context_flush(struct r600_context *ctx, unsigned flags)
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_winsys_cs *cs = ctx->cs;
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bool queries_suspended = false;
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bool streamout_suspended = false;
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!cs->cdw)
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return;
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* suspend queries */
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (ctx->num_cs_dw_queries_suspend) {
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		r600_context_queries_suspend(ctx);
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		queries_suspended = true;
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (ctx->num_cs_dw_streamout_end) {
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		r600_context_streamout_end(ctx);
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		streamout_suspended = true;
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600_flush_framebuffer(ctx);
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* partial flush is needed to avoid lockups on some chips with user fences */
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0);
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4);
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* force to keep tiling flags */
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	flags |= RADEON_FLUSH_KEEP_TILING_FLAGS;
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Flush the CS. */
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->ws->cs_flush(ctx->cs, flags);
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->pm4_dirty_cdwords = 0;
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->flags = 0;
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (streamout_suspended) {
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ctx->streamout_start = TRUE;
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ctx->streamout_append_bitmask = ~0;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* resume queries */
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (queries_suspended) {
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		r600_context_queries_resume(ctx);
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* set all valid group as dirty so they get reemited on
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * next draw command
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 */
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	si_pm4_reset_emitted(ctx);
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid si_context_emit_fence(struct r600_context *ctx, struct si_resource *fence_bo, unsigned offset, unsigned value)
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_winsys_cs *cs = ctx->cs;
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint64_t va;
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	si_need_cs_space(ctx, 10, FALSE);
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	va = r600_resource_va(&ctx->screen->screen, (void*)fence_bo);
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	va = va + (offset << 2);
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0);
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4);
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE_EOP, 4, 0);
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5);
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = va & 0xFFFFFFFFUL;       /* ADDRESS_LO */
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* DATA_SEL | INT_EN | ADDRESS_HI */
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = (1 << 29) | (0 << 24) | ((va >> 32UL) & 0xFF);
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = value;                   /* DATA_LO */
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = 0;                       /* DATA_HI */
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0);
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = r600_context_bo_reloc(ctx, fence_bo, RADEON_USAGE_WRITE);
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned r600_query_read_result(char *map, unsigned start_index, unsigned end_index,
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       bool test_status_bit)
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint32_t *current_result = (uint32_t*)map;
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint64_t start, end;
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	start = (uint64_t)current_result[start_index] |
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		(uint64_t)current_result[start_index+1] << 32;
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	end = (uint64_t)current_result[end_index] |
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      (uint64_t)current_result[end_index+1] << 32;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!test_status_bit ||
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ((start & 0x8000000000000000UL) && (end & 0x8000000000000000UL))) {
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return end - start;
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return 0;
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean r600_query_result(struct r600_context *ctx, struct r600_query *query, boolean wait)
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned results_base = query->results_start;
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	char *map;
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	map = ctx->ws->buffer_map(query->buffer->cs_buf, ctx->cs,
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  PIPE_TRANSFER_READ |
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  (wait ? 0 : PIPE_TRANSFER_DONTBLOCK));
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!map)
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return FALSE;
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* count all results across all data blocks */
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (query->type) {
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_OCCLUSION_COUNTER:
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		while (results_base != query->results_end) {
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			query->result.u64 +=
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				r600_query_read_result(map + results_base, 0, 2, true);
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			results_base = (results_base + 16) % query->buffer->b.b.width0;
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_OCCLUSION_PREDICATE:
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		while (results_base != query->results_end) {
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			query->result.b = query->result.b ||
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				r600_query_read_result(map + results_base, 0, 2, true) != 0;
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			results_base = (results_base + 16) % query->buffer->b.b.width0;
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_TIME_ELAPSED:
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		while (results_base != query->results_end) {
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			query->result.u64 +=
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				r600_query_read_result(map + results_base, 0, 2, false);
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			results_base = (results_base + query->result_size) % query->buffer->b.b.width0;
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_PRIMITIVES_EMITTED:
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* SAMPLE_STREAMOUTSTATS stores this structure:
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * {
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 *    u64 NumPrimitivesWritten;
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 *    u64 PrimitiveStorageNeeded;
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * }
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * We only need NumPrimitivesWritten here. */
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		while (results_base != query->results_end) {
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			query->result.u64 +=
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				r600_query_read_result(map + results_base, 2, 6, true);
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			results_base = (results_base + query->result_size) % query->buffer->b.b.width0;
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_PRIMITIVES_GENERATED:
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* Here we read PrimitiveStorageNeeded. */
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		while (results_base != query->results_end) {
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			query->result.u64 +=
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				r600_query_read_result(map + results_base, 0, 4, true);
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			results_base = (results_base + query->result_size) % query->buffer->b.b.width0;
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_SO_STATISTICS:
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		while (results_base != query->results_end) {
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			query->result.so.num_primitives_written +=
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				r600_query_read_result(map + results_base, 2, 6, true);
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			query->result.so.primitives_storage_needed +=
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				r600_query_read_result(map + results_base, 0, 4, true);
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			results_base = (results_base + query->result_size) % query->buffer->b.b.width0;
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		while (results_base != query->results_end) {
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			query->result.b = query->result.b ||
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				r600_query_read_result(map + results_base, 2, 6, true) !=
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				r600_query_read_result(map + results_base, 0, 4, true);
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			results_base = (results_base + query->result_size) % query->buffer->b.b.width0;
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		assert(0);
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	query->results_start = query->results_end;
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->ws->buffer_unmap(query->buffer->cs_buf);
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return TRUE;
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid r600_query_begin(struct r600_context *ctx, struct r600_query *query)
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_winsys_cs *cs = ctx->cs;
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned new_results_end, i;
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint32_t *results;
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint64_t va;
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	si_need_cs_space(ctx, query->num_cs_dw * 2, TRUE);
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	new_results_end = (query->results_end + query->result_size) % query->buffer->b.b.width0;
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* collect current results if query buffer is full */
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (new_results_end == query->results_start) {
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		r600_query_result(ctx, query, TRUE);
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (query->type) {
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_OCCLUSION_COUNTER:
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_OCCLUSION_PREDICATE:
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		results = ctx->ws->buffer_map(query->buffer->cs_buf, ctx->cs, PIPE_TRANSFER_WRITE);
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (results) {
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			results = (uint32_t*)((char*)results + query->results_end);
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			memset(results, 0, query->result_size);
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			/* Set top bits for unused backends */
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for (i = 0; i < ctx->max_db; i++) {
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				if (!(ctx->backend_mask & (1<<i))) {
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					results[(i * 4)+1] = 0x80000000;
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					results[(i * 4)+3] = 0x80000000;
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				}
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			ctx->ws->buffer_unmap(query->buffer->cs_buf);
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_TIME_ELAPSED:
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_PRIMITIVES_EMITTED:
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_PRIMITIVES_GENERATED:
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_SO_STATISTICS:
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		results = ctx->ws->buffer_map(query->buffer->cs_buf, ctx->cs, PIPE_TRANSFER_WRITE);
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		results = (uint32_t*)((char*)results + query->results_end);
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(results, 0, query->result_size);
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ctx->ws->buffer_unmap(query->buffer->cs_buf);
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		assert(0);
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* emit begin query */
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	va = r600_resource_va(&ctx->screen->screen, (void*)query->buffer);
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	va += query->results_end;
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (query->type) {
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_OCCLUSION_COUNTER:
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_OCCLUSION_PREDICATE:
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 2, 0);
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1);
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = va;
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = (va >> 32UL) & 0xFF;
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_PRIMITIVES_EMITTED:
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_PRIMITIVES_GENERATED:
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_SO_STATISTICS:
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 2, 0);
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_SAMPLE_STREAMOUTSTATS) | EVENT_INDEX(3);
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = query->results_end;
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = 0;
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_TIME_ELAPSED:
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE_EOP, 4, 0);
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5);
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = va;
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = (3 << 29) | ((va >> 32UL) & 0xFF);
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = 0;
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = 0;
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		assert(0);
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0);
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = r600_context_bo_reloc(ctx, query->buffer, RADEON_USAGE_WRITE);
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->num_cs_dw_queries_suspend += query->num_cs_dw;
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid r600_query_end(struct r600_context *ctx, struct r600_query *query)
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_winsys_cs *cs = ctx->cs;
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint64_t va;
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	va = r600_resource_va(&ctx->screen->screen, (void*)query->buffer);
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* emit end query */
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (query->type) {
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_OCCLUSION_COUNTER:
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_OCCLUSION_PREDICATE:
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		va += query->results_end + 8;
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 2, 0);
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1);
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = va;
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = (va >> 32UL) & 0xFF;
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_PRIMITIVES_EMITTED:
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_PRIMITIVES_GENERATED:
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_SO_STATISTICS:
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 2, 0);
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_SAMPLE_STREAMOUTSTATS) | EVENT_INDEX(3);
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = query->results_end + query->result_size/2;
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = 0;
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_TIME_ELAPSED:
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		va += query->results_end + query->result_size/2;
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE_EOP, 4, 0);
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5);
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = va;
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = (3 << 29) | ((va >> 32UL) & 0xFF);
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = 0;
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = 0;
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		assert(0);
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0);
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = r600_context_bo_reloc(ctx, query->buffer, RADEON_USAGE_WRITE);
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	query->results_end = (query->results_end + query->result_size) % query->buffer->b.b.width0;
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->num_cs_dw_queries_suspend -= query->num_cs_dw;
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid r600_query_predication(struct r600_context *ctx, struct r600_query *query, int operation,
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    int flag_wait)
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_winsys_cs *cs = ctx->cs;
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint64_t va;
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (operation == PREDICATION_OP_CLEAR) {
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		si_need_cs_space(ctx, 3, FALSE);
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = PKT3(PKT3_SET_PREDICATION, 1, 0);
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = 0;
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cs->buf[cs->cdw++] = PRED_OP(PREDICATION_OP_CLEAR);
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else {
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned results_base = query->results_start;
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned count;
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		uint32_t op;
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* find count of the query data blocks */
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		count = (query->buffer->b.b.width0 + query->results_end - query->results_start) % query->buffer->b.b.width0;
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		count /= query->result_size;
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		si_need_cs_space(ctx, 5 * count, TRUE);
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		op = PRED_OP(operation) | PREDICATION_DRAW_VISIBLE |
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				(flag_wait ? PREDICATION_HINT_WAIT : PREDICATION_HINT_NOWAIT_DRAW);
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		va = r600_resource_va(&ctx->screen->screen, (void*)query->buffer);
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* emit predicate packets for all data blocks */
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		while (results_base != query->results_end) {
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			cs->buf[cs->cdw++] = PKT3(PKT3_SET_PREDICATION, 1, 0);
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			cs->buf[cs->cdw++] = (va + results_base) & 0xFFFFFFFFUL;
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			cs->buf[cs->cdw++] = op | (((va + results_base) >> 32UL) & 0xFF);
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0);
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			cs->buf[cs->cdw++] = r600_context_bo_reloc(ctx, query->buffer,
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org									     RADEON_USAGE_READ);
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			results_base = (results_base + query->result_size) % query->buffer->b.b.width0;
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			/* set CONTINUE bit for all packets except the first */
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			op |= PREDICATION_CONTINUE;
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct r600_query *r600_context_query_create(struct r600_context *ctx, unsigned query_type)
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_query *query;
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned buffer_size = 4096;
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	query = CALLOC_STRUCT(r600_query);
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (query == NULL)
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	query->type = query_type;
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (query_type) {
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_OCCLUSION_COUNTER:
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_OCCLUSION_PREDICATE:
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		query->result_size = 16 * ctx->max_db;
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		query->num_cs_dw = 6;
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_TIME_ELAPSED:
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		query->result_size = 16;
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		query->num_cs_dw = 8;
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_PRIMITIVES_EMITTED:
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_PRIMITIVES_GENERATED:
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_SO_STATISTICS:
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* NumPrimitivesWritten, PrimitiveStorageNeeded. */
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		query->result_size = 32;
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		query->num_cs_dw = 6;
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		assert(0);
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		FREE(query);
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* adjust buffer size to simplify offsets wrapping math */
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	buffer_size -= buffer_size % query->result_size;
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Queries are normally read by the CPU after
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * being written by the gpu, hence staging is probably a good
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * usage pattern.
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 */
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	query->buffer = si_resource_create_custom(&ctx->screen->screen,
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						  PIPE_USAGE_STAGING,
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						  buffer_size);
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!query->buffer) {
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		FREE(query);
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return query;
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid r600_context_query_destroy(struct r600_context *ctx, struct r600_query *query)
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	si_resource_reference(&query->buffer, NULL);
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	free(query);
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgboolean r600_context_query_result(struct r600_context *ctx,
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				struct r600_query *query,
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				boolean wait, void *vresult)
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	boolean *result_b = (boolean*)vresult;
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint64_t *result_u64 = (uint64_t*)vresult;
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_query_data_so_statistics *result_so =
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		(struct pipe_query_data_so_statistics*)vresult;
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!r600_query_result(ctx, query, wait))
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return FALSE;
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (query->type) {
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_OCCLUSION_COUNTER:
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_PRIMITIVES_EMITTED:
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_PRIMITIVES_GENERATED:
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*result_u64 = query->result.u64;
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_OCCLUSION_PREDICATE:
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*result_b = query->result.b;
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_TIME_ELAPSED:
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*result_u64 = (1000000 * query->result.u64) / ctx->screen->info.r600_clock_crystal_freq;
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_SO_STATISTICS:
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*result_so = query->result.so;
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		assert(0);
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return TRUE;
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid r600_context_queries_suspend(struct r600_context *ctx)
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_query *query;
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LIST_FOR_EACH_ENTRY(query, &ctx->active_query_list, list) {
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		r600_query_end(ctx, query);
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	assert(ctx->num_cs_dw_queries_suspend == 0);
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid r600_context_queries_resume(struct r600_context *ctx)
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_query *query;
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	assert(ctx->num_cs_dw_queries_suspend == 0);
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LIST_FOR_EACH_ENTRY(query, &ctx->active_query_list, list) {
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		r600_query_begin(ctx, query);
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid r600_context_draw_opaque_count(struct r600_context *ctx, struct r600_so_target *t)
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_winsys_cs *cs = ctx->cs;
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	si_need_cs_space(ctx, 14 + 21, TRUE);
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = PKT3(PKT3_SET_CONTEXT_REG, 1, 0);
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = (R_028B28_VGT_STRMOUT_DRAW_OPAQUE_OFFSET - SI_CONTEXT_REG_OFFSET) >> 2;
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = 0;
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = PKT3(PKT3_SET_CONTEXT_REG, 1, 0);
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = (R_028B30_VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE - SI_CONTEXT_REG_OFFSET) >> 2;
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = t->stride >> 2;
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = PKT3(PKT3_COPY_DW, 4, 0);
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = COPY_DW_SRC_IS_MEM | COPY_DW_DST_IS_REG;
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = 0; /* src address lo */
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = 0; /* src address hi */
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = R_028B2C_VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE >> 2; /* dst register */
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = 0; /* unused */
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0);
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = r600_context_bo_reloc(ctx, t->filled_size, RADEON_USAGE_READ);
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0 /* I have not found this useful yet. */
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = PKT3(PKT3_COPY_DW, 4, 0);
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = COPY_DW_SRC_IS_REG | COPY_DW_DST_IS_REG;
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = R_028B2C_VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE >> 2; /* src register */
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = 0; /* unused */
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = R_0085F4_CP_COHER_SIZE >> 2; /* dst register */
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = 0; /* unused */
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = PKT3(PKT3_SET_CONFIG_REG, 1, 0);
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = (R_0085F0_CP_COHER_CNTL - SI_CONFIG_REG_OFFSET) >> 2;
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = S_0085F0_SO0_DEST_BASE_ENA(1) << t->so_index;
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = PKT3(PKT3_SET_CONFIG_REG, 1, 0);
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = (R_0085F8_CP_COHER_BASE - SI_CONFIG_REG_OFFSET) >> 2;
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = t->b.buffer_offset >> 2;
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0);
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = r600_context_bo_reloc(ctx, (struct si_resource*)t->b.buffer,
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							     RADEON_USAGE_WRITE);
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = PKT3(PKT3_WAIT_REG_MEM, 5, 0);
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = WAIT_REG_MEM_EQUAL; /* wait until the register is equal to the reference value */
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = R_0085FC_CP_COHER_STATUS >> 2;  /* register */
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = 0;
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = 0; /* reference value */
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = 0xffffffff; /* mask */
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cs->buf[cs->cdw++] = 4; /* poll interval */
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
701