xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/radeonsi/si_cp_reg_shadowing.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2020 Advanced Micro Devices, Inc.
3  *
4  * SPDX-License-Identifier: MIT
5  */
6 
7 #include "si_build_pm4.h"
8 #include "ac_debug.h"
9 #include "ac_shadowed_regs.h"
10 #include "util/u_memory.h"
11 
si_set_context_reg_array(struct radeon_cmdbuf * cs,unsigned reg,unsigned num,const uint32_t * values)12 static void si_set_context_reg_array(struct radeon_cmdbuf *cs, unsigned reg, unsigned num,
13                                      const uint32_t *values)
14 {
15    radeon_begin(cs);
16    radeon_set_context_reg_seq(reg, num);
17    radeon_emit_array(values, num);
18    radeon_end();
19 }
20 
si_init_cp_reg_shadowing(struct si_context * sctx)21 void si_init_cp_reg_shadowing(struct si_context *sctx)
22 {
23    if (sctx->has_graphics &&
24        sctx->screen->info.register_shadowing_required) {
25       if (sctx->screen->info.has_fw_based_shadowing) {
26          sctx->shadowing.registers =
27                si_aligned_buffer_create(sctx->b.screen,
28                                         PIPE_RESOURCE_FLAG_UNMAPPABLE | SI_RESOURCE_FLAG_DRIVER_INTERNAL,
29                                         PIPE_USAGE_DEFAULT,
30                                         sctx->screen->info.fw_based_mcbp.shadow_size,
31                                         sctx->screen->info.fw_based_mcbp.shadow_alignment);
32          sctx->shadowing.csa =
33                si_aligned_buffer_create(sctx->b.screen,
34                                         PIPE_RESOURCE_FLAG_UNMAPPABLE | SI_RESOURCE_FLAG_DRIVER_INTERNAL,
35                                         PIPE_USAGE_DEFAULT,
36                                         sctx->screen->info.fw_based_mcbp.csa_size,
37                                         sctx->screen->info.fw_based_mcbp.csa_alignment);
38          if (!sctx->shadowing.registers || !sctx->shadowing.csa)
39             fprintf(stderr, "radeonsi: cannot create register shadowing buffer(s)\n");
40          else
41             sctx->ws->cs_set_mcbp_reg_shadowing_va(&sctx->gfx_cs,
42                                                    sctx->shadowing.registers->gpu_address,
43                                                    sctx->shadowing.csa->gpu_address);
44       } else {
45          sctx->shadowing.registers =
46                si_aligned_buffer_create(sctx->b.screen,
47                                         PIPE_RESOURCE_FLAG_UNMAPPABLE | SI_RESOURCE_FLAG_DRIVER_INTERNAL,
48                                         PIPE_USAGE_DEFAULT,
49                                         SI_SHADOWED_REG_BUFFER_SIZE,
50                                         4096);
51          if (!sctx->shadowing.registers)
52             fprintf(stderr, "radeonsi: cannot create a shadowed_regs buffer\n");
53       }
54    }
55 
56    si_init_gfx_preamble_state(sctx);
57 
58    if (sctx->shadowing.registers) {
59       /* We need to clear the shadowed reg buffer. */
60       si_cp_dma_clear_buffer(sctx, &sctx->gfx_cs, &sctx->shadowing.registers->b.b,
61                              0, sctx->shadowing.registers->bo_size, 0);
62       si_barrier_after_simple_buffer_op(sctx, 0, &sctx->shadowing.registers->b.b, NULL);
63 
64       /* Create the shadowing preamble. (allocate enough dwords because the preamble is large) */
65       struct si_pm4_state *shadowing_preamble = si_pm4_create_sized(sctx->screen, 256, false);
66 
67       ac_create_shadowing_ib_preamble(&sctx->screen->info,
68                                       (pm4_cmd_add_fn)ac_pm4_cmd_add, &shadowing_preamble->base,
69                                       sctx->shadowing.registers->gpu_address, sctx->screen->dpbb_allowed);
70 
71       /* Initialize shadowed registers as follows. */
72       radeon_add_to_buffer_list(sctx, &sctx->gfx_cs, sctx->shadowing.registers,
73                                 RADEON_USAGE_READWRITE | RADEON_PRIO_DESCRIPTORS);
74       if (sctx->shadowing.csa)
75          radeon_add_to_buffer_list(sctx, &sctx->gfx_cs, sctx->shadowing.csa,
76                                    RADEON_USAGE_READWRITE | RADEON_PRIO_DESCRIPTORS);
77       si_pm4_emit_commands(sctx, shadowing_preamble);
78 
79       if (sctx->gfx_level < GFX12)
80          ac_emulate_clear_state(&sctx->screen->info, &sctx->gfx_cs, si_set_context_reg_array);
81 
82       /* TODO: Gfx11 fails GLCTS if we don't re-emit the preamble at the beginning of every IB. */
83       /* TODO: Skipping this may have made register shadowing slower on Gfx11. */
84       if (sctx->gfx_level < GFX11) {
85          si_pm4_emit_commands(sctx, sctx->cs_preamble_state);
86 
87          /* The register values are shadowed, so we won't need to set them again. */
88          si_pm4_free_state(sctx, sctx->cs_preamble_state, ~0);
89          sctx->cs_preamble_state = NULL;
90       }
91 
92       if (sctx->gfx_level < GFX12)
93          si_set_tracked_regs_to_clear_state(sctx);
94 
95       /* Setup preemption. The shadowing preamble will be executed as a preamble IB,
96        * which will load register values from memory on a context switch.
97        */
98       sctx->ws->cs_setup_preemption(&sctx->gfx_cs, shadowing_preamble->base.pm4,
99                                     shadowing_preamble->base.ndw);
100       si_pm4_free_state(sctx, shadowing_preamble, ~0);
101    }
102 }
103