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