1 /*
2 * Copyright 2012 Advanced Micro Devices, Inc.
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7 #include "si_pm4.h"
8 #include "si_pipe.h"
9 #include "si_build_pm4.h"
10 #include "sid.h"
11 #include "util/u_memory.h"
12 #include "ac_debug.h"
13
si_pm4_clear_state(struct si_pm4_state * state,struct si_screen * sscreen,bool is_compute_queue)14 void si_pm4_clear_state(struct si_pm4_state *state, struct si_screen *sscreen,
15 bool is_compute_queue)
16 {
17 const bool debug_sqtt = !!(sscreen->debug_flags & DBG(SQTT));
18
19 ac_pm4_clear_state(&state->base, &sscreen->info, debug_sqtt, is_compute_queue);
20 }
21
si_pm4_free_state(struct si_context * sctx,struct si_pm4_state * state,unsigned idx)22 void si_pm4_free_state(struct si_context *sctx, struct si_pm4_state *state, unsigned idx)
23 {
24 if (!state)
25 return;
26
27 if (idx != ~0) {
28 if (sctx->emitted.array[idx] == state)
29 sctx->emitted.array[idx] = NULL;
30
31 if (sctx->queued.array[idx] == state) {
32 sctx->queued.array[idx] = NULL;
33 sctx->dirty_atoms &= ~BITFIELD64_BIT(idx);
34 }
35 }
36
37 FREE(state);
38 }
39
si_pm4_emit_commands(struct si_context * sctx,struct si_pm4_state * state)40 void si_pm4_emit_commands(struct si_context *sctx, struct si_pm4_state *state)
41 {
42 struct radeon_cmdbuf *cs = &sctx->gfx_cs;
43
44 radeon_begin(cs);
45 radeon_emit_array(state->base.pm4, state->base.ndw);
46 radeon_end();
47 }
48
si_pm4_emit_state(struct si_context * sctx,unsigned index)49 void si_pm4_emit_state(struct si_context *sctx, unsigned index)
50 {
51 struct si_pm4_state *state = sctx->queued.array[index];
52 struct radeon_cmdbuf *cs = &sctx->gfx_cs;
53
54 /* All places should unset dirty_states if this doesn't pass. */
55 assert(state && state != sctx->emitted.array[index]);
56
57 radeon_begin(cs);
58 radeon_emit_array(state->base.pm4, state->base.ndw);
59 radeon_end();
60
61 sctx->emitted.array[index] = state;
62 }
63
si_pm4_emit_shader(struct si_context * sctx,unsigned index)64 void si_pm4_emit_shader(struct si_context *sctx, unsigned index)
65 {
66 struct si_pm4_state *state = sctx->queued.array[index];
67
68 si_pm4_emit_state(sctx, index);
69
70 radeon_add_to_buffer_list(sctx, &sctx->gfx_cs, ((struct si_shader*)state)->bo,
71 RADEON_USAGE_READ | RADEON_PRIO_SHADER_BINARY);
72 if (state->atom.emit)
73 state->atom.emit(sctx, -1);
74 }
75
si_pm4_reset_emitted(struct si_context * sctx)76 void si_pm4_reset_emitted(struct si_context *sctx)
77 {
78 memset(&sctx->emitted, 0, sizeof(sctx->emitted));
79
80 for (unsigned i = 0; i < SI_NUM_STATES; i++) {
81 if (sctx->queued.array[i])
82 sctx->dirty_atoms |= BITFIELD64_BIT(i);
83 }
84 }
85
si_pm4_create_sized(struct si_screen * sscreen,unsigned max_dw,bool is_compute_queue)86 struct si_pm4_state *si_pm4_create_sized(struct si_screen *sscreen, unsigned max_dw,
87 bool is_compute_queue)
88 {
89 struct si_pm4_state *pm4;
90 unsigned size = sizeof(*pm4) + 4 * (max_dw - ARRAY_SIZE(pm4->base.pm4));
91
92 pm4 = (struct si_pm4_state *)calloc(1, size);
93 if (pm4) {
94 pm4->base.max_dw = max_dw;
95 si_pm4_clear_state(pm4, sscreen, is_compute_queue);
96 }
97 return pm4;
98 }
99
si_pm4_clone(struct si_screen * sscreen,struct si_pm4_state * orig)100 struct si_pm4_state *si_pm4_clone(struct si_screen *sscreen, struct si_pm4_state *orig)
101 {
102 struct si_pm4_state *pm4 = si_pm4_create_sized(sscreen, orig->base.max_dw,
103 orig->base.is_compute_queue);
104 if (pm4)
105 memcpy(pm4, orig, sizeof(*pm4) + 4 * (pm4->base.max_dw - ARRAY_SIZE(pm4->base.pm4)));
106 return pm4;
107 }
108