Path: blob/21.2-virgl/src/gallium/drivers/nouveau/nv50/nv50_query.c
4574 views
/*1* Copyright 2011 Nouveau Project2*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 shall be included in11* all copies or substantial portions of the Software.12*13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL16* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR17* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,18* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR19* OTHER DEALINGS IN THE SOFTWARE.20*21* Authors: Christoph Bumiller22*/2324#define NV50_PUSH_EXPLICIT_SPACE_CHECKING2526#include "nv50/nv50_context.h"27#include "nv50/nv50_query.h"28#include "nv50/nv50_query_hw.h"29#include "nv50/nv50_query_hw_metric.h"30#include "nv50/nv50_query_hw_sm.h"3132static struct pipe_query *33nv50_create_query(struct pipe_context *pipe, unsigned type, unsigned index)34{35struct nv50_context *nv50 = nv50_context(pipe);36struct nv50_query *q;3738q = nv50_hw_create_query(nv50, type, index);39return (struct pipe_query *)q;40}4142static void43nv50_destroy_query(struct pipe_context *pipe, struct pipe_query *pq)44{45struct nv50_query *q = nv50_query(pq);46q->funcs->destroy_query(nv50_context(pipe), q);47}4849static bool50nv50_begin_query(struct pipe_context *pipe, struct pipe_query *pq)51{52struct nv50_query *q = nv50_query(pq);53return q->funcs->begin_query(nv50_context(pipe), q);54}5556static bool57nv50_end_query(struct pipe_context *pipe, struct pipe_query *pq)58{59struct nv50_query *q = nv50_query(pq);60q->funcs->end_query(nv50_context(pipe), q);61return true;62}6364static bool65nv50_get_query_result(struct pipe_context *pipe, struct pipe_query *pq,66bool wait, union pipe_query_result *result)67{68struct nv50_query *q = nv50_query(pq);69return q->funcs->get_query_result(nv50_context(pipe), q, wait, result);70}7172static void73nv50_render_condition(struct pipe_context *pipe,74struct pipe_query *pq,75bool condition, enum pipe_render_cond_flag mode)76{77struct nv50_context *nv50 = nv50_context(pipe);78struct nouveau_pushbuf *push = nv50->base.pushbuf;79struct nv50_query *q = nv50_query(pq);80struct nv50_hw_query *hq = nv50_hw_query(q);81uint32_t cond;82bool wait =83mode != PIPE_RENDER_COND_NO_WAIT &&84mode != PIPE_RENDER_COND_BY_REGION_NO_WAIT;8586if (!pq) {87cond = NV50_3D_COND_MODE_ALWAYS;88}89else {90/* NOTE: comparison of 2 queries only works if both have completed */91switch (q->type) {92case PIPE_QUERY_SO_OVERFLOW_PREDICATE:93cond = condition ? NV50_3D_COND_MODE_EQUAL :94NV50_3D_COND_MODE_NOT_EQUAL;95wait = true;96break;97case PIPE_QUERY_OCCLUSION_COUNTER:98case PIPE_QUERY_OCCLUSION_PREDICATE:99case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:100if (hq->state == NV50_HW_QUERY_STATE_READY)101wait = true;102if (likely(!condition)) {103cond = wait ? NV50_3D_COND_MODE_NOT_EQUAL : NV50_3D_COND_MODE_ALWAYS;104} else {105cond = wait ? NV50_3D_COND_MODE_EQUAL : NV50_3D_COND_MODE_ALWAYS;106}107break;108default:109assert(!"render condition query not a predicate");110cond = NV50_3D_COND_MODE_ALWAYS;111break;112}113}114115nv50->cond_query = pq;116nv50->cond_cond = condition;117nv50->cond_condmode = cond;118nv50->cond_mode = mode;119120if (!pq) {121PUSH_SPACE(push, 2);122BEGIN_NV04(push, NV50_3D(COND_MODE), 1);123PUSH_DATA (push, cond);124return;125}126127PUSH_SPACE(push, 9);128129if (wait && hq->state != NV50_HW_QUERY_STATE_READY) {130BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);131PUSH_DATA (push, 0);132}133134PUSH_REFN (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);135BEGIN_NV04(push, NV50_3D(COND_ADDRESS_HIGH), 3);136PUSH_DATAh(push, hq->bo->offset + hq->offset);137PUSH_DATA (push, hq->bo->offset + hq->offset);138PUSH_DATA (push, cond);139140BEGIN_NV04(push, NV50_2D(COND_ADDRESS_HIGH), 2);141PUSH_DATAh(push, hq->bo->offset + hq->offset);142PUSH_DATA (push, hq->bo->offset + hq->offset);143}144145static void146nv50_set_active_query_state(struct pipe_context *pipe, bool enable)147{148}149150void151nv50_init_query_functions(struct nv50_context *nv50)152{153struct pipe_context *pipe = &nv50->base.pipe;154155pipe->create_query = nv50_create_query;156pipe->destroy_query = nv50_destroy_query;157pipe->begin_query = nv50_begin_query;158pipe->end_query = nv50_end_query;159pipe->get_query_result = nv50_get_query_result;160pipe->set_active_query_state = nv50_set_active_query_state;161pipe->render_condition = nv50_render_condition;162nv50->cond_condmode = NV50_3D_COND_MODE_ALWAYS;163}164165int166nv50_screen_get_driver_query_info(struct pipe_screen *pscreen,167unsigned id,168struct pipe_driver_query_info *info)169{170struct nv50_screen *screen = nv50_screen(pscreen);171int num_hw_queries = 0;172173num_hw_queries = nv50_hw_get_driver_query_info(screen, 0, NULL);174175if (!info)176return num_hw_queries;177178/* Init default values. */179info->name = "this_is_not_the_query_you_are_looking_for";180info->query_type = 0xdeadd01d;181info->max_value.u64 = 0;182info->type = PIPE_DRIVER_QUERY_TYPE_UINT64;183info->group_id = -1;184info->flags = 0;185186return nv50_hw_get_driver_query_info(screen, id, info);187}188189int190nv50_screen_get_driver_query_group_info(struct pipe_screen *pscreen,191unsigned id,192struct pipe_driver_query_group_info *info)193{194struct nv50_screen *screen = nv50_screen(pscreen);195int count = 0;196197if (screen->compute)198if (screen->base.class_3d >= NV84_3D_CLASS)199count += 2;200201if (!info)202return count;203204if (id == NV50_HW_SM_QUERY_GROUP) {205if (screen->compute) {206if (screen->base.class_3d >= NV84_3D_CLASS) {207info->name = "MP counters";208209/* Expose the maximum number of hardware counters available,210* although some queries use more than one counter. Expect failures211* in that case but as performance counters are for developers,212* this should not have a real impact. */213info->max_active_queries = 4;214info->num_queries = NV50_HW_SM_QUERY_COUNT;215return 1;216}217}218} else219if (id == NV50_HW_METRIC_QUERY_GROUP) {220if (screen->compute) {221if (screen->base.class_3d >= NV84_3D_CLASS) {222info->name = "Performance metrics";223info->max_active_queries = 2; /* A metric uses at least 2 queries */224info->num_queries = NV50_HW_METRIC_QUERY_COUNT;225return 1;226}227}228}229230/* user asked for info about non-existing query group */231info->name = "this_is_not_the_query_group_you_are_looking_for";232info->max_active_queries = 0;233info->num_queries = 0;234return 0;235}236237238