Path: blob/21.2-virgl/src/gallium/drivers/swr/swr_query.cpp
4570 views
/****************************************************************************1* Copyright (C) 2015 Intel Corporation. All Rights Reserved.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* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* 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 NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21***************************************************************************/2223#include "pipe/p_defines.h"24#include "util/u_memory.h"25#include "util/os_time.h"26#include "swr_context.h"27#include "swr_fence.h"28#include "swr_query.h"29#include "swr_screen.h"30#include "swr_state.h"31#include "common/os.h"3233static struct swr_query *34swr_query(struct pipe_query *p)35{36return (struct swr_query *)p;37}3839static struct pipe_query *40swr_create_query(struct pipe_context *pipe, unsigned type, unsigned index)41{42struct swr_query *pq;4344assert(type < PIPE_QUERY_TYPES);45assert(index < MAX_SO_STREAMS);4647pq = (struct swr_query *) AlignedMalloc(sizeof(struct swr_query), 64);4849if (pq) {50memset(pq, 0, sizeof(*pq));51pq->type = type;52pq->index = index;53}5455return (struct pipe_query *)pq;56}575859static void60swr_destroy_query(struct pipe_context *pipe, struct pipe_query *q)61{62struct swr_query *pq = swr_query(q);6364if (pq->fence) {65if (swr_is_fence_pending(pq->fence))66swr_fence_finish(pipe->screen, NULL, pq->fence, 0);67swr_fence_reference(pipe->screen, &pq->fence, NULL);68}6970AlignedFree(pq);71}727374static bool75swr_get_query_result(struct pipe_context *pipe,76struct pipe_query *q,77bool wait,78union pipe_query_result *result)79{80struct swr_query *pq = swr_query(q);81unsigned index = pq->index;8283if (pq->fence) {84if (!wait && !swr_is_fence_done(pq->fence))85return false;8687swr_fence_finish(pipe->screen, NULL, pq->fence, 0);88swr_fence_reference(pipe->screen, &pq->fence, NULL);89}9091/* All values are reset to 0 at swr_begin_query, except starting timestamp.92* Counters become simply end values. */93switch (pq->type) {94/* Booleans */95case PIPE_QUERY_OCCLUSION_PREDICATE:96case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:97result->b = pq->result.core.DepthPassCount != 0;98break;99case PIPE_QUERY_GPU_FINISHED:100result->b = true;101break;102/* Counters */103case PIPE_QUERY_OCCLUSION_COUNTER:104result->u64 = pq->result.core.DepthPassCount;105break;106case PIPE_QUERY_TIMESTAMP:107case PIPE_QUERY_TIME_ELAPSED:108result->u64 = pq->result.timestamp_end - pq->result.timestamp_start;109break;110case PIPE_QUERY_PRIMITIVES_GENERATED:111result->u64 = pq->result.coreFE.IaPrimitives;112break;113case PIPE_QUERY_PRIMITIVES_EMITTED:114result->u64 = pq->result.coreFE.SoNumPrimsWritten[index];115break;116/* Structures */117case PIPE_QUERY_SO_STATISTICS: {118struct pipe_query_data_so_statistics *so_stats = &result->so_statistics;119so_stats->num_primitives_written =120pq->result.coreFE.SoNumPrimsWritten[index];121so_stats->primitives_storage_needed =122pq->result.coreFE.SoPrimStorageNeeded[index];123} break;124case PIPE_QUERY_TIMESTAMP_DISJOINT:125/* os_get_time_nano returns nanoseconds */126result->timestamp_disjoint.frequency = UINT64_C(1000000000);127result->timestamp_disjoint.disjoint = FALSE;128break;129case PIPE_QUERY_PIPELINE_STATISTICS: {130struct pipe_query_data_pipeline_statistics *p_stats =131&result->pipeline_statistics;132p_stats->ia_vertices = pq->result.coreFE.IaVertices;133p_stats->ia_primitives = pq->result.coreFE.IaPrimitives;134p_stats->vs_invocations = pq->result.coreFE.VsInvocations;135p_stats->gs_invocations = pq->result.coreFE.GsInvocations;136p_stats->gs_primitives = pq->result.coreFE.GsPrimitives;137p_stats->c_invocations = pq->result.coreFE.CPrimitives;138p_stats->c_primitives = pq->result.coreFE.CPrimitives;139p_stats->ps_invocations = pq->result.core.PsInvocations;140p_stats->hs_invocations = pq->result.coreFE.HsInvocations;141p_stats->ds_invocations = pq->result.coreFE.DsInvocations;142p_stats->cs_invocations = pq->result.core.CsInvocations;143} break;144case PIPE_QUERY_SO_OVERFLOW_PREDICATE: {145uint64_t num_primitives_written =146pq->result.coreFE.SoNumPrimsWritten[index];147uint64_t primitives_storage_needed =148pq->result.coreFE.SoPrimStorageNeeded[index];149result->b = num_primitives_written > primitives_storage_needed;150}151break;152default:153assert(0 && "Unsupported query");154break;155}156157return true;158}159160static bool161swr_begin_query(struct pipe_context *pipe, struct pipe_query *q)162{163struct swr_context *ctx = swr_context(pipe);164struct swr_query *pq = swr_query(q);165166/* Initialize Results */167memset(&pq->result, 0, sizeof(pq->result));168switch (pq->type) {169case PIPE_QUERY_GPU_FINISHED:170case PIPE_QUERY_TIMESTAMP:171/* nothing to do, but don't want the default */172break;173case PIPE_QUERY_TIME_ELAPSED:174pq->result.timestamp_start = swr_get_timestamp(pipe->screen);175break;176default:177/* Core counters required. Update draw context with location to178* store results. */179swr_update_draw_context(ctx, &pq->result);180181/* Only change stat collection if there are no active queries */182if (ctx->active_queries == 0) {183ctx->api.pfnSwrEnableStatsFE(ctx->swrContext, TRUE);184ctx->api.pfnSwrEnableStatsBE(ctx->swrContext, TRUE);185}186ctx->active_queries++;187break;188}189190191return true;192}193194static bool195swr_end_query(struct pipe_context *pipe, struct pipe_query *q)196{197struct swr_context *ctx = swr_context(pipe);198struct swr_query *pq = swr_query(q);199200switch (pq->type) {201case PIPE_QUERY_GPU_FINISHED:202/* nothing to do, but don't want the default */203break;204case PIPE_QUERY_TIMESTAMP:205case PIPE_QUERY_TIME_ELAPSED:206pq->result.timestamp_end = swr_get_timestamp(pipe->screen);207break;208default:209/* Stats are updated asynchronously, a fence is used to signal210* completion. */211if (!pq->fence) {212struct swr_screen *screen = swr_screen(pipe->screen);213swr_fence_reference(pipe->screen, &pq->fence, screen->flush_fence);214}215swr_fence_submit(ctx, pq->fence);216217/* Only change stat collection if there are no active queries */218ctx->active_queries--;219if (ctx->active_queries == 0) {220ctx->api.pfnSwrEnableStatsFE(ctx->swrContext, FALSE);221ctx->api.pfnSwrEnableStatsBE(ctx->swrContext, FALSE);222}223224break;225}226227return true;228}229230231bool232swr_check_render_cond(struct pipe_context *pipe)233{234struct swr_context *ctx = swr_context(pipe);235bool b, wait;236uint64_t result;237238if (!ctx->render_cond_query)239return true; /* no query predicate, draw normally */240241wait = (ctx->render_cond_mode == PIPE_RENDER_COND_WAIT242|| ctx->render_cond_mode == PIPE_RENDER_COND_BY_REGION_WAIT);243244b = pipe->get_query_result(245pipe, ctx->render_cond_query, wait, (union pipe_query_result *)&result);246if (b)247return ((!result) == ctx->render_cond_cond);248else249return true;250}251252253static void254swr_set_active_query_state(struct pipe_context *pipe, bool enable)255{256}257258void259swr_query_init(struct pipe_context *pipe)260{261struct swr_context *ctx = swr_context(pipe);262263pipe->create_query = swr_create_query;264pipe->destroy_query = swr_destroy_query;265pipe->begin_query = swr_begin_query;266pipe->end_query = swr_end_query;267pipe->get_query_result = swr_get_query_result;268pipe->set_active_query_state = swr_set_active_query_state;269270ctx->active_queries = 0;271}272273274