2
2
* Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
3
3
* Copyright 2014 Marek Olšák <marek.olsak@amd.com>
4
4
* Copyright 2018 Advanced Micro Devices, Inc.
7
* Permission is hereby granted, free of charge, to any person obtaining a
8
* copy of this software and associated documentation files (the "Software"),
9
* to deal in the Software without restriction, including without limitation
10
* on the rights to use, copy, modify, merge, publish, distribute, sub
11
* license, and/or sell copies of the Software, and to permit persons to whom
12
* the Software is furnished to do so, subject to the following conditions:
14
* The above copyright notice and this permission notice (including the next
15
* paragraph) shall be included in all copies or substantial portions of the
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24
* USE OR OTHER DEALINGS IN THE SOFTWARE.
6
* SPDX-License-Identifier: MIT
27
9
#include "si_query.h"
35
17
#include "util/u_upload_mgr.h"
37
19
static const struct si_query_ops query_hw_ops;
20
static const struct si_query_hw_ops query_hw_default_hw_ops;
21
static const struct si_query_ops sw_query_ops;
39
23
struct si_hw_query_params {
40
24
unsigned start_offset;
448
432
struct pipe_screen *screen = sctx->b.screen;
449
433
struct pipe_context *ctx = squery->b.flushed ? NULL : &sctx->b;
451
result->b = screen->fence_finish(screen, ctx, query->fence, wait ? PIPE_TIMEOUT_INFINITE : 0);
435
result->b = screen->fence_finish(screen, ctx, query->fence, wait ? OS_TIMEOUT_INFINITE : 0);
452
436
return result->b;
497
static const struct si_query_ops sw_query_ops = {.destroy = si_query_sw_destroy,
498
.begin = si_query_sw_begin,
499
.end = si_query_sw_end,
500
.get_result = si_query_sw_get_result,
501
.get_result_resource = NULL};
503
481
static struct pipe_query *si_query_sw_create(unsigned query_type)
505
483
struct si_query_sw *query;
594
void si_query_hw_destroy(struct si_context *sctx, struct si_query *squery)
572
static void si_query_hw_destroy(struct si_context *sctx, struct si_query *squery)
596
574
struct si_query_hw *query = (struct si_query_hw *)squery;
671
649
return si_query_pipestats_num_results(sscreen) * 2 + si_query_pipestat_dw_offset(index);
674
static void si_query_hw_get_result_resource(struct si_context *sctx, struct si_query *squery,
675
enum pipe_query_flags flags,
676
enum pipe_query_value_type result_type,
677
int index, struct pipe_resource *resource,
680
static void si_query_hw_do_emit_start(struct si_context *sctx, struct si_query_hw *query,
681
struct si_resource *buffer, uint64_t va);
682
static void si_query_hw_do_emit_stop(struct si_context *sctx, struct si_query_hw *query,
683
struct si_resource *buffer, uint64_t va);
684
static void si_query_hw_add_result(struct si_screen *sscreen, struct si_query_hw *, void *buffer,
685
union pipe_query_result *result);
686
static void si_query_hw_clear_result(struct si_query_hw *, union pipe_query_result *);
688
static struct si_query_hw_ops query_hw_default_hw_ops = {
689
.prepare_buffer = si_query_hw_prepare_buffer,
690
.emit_start = si_query_hw_do_emit_start,
691
.emit_stop = si_query_hw_do_emit_stop,
692
.clear_result = si_query_hw_clear_result,
693
.add_result = si_query_hw_add_result,
696
652
static struct pipe_query *si_query_hw_create(struct si_screen *sscreen, unsigned query_type,
890
846
RADEON_USAGE_WRITE | RADEON_PRIO_QUERY);
849
static void si_update_hw_pipeline_stats(struct si_context *sctx, unsigned type, int diff)
851
if (type == PIPE_QUERY_PIPELINE_STATISTICS ||
852
/* All streamout queries: */
853
type == PIPE_QUERY_PRIMITIVES_GENERATED ||
854
type == PIPE_QUERY_PRIMITIVES_EMITTED ||
855
type == PIPE_QUERY_SO_STATISTICS ||
856
type == PIPE_QUERY_SO_OVERFLOW_PREDICATE ||
857
type == PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE) {
858
if (type == PIPE_QUERY_PIPELINE_STATISTICS)
859
sctx->num_pipeline_stat_queries += diff;
861
/* Increment for pipeline statistics and streamout queries. */
862
sctx->num_hw_pipestat_streamout_queries += diff;
864
/* Enable/disable pipeline stats if we have any queries. */
865
if (diff == 1 && sctx->num_hw_pipestat_streamout_queries == 1) {
866
sctx->flags &= ~SI_CONTEXT_STOP_PIPELINE_STATS;
867
sctx->flags |= SI_CONTEXT_START_PIPELINE_STATS;
868
} else if (diff == -1 && sctx->num_hw_pipestat_streamout_queries == 0) {
869
sctx->flags &= ~SI_CONTEXT_START_PIPELINE_STATS;
870
sctx->flags |= SI_CONTEXT_STOP_PIPELINE_STATS;
893
875
static void si_query_hw_emit_start(struct si_context *sctx, struct si_query_hw *query)
908
890
si_update_occlusion_query_state(sctx, query->b.type, 1);
909
891
si_update_prims_generated_query_state(sctx, query->b.type, 1);
911
if (query->b.type == PIPE_QUERY_PIPELINE_STATISTICS)
912
sctx->num_pipeline_stat_queries++;
892
si_update_hw_pipeline_stats(sctx, query->b.type, 1);
914
894
si_need_gfx_cs_space(sctx, 0);
1029
1009
si_update_occlusion_query_state(sctx, query->b.type, -1);
1030
1010
si_update_prims_generated_query_state(sctx, query->b.type, -1);
1032
if (query->b.type == PIPE_QUERY_PIPELINE_STATISTICS)
1033
sctx->num_pipeline_stat_queries--;
1011
si_update_hw_pipeline_stats(sctx, query->b.type, -1);
1036
1014
static void emit_set_predicate(struct si_context *ctx, struct si_resource *buf, uint64_t va,
1068
1046
flag_wait = ctx->render_cond_mode == PIPE_RENDER_COND_WAIT ||
1069
1047
ctx->render_cond_mode == PIPE_RENDER_COND_BY_REGION_WAIT;
1071
if (ctx->screen->use_ngg_streamout && (query->b.type == PIPE_QUERY_SO_OVERFLOW_PREDICATE ||
1072
query->b.type == PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE)) {
1073
struct gfx10_sh_query *gfx10_query = (struct gfx10_sh_query *)query;
1074
struct gfx10_sh_query_buffer *qbuf, *first, *last;
1049
if (ctx->gfx_level >= GFX11 && (query->b.type == PIPE_QUERY_SO_OVERFLOW_PREDICATE ||
1050
query->b.type == PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE)) {
1051
struct gfx11_sh_query *gfx10_query = (struct gfx11_sh_query *)query;
1052
struct gfx11_sh_query_buffer *qbuf, *first, *last;
1076
1054
op = PRED_OP(PREDICATION_OP_PRIMCOUNT);
1100
1078
unsigned begin = qbuf == gfx10_query->first ? gfx10_query->first_begin : 0;
1101
1079
unsigned end = qbuf == gfx10_query->last ? gfx10_query->last_end : qbuf->buf->b.b.width0;
1103
unsigned count = (end - begin) / sizeof(struct gfx10_sh_query_buffer_mem);
1081
unsigned count = (end - begin) / sizeof(struct gfx11_sh_query_buffer_mem);
1105
1083
if (gfx10_query->b.type == PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE) {
1106
1084
for (unsigned stream = 0; stream < SI_MAX_STREAMS; ++stream) {
1196
1174
(query_type >= PIPE_QUERY_DRIVER_SPECIFIC))
1197
1175
return si_query_sw_create(query_type);
1199
if (sscreen->use_ngg_streamout &&
1177
if (sscreen->info.gfx_level >= GFX11 &&
1200
1178
(query_type == PIPE_QUERY_PRIMITIVES_EMITTED ||
1201
1179
query_type == PIPE_QUERY_PRIMITIVES_GENERATED || query_type == PIPE_QUERY_SO_STATISTICS ||
1202
1180
query_type == PIPE_QUERY_SO_OVERFLOW_PREDICATE ||
1203
1181
query_type == PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE))
1204
return gfx10_sh_query_create(sscreen, query_type, index);
1182
return gfx11_sh_query_create(sscreen, query_type, index);
1206
1184
return si_query_hw_create(sscreen, query_type, index);
1222
1200
return squery->ops->begin(sctx, squery);
1225
bool si_query_hw_begin(struct si_context *sctx, struct si_query *squery)
1203
static bool si_query_hw_begin(struct si_context *sctx, struct si_query *squery)
1227
1205
struct si_query_hw *query = (struct si_query_hw *)squery;
1253
1231
return squery->ops->end(sctx, squery);
1256
bool si_query_hw_end(struct si_context *sctx, struct si_query *squery)
1234
static bool si_query_hw_end(struct si_context *sctx, struct si_query *squery)
1258
1236
struct si_query_hw *query = (struct si_query_hw *)squery;
1442
void si_query_hw_suspend(struct si_context *sctx, struct si_query *query)
1420
static void si_query_hw_suspend(struct si_context *sctx, struct si_query *query)
1444
1422
si_query_hw_emit_stop(sctx, (struct si_query_hw *)query);
1447
void si_query_hw_resume(struct si_context *sctx, struct si_query *query)
1425
static void si_query_hw_resume(struct si_context *sctx, struct si_query *query)
1449
1427
si_query_hw_emit_start(sctx, (struct si_query_hw *)query);
1452
static const struct si_query_ops query_hw_ops = {
1453
.destroy = si_query_hw_destroy,
1454
.begin = si_query_hw_begin,
1455
.end = si_query_hw_end,
1456
.get_result = si_query_hw_get_result,
1457
.get_result_resource = si_query_hw_get_result_resource,
1459
.suspend = si_query_hw_suspend,
1460
.resume = si_query_hw_resume,
1463
1430
static bool si_get_query_result(struct pipe_context *ctx, struct pipe_query *query, bool wait,
1464
1431
union pipe_query_result *result)
1484
1451
util_query_clear_result(result, query->b.type);
1487
bool si_query_hw_get_result(struct si_context *sctx, struct si_query *squery, bool wait,
1488
union pipe_query_result *result)
1454
static bool si_query_hw_get_result(struct si_context *sctx, struct si_query *squery, bool wait,
1455
union pipe_query_result *result)
1490
1457
struct si_screen *sscreen = sctx->screen;
1491
1458
struct si_query_hw *query = (struct si_query_hw *)squery;
1903
static const struct si_query_ops query_hw_ops = {
1904
.destroy = si_query_hw_destroy,
1905
.begin = si_query_hw_begin,
1906
.end = si_query_hw_end,
1907
.get_result = si_query_hw_get_result,
1908
.get_result_resource = si_query_hw_get_result_resource,
1910
.suspend = si_query_hw_suspend,
1911
.resume = si_query_hw_resume,
1914
static const struct si_query_ops sw_query_ops = {
1915
.destroy = si_query_sw_destroy,
1916
.begin = si_query_sw_begin,
1917
.end = si_query_sw_end,
1918
.get_result = si_query_sw_get_result,
1919
.get_result_resource = NULL
1922
static const struct si_query_hw_ops query_hw_default_hw_ops = {
1923
.prepare_buffer = si_query_hw_prepare_buffer,
1924
.emit_start = si_query_hw_do_emit_start,
1925
.emit_stop = si_query_hw_do_emit_stop,
1926
.clear_result = si_query_hw_clear_result,
1927
.add_result = si_query_hw_add_result,
1936
1930
void si_init_query_functions(struct si_context *sctx)
1938
1932
sctx->b.create_query = si_create_query;