blob: cf026abf1fbf1f3e5ff50145b7dbf6a2f6a1d1ab [file] [log] [blame]
Jerome Glisse1235bec2010-09-29 15:05:19 -04001/*
2 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
Jerome Glisse1235bec2010-09-29 15:05:19 -040023#include "r600_pipe.h"
Dave Airliea44b6532011-02-28 16:19:58 +100024#include "r600d.h"
Marek Olšákdf00dc32012-02-22 00:25:55 +010025#include "util/u_memory.h"
Jerome Glisse1235bec2010-09-29 15:05:19 -040026
27static struct pipe_query *r600_create_query(struct pipe_context *ctx, unsigned query_type)
28{
Marek Olšáke4340c12012-01-29 23:25:42 +010029 struct r600_context *rctx = (struct r600_context *)ctx;
Jerome Glisse1235bec2010-09-29 15:05:19 -040030
Marek Olšáke4340c12012-01-29 23:25:42 +010031 return (struct pipe_query*)r600_context_query_create(rctx, query_type);
Jerome Glisse1235bec2010-09-29 15:05:19 -040032}
33
34static void r600_destroy_query(struct pipe_context *ctx, struct pipe_query *query)
35{
Marek Olšáke4340c12012-01-29 23:25:42 +010036 struct r600_context *rctx = (struct r600_context *)ctx;
Jerome Glisse1235bec2010-09-29 15:05:19 -040037
Marek Olšáke4340c12012-01-29 23:25:42 +010038 r600_context_query_destroy(rctx, (struct r600_query *)query);
Jerome Glisse1235bec2010-09-29 15:05:19 -040039}
40
Marek Olšáke2809842012-02-02 14:01:12 +010041static void r600_update_occlusion_query_state(struct r600_context *rctx,
42 unsigned type, int diff)
43{
44 if (type == PIPE_QUERY_OCCLUSION_COUNTER ||
45 type == PIPE_QUERY_OCCLUSION_PREDICATE) {
46 bool enable;
47
48 rctx->num_occlusion_queries += diff;
49 assert(rctx->num_occlusion_queries >= 0);
50
51 enable = rctx->num_occlusion_queries != 0;
52
53 if (rctx->atom_db_misc_state.occlusion_query_enabled != enable) {
54 rctx->atom_db_misc_state.occlusion_query_enabled = enable;
55 r600_atom_dirty(rctx, &rctx->atom_db_misc_state.atom);
56 }
57 }
58}
59
Marek Olšákdf00dc32012-02-22 00:25:55 +010060static void r600_query_discard_results(struct r600_context *rctx,
61 struct r600_query *query)
62{
63 /* Discard the old query buffers. */
64 struct r600_query_buffer *prev = query->buffer.previous;
65
66 while (prev) {
67 struct r600_query_buffer *qbuf = prev;
68 prev = prev->previous;
69 pipe_resource_reference((struct pipe_resource**)&qbuf->buf, NULL);
70 FREE(qbuf);
71 }
72
73 /* Obtain a new buffer if the current one can't be mapped without a stall. */
74 if (rctx->ws->cs_is_buffer_referenced(rctx->cs, query->buffer.buf->cs_buf) ||
75 rctx->ws->buffer_is_busy(query->buffer.buf->buf, RADEON_USAGE_READWRITE)) {
76 pipe_resource_reference((struct pipe_resource**)&query->buffer.buf, NULL);
77 query->buffer.buf = r600_new_query_buffer(rctx, query->type);
78 }
79
80 query->buffer.results_end = 0;
81 query->buffer.previous = NULL;
82}
83
Jerome Glisse1235bec2010-09-29 15:05:19 -040084static void r600_begin_query(struct pipe_context *ctx, struct pipe_query *query)
85{
Marek Olšáke4340c12012-01-29 23:25:42 +010086 struct r600_context *rctx = (struct r600_context *)ctx;
Jerome Glisse1235bec2010-09-29 15:05:19 -040087 struct r600_query *rquery = (struct r600_query *)query;
88
Marek Olšáke2809842012-02-02 14:01:12 +010089 r600_update_occlusion_query_state(rctx, rquery->type, 1);
90
Marek Olšákdf00dc32012-02-22 00:25:55 +010091 r600_query_discard_results(rctx, rquery);
92 r600_query_begin(rctx, rquery);
Marek Olšáke4340c12012-01-29 23:25:42 +010093 LIST_ADDTAIL(&rquery->list, &rctx->active_query_list);
Jerome Glisse1235bec2010-09-29 15:05:19 -040094}
95
96static void r600_end_query(struct pipe_context *ctx, struct pipe_query *query)
97{
Marek Olšáke4340c12012-01-29 23:25:42 +010098 struct r600_context *rctx = (struct r600_context *)ctx;
Marek Olšáke9b6f212011-10-28 18:27:00 +020099 struct r600_query *rquery = (struct r600_query *)query;
Jerome Glisse1235bec2010-09-29 15:05:19 -0400100
Marek Olšáke4340c12012-01-29 23:25:42 +0100101 r600_query_end(rctx, rquery);
Marek Olšáke9b6f212011-10-28 18:27:00 +0200102 LIST_DELINIT(&rquery->list);
Marek Olšáke2809842012-02-02 14:01:12 +0100103
104 r600_update_occlusion_query_state(rctx, rquery->type, -1);
Jerome Glisse1235bec2010-09-29 15:05:19 -0400105}
106
107static boolean r600_get_query_result(struct pipe_context *ctx,
108 struct pipe_query *query,
109 boolean wait, void *vresult)
110{
Marek Olšáke4340c12012-01-29 23:25:42 +0100111 struct r600_context *rctx = (struct r600_context *)ctx;
Jerome Glisse1235bec2010-09-29 15:05:19 -0400112 struct r600_query *rquery = (struct r600_query *)query;
113
Marek Olšáke4340c12012-01-29 23:25:42 +0100114 return r600_context_query_result(rctx, rquery, wait, vresult);
Jerome Glisse1235bec2010-09-29 15:05:19 -0400115}
116
Dave Airliea44b6532011-02-28 16:19:58 +1000117static void r600_render_condition(struct pipe_context *ctx,
118 struct pipe_query *query,
119 uint mode)
120{
Marek Olšáke4340c12012-01-29 23:25:42 +0100121 struct r600_context *rctx = (struct r600_context *)ctx;
Dave Airliea44b6532011-02-28 16:19:58 +1000122 struct r600_query *rquery = (struct r600_query *)query;
123 int wait_flag = 0;
124
Marek Olšák6f243ec2011-06-15 14:26:41 +0200125 rctx->current_render_cond = query;
126 rctx->current_render_cond_mode = mode;
127
Vadim Girlinef29bfe2011-07-15 07:22:20 +0400128 if (query == NULL) {
Marek Olšáke4340c12012-01-29 23:25:42 +0100129 if (rctx->predicate_drawing) {
130 rctx->predicate_drawing = false;
131 r600_query_predication(rctx, NULL, PREDICATION_OP_CLEAR, 1);
Vadim Girlinef29bfe2011-07-15 07:22:20 +0400132 }
Dave Airliea44b6532011-02-28 16:19:58 +1000133 return;
134 }
135
136 if (mode == PIPE_RENDER_COND_WAIT ||
137 mode == PIPE_RENDER_COND_BY_REGION_WAIT) {
138 wait_flag = 1;
139 }
140
Marek Olšáke4340c12012-01-29 23:25:42 +0100141 rctx->predicate_drawing = true;
Marek Olšák543b2332011-11-08 21:58:27 +0100142
143 switch (rquery->type) {
144 case PIPE_QUERY_OCCLUSION_COUNTER:
145 case PIPE_QUERY_OCCLUSION_PREDICATE:
Marek Olšáke4340c12012-01-29 23:25:42 +0100146 r600_query_predication(rctx, rquery, PREDICATION_OP_ZPASS, wait_flag);
Marek Olšák543b2332011-11-08 21:58:27 +0100147 break;
148 case PIPE_QUERY_PRIMITIVES_EMITTED:
149 case PIPE_QUERY_PRIMITIVES_GENERATED:
150 case PIPE_QUERY_SO_STATISTICS:
151 case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
Marek Olšáke4340c12012-01-29 23:25:42 +0100152 r600_query_predication(rctx, rquery, PREDICATION_OP_PRIMCOUNT, wait_flag);
Marek Olšák543b2332011-11-08 21:58:27 +0100153 break;
154 default:
155 assert(0);
156 }
Dave Airliea44b6532011-02-28 16:19:58 +1000157}
158
Marek Olšáke4340c12012-01-29 23:25:42 +0100159void r600_init_query_functions(struct r600_context *rctx)
Jerome Glisse1235bec2010-09-29 15:05:19 -0400160{
161 rctx->context.create_query = r600_create_query;
162 rctx->context.destroy_query = r600_destroy_query;
163 rctx->context.begin_query = r600_begin_query;
164 rctx->context.end_query = r600_end_query;
165 rctx->context.get_query_result = r600_get_query_result;
Dave Airliea44b6532011-02-28 16:19:58 +1000166
Marek Olšák1a532ca2011-09-11 16:35:10 +0200167 if (rctx->screen->info.r600_num_backends > 0)
Dave Airliea44b6532011-02-28 16:19:58 +1000168 rctx->context.render_condition = r600_render_condition;
Jerome Glisse1235bec2010-09-29 15:05:19 -0400169}