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 236a448a525baf81173f92ee8c3074b98baa54397bCorbin Simpson#include "util/u_memory.h" 246a448a525baf81173f92ee8c3074b98baa54397bCorbin Simpson#include "util/u_simple_list.h" 25d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson 266a448a525baf81173f92ee8c3074b98baa54397bCorbin Simpson#include "r300_context.h" 276a448a525baf81173f92ee8c3074b98baa54397bCorbin Simpson#include "r300_screen.h" 281ddb22675c123fc955ad3ab46bba45d3330d2ec4Nicolai Hähnle#include "r300_emit.h" 291ddb22675c123fc955ad3ab46bba45d3330d2ec4Nicolai Hähnle 304b8d3480764daf45cbbc03d76cd8b7c81937f532Marek Olšák#include <stdio.h> 314b8d3480764daf45cbbc03d76cd8b7c81937f532Marek Olšák 32c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airliestatic struct pipe_query *r300_create_query(struct pipe_context *pipe, 33d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson unsigned query_type) 34d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson{ 35c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie struct r300_context *r300 = r300_context(pipe); 36b71bfc4400e1d7c15a2bebbbd3b26a8770fbf546Marek Olšák struct r300_screen *r300screen = r300->screen; 37cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák struct r300_query *q; 38cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák 39014b3aa07d252d71a85234cfd2255b3b561b5c16Marek Olšák if (query_type != PIPE_QUERY_OCCLUSION_COUNTER && 40c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák query_type != PIPE_QUERY_OCCLUSION_PREDICATE && 41c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák query_type != PIPE_QUERY_GPU_FINISHED) { 42a6cc91487446f8e1e72e4f67823a359c0b3a41d6Corbin Simpson return NULL; 43a6cc91487446f8e1e72e4f67823a359c0b3a41d6Corbin Simpson } 44a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson 45a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson q = CALLOC_STRUCT(r300_query); 46cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák if (!q) 47cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák return NULL; 48d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson 49d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson q->type = query_type; 50d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson 51c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák if (query_type == PIPE_QUERY_GPU_FINISHED) { 52c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák return (struct pipe_query*)q; 53c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák } 54c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák 55b71bfc4400e1d7c15a2bebbbd3b26a8770fbf546Marek Olšák if (r300screen->caps.family == CHIP_FAMILY_RV530) 5628a336dc38c478b809544e7404c4d1fddd873333Marek Olšák q->num_pipes = r300screen->info.r300_num_z_pipes; 57c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie else 5828a336dc38c478b809544e7404c4d1fddd873333Marek Olšák q->num_pipes = r300screen->info.r300_num_gb_pipes; 59c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie 60671af44b1962a7a138185a4cfb992f6b349de10aMarek Olšák q->buf = r300->rws->buffer_create(r300->rws, 4096, 4096, 6193f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák PIPE_BIND_CUSTOM, RADEON_DOMAIN_GTT); 62c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák if (!q->buf) { 63c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák FREE(q); 64c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák return NULL; 65c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák } 666ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák q->cs_buf = r300->rws->buffer_get_cs_handle(q->buf); 67fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson 68d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson return (struct pipe_query*)q; 69d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson} 70d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson 71d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpsonstatic void r300_destroy_query(struct pipe_context* pipe, 72fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson struct pipe_query* query) 73d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson{ 74cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák struct r300_query* q = r300_query(query); 75a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson 76d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák pb_reference(&q->buf, NULL); 77fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson FREE(query); 78d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson} 79d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson 80cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšákvoid r300_resume_query(struct r300_context *r300, 81cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák struct r300_query *query) 82cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák{ 83cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák r300->query_current = query; 8466d45567b4e2c6f2585789b68667e6c00b7567e1Marek Olšák r300_mark_atom_dirty(r300, &r300->query_start); 85cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák} 86cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák 87d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpsonstatic void r300_begin_query(struct pipe_context* pipe, 88fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson struct pipe_query* query) 89d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson{ 90d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson struct r300_context* r300 = r300_context(pipe); 91cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák struct r300_query* q = r300_query(query); 92d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson 93c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák if (q->type == PIPE_QUERY_GPU_FINISHED) 94c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák return; 95c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák 9600704370e42eb9c828dc1699a033b8da9a2521b0Marek Olšák if (r300->query_current != NULL) { 9700704370e42eb9c828dc1699a033b8da9a2521b0Marek Olšák fprintf(stderr, "r300: begin_query: " 9800704370e42eb9c828dc1699a033b8da9a2521b0Marek Olšák "Some other query has already been started.\n"); 9900704370e42eb9c828dc1699a033b8da9a2521b0Marek Olšák assert(0); 10000704370e42eb9c828dc1699a033b8da9a2521b0Marek Olšák return; 10100704370e42eb9c828dc1699a033b8da9a2521b0Marek Olšák } 10247791697ab6eb6965f0ba8ba3f20373b3753ca2aDave Airlie 103cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák q->num_results = 0; 104cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák r300_resume_query(r300, q); 105cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák} 106fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson 107cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšákvoid r300_stop_query(struct r300_context *r300) 108cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák{ 109cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák r300_emit_query_end(r300); 110cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák r300->query_current = NULL; 111d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson} 112d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson 113d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpsonstatic void r300_end_query(struct pipe_context* pipe, 11451d1cf55da6f8b8a215814589a189b6e5e537fe5Dave Airlie struct pipe_query* query) 115d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson{ 116d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson struct r300_context* r300 = r300_context(pipe); 117cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák struct r300_query *q = r300_query(query); 11847791697ab6eb6965f0ba8ba3f20373b3753ca2aDave Airlie 119c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák if (q->type == PIPE_QUERY_GPU_FINISHED) { 120c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák pb_reference(&q->buf, NULL); 121c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák r300_flush(pipe, RADEON_FLUSH_ASYNC, 122c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák (struct pipe_fence_handle**)&q->buf); 123c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák return; 124c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák } 125c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák 126cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák if (q != r300->query_current) { 12700704370e42eb9c828dc1699a033b8da9a2521b0Marek Olšák fprintf(stderr, "r300: end_query: Got invalid query.\n"); 12800704370e42eb9c828dc1699a033b8da9a2521b0Marek Olšák assert(0); 12900704370e42eb9c828dc1699a033b8da9a2521b0Marek Olšák return; 13000704370e42eb9c828dc1699a033b8da9a2521b0Marek Olšák } 13100704370e42eb9c828dc1699a033b8da9a2521b0Marek Olšák 132cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák r300_stop_query(r300); 133d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson} 134d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson 135d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpsonstatic boolean r300_get_query_result(struct pipe_context* pipe, 136fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson struct pipe_query* query, 137d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson boolean wait, 1384445e170bee23a3607ece0e010adef7058ac6a11Marek Olšák union pipe_query_result *vresult) 139d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson{ 140a381ee82663f10ff3cdcfad331258d03d4188894Corbin Simpson struct r300_context* r300 = r300_context(pipe); 141cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák struct r300_query *q = r300_query(query); 14220112cca262c926de887dff7d7f108b046ea781aMarek Olšák unsigned i; 143cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák uint32_t temp, *map; 144fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson 145c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák if (q->type == PIPE_QUERY_GPU_FINISHED) { 146c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák if (wait) { 147c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák r300->rws->buffer_wait(q->buf, RADEON_USAGE_READWRITE); 1486d73382afc1d2a5e5815d0e6e7f39e0bf8138002Marek Olšák vresult->b = TRUE; 149c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák } else { 1506d73382afc1d2a5e5815d0e6e7f39e0bf8138002Marek Olšák vresult->b = !r300->rws->buffer_is_busy(q->buf, RADEON_USAGE_READWRITE); 151c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák } 1526d73382afc1d2a5e5815d0e6e7f39e0bf8138002Marek Olšák return vresult->b; 153c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák } 154c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák 1550a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák map = r300->rws->buffer_map(q->cs_buf, r300->cs, 15620112cca262c926de887dff7d7f108b046ea781aMarek Olšák PIPE_TRANSFER_READ | 15720112cca262c926de887dff7d7f108b046ea781aMarek Olšák (!wait ? PIPE_TRANSFER_DONTBLOCK : 0)); 158c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie if (!map) 159c1bee7bdea470b6b5dcebef9aacc8fe4feca687cDave Airlie return FALSE; 1605241b9568c1f97eb9aca8be5eb7a3ef659d9917fMarek Olšák 161cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák /* Sum up the results. */ 162cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák temp = 0; 163cf3778bae03460325960d2aec0cd4cdf325299ebMarek Olšák for (i = 0; i < q->num_results; i++) { 1640be1f797709528546f17f82e67b86181fa0c61e1Michel Dänzer /* Convert little endian values written by GPU to CPU byte order */ 1650be1f797709528546f17f82e67b86181fa0c61e1Michel Dänzer temp += util_le32_to_cpu(*map); 1660086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson map++; 1670086a84e2df92d48d3fb3361daaa1359d920fb31Corbin Simpson } 168fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson 1690a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák r300->rws->buffer_unmap(q->cs_buf); 170fbd758c55e6dc443f877bd87d5e6c54c86f61a33Corbin Simpson 171014b3aa07d252d71a85234cfd2255b3b561b5c16Marek Olšák if (q->type == PIPE_QUERY_OCCLUSION_PREDICATE) { 1726d73382afc1d2a5e5815d0e6e7f39e0bf8138002Marek Olšák vresult->b = temp != 0; 1736d73382afc1d2a5e5815d0e6e7f39e0bf8138002Marek Olšák } else { 1746d73382afc1d2a5e5815d0e6e7f39e0bf8138002Marek Olšák vresult->u64 = temp; 175014b3aa07d252d71a85234cfd2255b3b561b5c16Marek Olšák } 176d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson return TRUE; 177d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson} 178d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson 179655fe281556679669699052f37412a6243771619Marek Olšákstatic void r300_render_condition(struct pipe_context *pipe, 180655fe281556679669699052f37412a6243771619Marek Olšák struct pipe_query *query, 181655fe281556679669699052f37412a6243771619Marek Olšák uint mode) 182655fe281556679669699052f37412a6243771619Marek Olšák{ 183655fe281556679669699052f37412a6243771619Marek Olšák struct r300_context *r300 = r300_context(pipe); 1846d73382afc1d2a5e5815d0e6e7f39e0bf8138002Marek Olšák union pipe_query_result result; 185655fe281556679669699052f37412a6243771619Marek Olšák boolean wait; 186655fe281556679669699052f37412a6243771619Marek Olšák 187d18792f93d6dcdf7ef971522bdfba1ceeb0c6668Marek Olšák r300->skip_rendering = FALSE; 188d18792f93d6dcdf7ef971522bdfba1ceeb0c6668Marek Olšák 189655fe281556679669699052f37412a6243771619Marek Olšák if (query) { 190655fe281556679669699052f37412a6243771619Marek Olšák wait = mode == PIPE_RENDER_COND_WAIT || 191655fe281556679669699052f37412a6243771619Marek Olšák mode == PIPE_RENDER_COND_BY_REGION_WAIT; 192655fe281556679669699052f37412a6243771619Marek Olšák 1936d73382afc1d2a5e5815d0e6e7f39e0bf8138002Marek Olšák if (r300_get_query_result(pipe, query, wait, &result)) { 1946d73382afc1d2a5e5815d0e6e7f39e0bf8138002Marek Olšák if (r300_query(query)->type == PIPE_QUERY_OCCLUSION_PREDICATE) { 1956d73382afc1d2a5e5815d0e6e7f39e0bf8138002Marek Olšák r300->skip_rendering = !result.b; 1966d73382afc1d2a5e5815d0e6e7f39e0bf8138002Marek Olšák } else { 1976d73382afc1d2a5e5815d0e6e7f39e0bf8138002Marek Olšák r300->skip_rendering = !result.u64; 1986d73382afc1d2a5e5815d0e6e7f39e0bf8138002Marek Olšák } 199655fe281556679669699052f37412a6243771619Marek Olšák } 200655fe281556679669699052f37412a6243771619Marek Olšák } 201655fe281556679669699052f37412a6243771619Marek Olšák} 202655fe281556679669699052f37412a6243771619Marek Olšák 203c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšákvoid r300_init_query_functions(struct r300_context* r300) 204c5ae81652d7d153accc42002fc80f95e399410f7Marek Olšák{ 20570b86fb273ee9c3b6fea750bc14eae43328ba677Marek Olšák r300->context.create_query = r300_create_query; 20670b86fb273ee9c3b6fea750bc14eae43328ba677Marek Olšák r300->context.destroy_query = r300_destroy_query; 20770b86fb273ee9c3b6fea750bc14eae43328ba677Marek Olšák r300->context.begin_query = r300_begin_query; 20870b86fb273ee9c3b6fea750bc14eae43328ba677Marek Olšák r300->context.end_query = r300_end_query; 20970b86fb273ee9c3b6fea750bc14eae43328ba677Marek Olšák r300->context.get_query_result = r300_get_query_result; 21070b86fb273ee9c3b6fea750bc14eae43328ba677Marek Olšák r300->context.render_condition = r300_render_condition; 211d559796d6f13579ecf921a63d9f0c6c6342dc230Corbin Simpson} 212