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#include "radeonsi_pipe.h"
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "sid.h"
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pipe_query *r600_create_query(struct pipe_context *ctx, unsigned query_type)
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_context *rctx = (struct r600_context *)ctx;
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return (struct pipe_query*)r600_context_query_create(rctx, query_type);
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void r600_destroy_query(struct pipe_context *ctx, struct pipe_query *query)
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_context *rctx = (struct r600_context *)ctx;
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600_context_query_destroy(rctx, (struct r600_query *)query);
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void r600_begin_query(struct pipe_context *ctx, struct pipe_query *query)
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_context *rctx = (struct r600_context *)ctx;
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_query *rquery = (struct r600_query *)query;
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	memset(&rquery->result, 0, sizeof(rquery->result));
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rquery->results_start = rquery->results_end;
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600_query_begin(rctx, (struct r600_query *)query);
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LIST_ADDTAIL(&rquery->list, &rctx->active_query_list);
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void r600_end_query(struct pipe_context *ctx, struct pipe_query *query)
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_context *rctx = (struct r600_context *)ctx;
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_query *rquery = (struct r600_query *)query;
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600_query_end(rctx, rquery);
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LIST_DELINIT(&rquery->list);
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean r600_get_query_result(struct pipe_context *ctx,
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					struct pipe_query *query,
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					boolean wait, union pipe_query_result *vresult)
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_context *rctx = (struct r600_context *)ctx;
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_query *rquery = (struct r600_query *)query;
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return r600_context_query_result(rctx, rquery, wait, vresult);
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void r600_render_condition(struct pipe_context *ctx,
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  struct pipe_query *query,
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  uint mode)
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_context *rctx = (struct r600_context *)ctx;
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_query *rquery = (struct r600_query *)query;
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int wait_flag = 0;
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* If we already have nonzero result, render unconditionally */
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (query != NULL && rquery->result.u64 != 0) {
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (rctx->current_render_cond) {
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			r600_render_condition(ctx, NULL, 0);
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return;
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rctx->current_render_cond = query;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rctx->current_render_cond_mode = mode;
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (query == NULL) {
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (rctx->predicate_drawing) {
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			rctx->predicate_drawing = false;
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			r600_query_predication(rctx, NULL, PREDICATION_OP_CLEAR, 1);
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return;
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (mode == PIPE_RENDER_COND_WAIT ||
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    mode == PIPE_RENDER_COND_BY_REGION_WAIT) {
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		wait_flag = 1;
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rctx->predicate_drawing = true;
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (rquery->type) {
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_OCCLUSION_COUNTER:
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_OCCLUSION_PREDICATE:
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		r600_query_predication(rctx, rquery, PREDICATION_OP_ZPASS, wait_flag);
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_PRIMITIVES_EMITTED:
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_PRIMITIVES_GENERATED:
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_SO_STATISTICS:
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		r600_query_predication(rctx, rquery, PREDICATION_OP_PRIMCOUNT, wait_flag);
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		assert(0);
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid r600_init_query_functions(struct r600_context *rctx)
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rctx->context.create_query = r600_create_query;
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rctx->context.destroy_query = r600_destroy_query;
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rctx->context.begin_query = r600_begin_query;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rctx->context.end_query = r600_end_query;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rctx->context.get_query_result = r600_get_query_result;
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rctx->screen->info.r600_num_backends > 0)
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    rctx->context.render_condition = r600_render_condition;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
131