Path: blob/21.2-virgl/src/gallium/drivers/r300/r300_query.c
4570 views
/*1* Copyright 2009 Corbin Simpson <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* on the rights to use, copy, modify, merge, publish, distribute, sub7* license, and/or sell copies of the Software, and to permit persons to whom8* the Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL17* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,18* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR19* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE20* USE OR OTHER DEALINGS IN THE SOFTWARE. */2122#include "util/u_memory.h"23#include "util/simple_list.h"2425#include "r300_context.h"26#include "r300_screen.h"27#include "r300_emit.h"2829#include <stdio.h>3031static struct pipe_query *r300_create_query(struct pipe_context *pipe,32unsigned query_type,33unsigned index)34{35struct r300_context *r300 = r300_context(pipe);36struct r300_screen *r300screen = r300->screen;37struct r300_query *q;3839if (query_type != PIPE_QUERY_OCCLUSION_COUNTER &&40query_type != PIPE_QUERY_OCCLUSION_PREDICATE &&41query_type != PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE &&42query_type != PIPE_QUERY_GPU_FINISHED) {43return NULL;44}4546q = CALLOC_STRUCT(r300_query);47if (!q)48return NULL;4950q->type = query_type;5152if (query_type == PIPE_QUERY_GPU_FINISHED) {53return (struct pipe_query*)q;54}5556if (r300screen->caps.family == CHIP_RV530)57q->num_pipes = r300screen->info.r300_num_z_pipes;58else59q->num_pipes = r300screen->info.r300_num_gb_pipes;6061q->buf = r300->rws->buffer_create(r300->rws,62r300screen->info.gart_page_size,63r300screen->info.gart_page_size,64RADEON_DOMAIN_GTT,65RADEON_FLAG_NO_INTERPROCESS_SHARING);66if (!q->buf) {67FREE(q);68return NULL;69}70return (struct pipe_query*)q;71}7273static void r300_destroy_query(struct pipe_context* pipe,74struct pipe_query* query)75{76struct r300_query* q = r300_query(query);7778pb_reference(&q->buf, NULL);79FREE(query);80}8182void r300_resume_query(struct r300_context *r300,83struct r300_query *query)84{85r300->query_current = query;86r300_mark_atom_dirty(r300, &r300->query_start);87}8889static bool r300_begin_query(struct pipe_context* pipe,90struct pipe_query* query)91{92struct r300_context* r300 = r300_context(pipe);93struct r300_query* q = r300_query(query);9495if (q->type == PIPE_QUERY_GPU_FINISHED)96return true;9798if (r300->query_current != NULL) {99fprintf(stderr, "r300: begin_query: "100"Some other query has already been started.\n");101assert(0);102return false;103}104105q->num_results = 0;106r300_resume_query(r300, q);107return true;108}109110void r300_stop_query(struct r300_context *r300)111{112r300_emit_query_end(r300);113r300->query_current = NULL;114}115116static bool r300_end_query(struct pipe_context* pipe,117struct pipe_query* query)118{119struct r300_context* r300 = r300_context(pipe);120struct r300_query *q = r300_query(query);121122if (q->type == PIPE_QUERY_GPU_FINISHED) {123pb_reference(&q->buf, NULL);124r300_flush(pipe, PIPE_FLUSH_ASYNC,125(struct pipe_fence_handle**)&q->buf);126return true;127}128129if (q != r300->query_current) {130fprintf(stderr, "r300: end_query: Got invalid query.\n");131assert(0);132return false;133}134135r300_stop_query(r300);136137return true;138}139140static bool r300_get_query_result(struct pipe_context* pipe,141struct pipe_query* query,142bool wait,143union pipe_query_result *vresult)144{145struct r300_context* r300 = r300_context(pipe);146struct r300_query *q = r300_query(query);147unsigned i;148uint32_t temp, *map;149150if (q->type == PIPE_QUERY_GPU_FINISHED) {151if (wait) {152r300->rws->buffer_wait(r300->rws, q->buf, PIPE_TIMEOUT_INFINITE,153RADEON_USAGE_READWRITE);154vresult->b = TRUE;155} else {156vresult->b = r300->rws->buffer_wait(r300->rws, q->buf, 0, RADEON_USAGE_READWRITE);157}158return vresult->b;159}160161map = r300->rws->buffer_map(r300->rws, q->buf, &r300->cs,162PIPE_MAP_READ |163(!wait ? PIPE_MAP_DONTBLOCK : 0));164if (!map)165return FALSE;166167/* Sum up the results. */168temp = 0;169for (i = 0; i < q->num_results; i++) {170/* Convert little endian values written by GPU to CPU byte order */171temp += util_le32_to_cpu(*map);172map++;173}174175if (q->type == PIPE_QUERY_OCCLUSION_PREDICATE ||176q->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) {177vresult->b = temp != 0;178} else {179vresult->u64 = temp;180}181return TRUE;182}183184static void r300_render_condition(struct pipe_context *pipe,185struct pipe_query *query,186bool condition,187enum pipe_render_cond_flag mode)188{189struct r300_context *r300 = r300_context(pipe);190union pipe_query_result result;191bool wait;192193r300->skip_rendering = FALSE;194195if (query) {196wait = mode == PIPE_RENDER_COND_WAIT ||197mode == PIPE_RENDER_COND_BY_REGION_WAIT;198199if (r300_get_query_result(pipe, query, wait, &result)) {200if (r300_query(query)->type == PIPE_QUERY_OCCLUSION_PREDICATE ||201r300_query(query)->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) {202r300->skip_rendering = condition == result.b;203} else {204r300->skip_rendering = condition == !!result.u64;205}206}207}208}209210static void211r300_set_active_query_state(struct pipe_context *pipe, bool enable)212{213}214215void r300_init_query_functions(struct r300_context* r300)216{217r300->context.create_query = r300_create_query;218r300->context.destroy_query = r300_destroy_query;219r300->context.begin_query = r300_begin_query;220r300->context.end_query = r300_end_query;221r300->context.get_query_result = r300_get_query_result;222r300->context.set_active_query_state = r300_set_active_query_state;223r300->context.render_condition = r300_render_condition;224}225226227