r300_query.c revision 51d1cf55da6f8b8a215814589a189b6e5e537fe5
1d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson/*
2d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com>
3d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson *
4d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson * Permission is hereby granted, free of charge, to any person obtaining a
5d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson * copy of this software and associated documentation files (the "Software"),
6d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson * to deal in the Software without restriction, including without limitation
7d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson * on the rights to use, copy, modify, merge, publish, distribute, sub
8d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson * license, and/or sell copies of the Software, and to permit persons to whom
9d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson * the Software is furnished to do so, subject to the following conditions:
10d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson *
11d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson * The above copyright notice and this permission notice (including the next
12d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson * paragraph) shall be included in all copies or substantial portions of the
13d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson * Software.
14d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson *
15d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson * USE OR OTHER DEALINGS IN THE SOFTWARE. */
22d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson
23d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson#include "r300_query.h"
24d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson
251ddb22675c123fc955ad3ab46bba45d3330d2ec4Nicolai Hähnle#include "r300_emit.h"
261ddb22675c123fc955ad3ab46bba45d3330d2ec4Nicolai Hähnle
27c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airliestatic struct pipe_query *r300_create_query(struct pipe_context *pipe,
28d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson                                            unsigned query_type)
29d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson{
30c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie    struct r300_context *r300 = r300_context(pipe);
31c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie    struct r300_screen *r300screen = r300_screen(r300->context.screen);
32c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie    unsigned query_size;
33c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie    struct r300_query *q, *qptr;
34a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson
35a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson    q = CALLOC_STRUCT(r300_query);
36d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson
37d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson    q->type = query_type;
38d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson    assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
39d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson
40a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson    q->active = FALSE;
41a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson
42c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie    if (r300screen->caps->family == CHIP_FAMILY_RV530)
43c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie	query_size = r300screen->caps->num_z_pipes * sizeof(uint32_t);
44c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie    else
45c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie	query_size = r300screen->caps->num_frag_pipes * sizeof(uint32_t);
46c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie
47c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie    if (!is_empty_list(&r300->query_list)) {
48c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie        qptr = last_elem(&r300->query_list);
49a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson        q->offset = qptr->offset + query_size;
50a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson    }
51c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie    insert_at_tail(&r300->query_list, q);
52a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson
53a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson    /* XXX */
54a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson    if (q->offset >= 4096) {
55a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson        q->offset = 0;
56a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson    }
57fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson
58d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson    return (struct pipe_query*)q;
59d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson}
60d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson
61d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpsonstatic void r300_destroy_query(struct pipe_context* pipe,
62fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson                               struct pipe_query* query)
63d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson{
64a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson    struct r300_query* q = (struct r300_query*)query;
65a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson
66a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson    remove_from_list(q);
67fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson    FREE(query);
68d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson}
69d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson
70d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpsonstatic void r300_begin_query(struct pipe_context* pipe,
71fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson                             struct pipe_query* query)
72d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson{
73be1dbba0a4d0d75468461aff8c281a512a537eccCorbin Simpson    uint32_t* map;
74d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson    struct r300_context* r300 = r300_context(pipe);
75fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson    struct r300_query* q = (struct r300_query*)query;
76d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson
7747791697ab6eb6965f0ba8ba3f20373b3753ca2aDave Airlie    assert(r300->query_current == NULL);
7847791697ab6eb6965f0ba8ba3f20373b3753ca2aDave Airlie
79a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson    map = pipe->screen->buffer_map(pipe->screen, r300->oqbo,
80a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson            PIPE_BUFFER_USAGE_CPU_WRITE);
81a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson    map += q->offset / 4;
82c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie    *map = ~0U;
83a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson    pipe->screen->buffer_unmap(pipe->screen, r300->oqbo);
84fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson
85c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie    q->flushed = FALSE;
8647791697ab6eb6965f0ba8ba3f20373b3753ca2aDave Airlie    r300->query_current = q;
8747791697ab6eb6965f0ba8ba3f20373b3753ca2aDave Airlie    r300->dirty_state |= R300_NEW_QUERY;
88d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson}
89d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson
90d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpsonstatic void r300_end_query(struct pipe_context* pipe,
9151d1cf55da6f8b8a215814589a189b6e5e537fe5Dave Airlie	                   struct pipe_query* query)
92d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson{
93d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson    struct r300_context* r300 = r300_context(pipe);
9447791697ab6eb6965f0ba8ba3f20373b3753ca2aDave Airlie
9551d1cf55da6f8b8a215814589a189b6e5e537fe5Dave Airlie    r300_emit_query_end(r300);
9647791697ab6eb6965f0ba8ba3f20373b3753ca2aDave Airlie    r300->query_current = NULL;
97d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson}
98d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson
99d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpsonstatic boolean r300_get_query_result(struct pipe_context* pipe,
100fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson                                     struct pipe_query* query,
101d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson                                     boolean wait,
102d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson                                     uint64_t* result)
103d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson{
104a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson    struct r300_context* r300 = r300_context(pipe);
1050086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson    struct r300_screen* r300screen = r300_screen(r300->context.screen);
106c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie    struct r300_query *q = (struct r300_query*)query;
1070086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson    unsigned flags = PIPE_BUFFER_USAGE_CPU_READ;
108be1dbba0a4d0d75468461aff8c281a512a537eccCorbin Simpson    uint32_t* map;
109c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie    uint32_t temp = 0;
1100086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson    unsigned i;
111fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson
112c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie    if (q->flushed == FALSE)
113fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson        pipe->flush(pipe, 0, NULL);
114c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie    if (!wait) {
1150086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson        flags |= PIPE_BUFFER_USAGE_DONTBLOCK;
116fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson    }
117fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson
1180086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson    map = pipe->screen->buffer_map(pipe->screen, r300->oqbo, flags);
119c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie    if (!map)
120c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie        return FALSE;
121a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson    map += q->offset / 4;
1220086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson    for (i = 0; i < r300screen->caps->num_frag_pipes; i++) {
123c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie        if (*map == ~0U) {
1240086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson            /* Looks like our results aren't ready yet. */
1250086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson            if (wait) {
1260086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson                debug_printf("r300: Despite waiting, OQ results haven't"
1270086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson                        " come in yet.\n");
1280086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson            }
129c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie            temp = ~0U;
1300086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson            break;
1310086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson        }
1320086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson        temp += *map;
1330086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson        map++;
1340086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson    }
135a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson    pipe->screen->buffer_unmap(pipe->screen, r300->oqbo);
136fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson
137c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie    if (temp == ~0U) {
138fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson        /* Our results haven't been written yet... */
139fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson        return FALSE;
140fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson    }
141fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson
142fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson    *result = temp;
143d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson    return TRUE;
144d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson}
145d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson
146d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpsonvoid r300_init_query_functions(struct r300_context* r300) {
147d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson    r300->context.create_query = r300_create_query;
148d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson    r300->context.destroy_query = r300_destroy_query;
149d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson    r300->context.begin_query = r300_begin_query;
150d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson    r300->context.end_query = r300_end_query;
151d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson    r300->context.get_query_result = r300_get_query_result;
152d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson}
153