~mmach/netext73/mesa-ryzen

« back to all changes in this revision

Viewing changes to src/gallium/drivers/radeonsi/si_query.c

  • Committer: mmach
  • Date: 2023-11-02 21:31:35 UTC
  • Revision ID: netbit73@gmail.com-20231102213135-18d4tzh7tj0uz752
2023-11-02 22:11:57

Show diffs side-by-side

added added

removed removed

Lines of Context:
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.
5
 
 * All Rights Reserved.
6
 
 *
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:
13
 
 *
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
16
 
 * Software.
17
 
 *
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.
 
5
 *
 
6
 * SPDX-License-Identifier: MIT
25
7
 */
26
8
 
27
9
#include "si_query.h"
35
17
#include "util/u_upload_mgr.h"
36
18
 
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;
38
22
 
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;
450
434
 
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;
453
437
   }
454
438
 
494
478
   return true;
495
479
}
496
480
 
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};
502
 
 
503
481
static struct pipe_query *si_query_sw_create(unsigned query_type)
504
482
{
505
483
   struct si_query_sw *query;
591
569
   return true;
592
570
}
593
571
 
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)
595
573
{
596
574
   struct si_query_hw *query = (struct si_query_hw *)squery;
597
575
 
671
649
   return si_query_pipestats_num_results(sscreen) * 2 + si_query_pipestat_dw_offset(index);
672
650
}
673
651
 
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,
678
 
                                            unsigned offset);
679
 
 
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 *);
687
 
 
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,
694
 
};
695
 
 
696
652
static struct pipe_query *si_query_hw_create(struct si_screen *sscreen, unsigned query_type,
697
653
                                             unsigned index)
698
654
{
890
846
                             RADEON_USAGE_WRITE | RADEON_PRIO_QUERY);
891
847
}
892
848
 
 
849
static void si_update_hw_pipeline_stats(struct si_context *sctx, unsigned type, int diff)
 
850
{
 
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;
 
860
 
 
861
      /* Increment for pipeline statistics and streamout queries. */
 
862
      sctx->num_hw_pipestat_streamout_queries += diff;
 
863
 
 
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;
 
871
      }
 
872
   }
 
873
}
 
874
 
893
875
static void si_query_hw_emit_start(struct si_context *sctx, struct si_query_hw *query)
894
876
{
895
877
   uint64_t va;
907
889
 
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);
910
 
 
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);
913
893
 
914
894
   si_need_gfx_cs_space(sctx, 0);
915
895
 
1028
1008
 
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);
1031
 
 
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);
1034
1012
}
1035
1013
 
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;
1070
1048
 
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;
1075
1053
 
1076
1054
      op = PRED_OP(PREDICATION_OP_PRIMCOUNT);
1077
1055
 
1089
1067
      while (first) {
1090
1068
         qbuf = first;
1091
1069
         if (first != last)
1092
 
            first = list_entry(qbuf->list.next, struct gfx10_sh_query_buffer, list);
 
1070
            first = list_entry(qbuf->list.next, struct gfx11_sh_query_buffer, list);
1093
1071
         else
1094
1072
            first = NULL;
1095
1073
 
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;
1102
1080
 
1103
 
         unsigned count = (end - begin) / sizeof(struct gfx10_sh_query_buffer_mem);
 
1081
         unsigned count = (end - begin) / sizeof(struct gfx11_sh_query_buffer_mem);
1104
1082
         do {
1105
1083
            if (gfx10_query->b.type == PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE) {
1106
1084
               for (unsigned stream = 0; stream < SI_MAX_STREAMS; ++stream) {
1114
1092
               op |= PREDICATION_CONTINUE;
1115
1093
            }
1116
1094
 
1117
 
            results_base += sizeof(struct gfx10_sh_query_buffer_mem);
 
1095
            results_base += sizeof(struct gfx11_sh_query_buffer_mem);
1118
1096
         } while (count--);
1119
1097
      }
1120
1098
   } else {
1196
1174
       (query_type >= PIPE_QUERY_DRIVER_SPECIFIC))
1197
1175
      return si_query_sw_create(query_type);
1198
1176
 
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);
1205
1183
 
1206
1184
   return si_query_hw_create(sscreen, query_type, index);
1207
1185
}
1222
1200
   return squery->ops->begin(sctx, squery);
1223
1201
}
1224
1202
 
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)
1226
1204
{
1227
1205
   struct si_query_hw *query = (struct si_query_hw *)squery;
1228
1206
 
1253
1231
   return squery->ops->end(sctx, squery);
1254
1232
}
1255
1233
 
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)
1257
1235
{
1258
1236
   struct si_query_hw *query = (struct si_query_hw *)squery;
1259
1237
 
1439
1417
   }
1440
1418
}
1441
1419
 
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)
1443
1421
{
1444
1422
   si_query_hw_emit_stop(sctx, (struct si_query_hw *)query);
1445
1423
}
1446
1424
 
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)
1448
1426
{
1449
1427
   si_query_hw_emit_start(sctx, (struct si_query_hw *)query);
1450
1428
}
1451
1429
 
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,
1458
 
 
1459
 
   .suspend = si_query_hw_suspend,
1460
 
   .resume = si_query_hw_resume,
1461
 
};
1462
 
 
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)
1465
1432
{
1484
1451
   util_query_clear_result(result, query->b.type);
1485
1452
}
1486
1453
 
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)
1489
1456
{
1490
1457
   struct si_screen *sscreen = sctx->screen;
1491
1458
   struct si_query_hw *query = (struct si_query_hw *)squery;
1933
1900
   return 1;
1934
1901
}
1935
1902
 
 
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,
 
1909
 
 
1910
   .suspend = si_query_hw_suspend,
 
1911
   .resume = si_query_hw_resume,
 
1912
};
 
1913
 
 
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
 
1920
};
 
1921
 
 
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,
 
1928
};
 
1929
 
1936
1930
void si_init_query_functions(struct si_context *sctx)
1937
1931
{
1938
1932
   sctx->b.create_query = si_create_query;