xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/r600/r600_cs.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2013 Advanced Micro Devices, Inc.
3  * Authors: Marek Olšák <[email protected]>
4  * SPDX-License-Identifier: MIT
5  */
6 
7 /**
8  * This file contains helpers for writing commands to commands streams.
9  */
10 
11 #ifndef R600_CS_H
12 #define R600_CS_H
13 
14 #include "r600_pipe_common.h"
15 #include "r600d_common.h"
16 
17 /**
18  * Return true if there is enough memory in VRAM and GTT for the buffers
19  * added so far.
20  *
21  * \param vram      VRAM memory size not added to the buffer list yet
22  * \param gtt       GTT memory size not added to the buffer list yet
23  */
24 static inline bool
radeon_cs_memory_below_limit(struct r600_common_screen * screen,struct radeon_cmdbuf * cs,uint64_t vram,uint64_t gtt)25 radeon_cs_memory_below_limit(struct r600_common_screen *screen,
26 			     struct radeon_cmdbuf *cs,
27 			     uint64_t vram, uint64_t gtt)
28 {
29 	vram += (uint64_t)cs->used_vram_kb * 1024;
30 	gtt += (uint64_t)cs->used_gart_kb * 1024;
31 
32 	/* Anything that goes above the VRAM size should go to GTT. */
33 	if (vram > (uint64_t)screen->info.vram_size_kb * 1024)
34 		gtt += vram - (uint64_t)screen->info.vram_size_kb * 1024;
35 
36 	/* Now we just need to check if we have enough GTT. */
37 	return gtt < (uint64_t)screen->info.gart_size_kb * 1024 * 0.7;
38 }
39 
40 /**
41  * Add a buffer to the buffer list for the given command stream (CS).
42  *
43  * All buffers used by a CS must be added to the list. This tells the kernel
44  * driver which buffers are used by GPU commands. Other buffers can
45  * be swapped out (not accessible) during execution.
46  *
47  * The buffer list becomes empty after every context flush and must be
48  * rebuilt.
49  */
radeon_add_to_buffer_list(struct r600_common_context * rctx,struct r600_ring * ring,struct r600_resource * rbo,unsigned usage)50 static inline unsigned radeon_add_to_buffer_list(struct r600_common_context *rctx,
51 						 struct r600_ring *ring,
52 						 struct r600_resource *rbo,
53 						 unsigned usage)
54 {
55 	assert(usage);
56 	return rctx->ws->cs_add_buffer(
57 		&ring->cs, rbo->buf,
58 		usage | RADEON_USAGE_SYNCHRONIZED,
59 		rbo->domains) * 4;
60 }
61 
62 /**
63  * Same as above, but also checks memory usage and flushes the context
64  * accordingly.
65  *
66  * When this SHOULD NOT be used:
67  *
68  * - if r600_context_add_resource_size has been called for the buffer
69  *   followed by *_need_cs_space for checking the memory usage
70  *
71  * - if r600_need_dma_space has been called for the buffer
72  *
73  * - when emitting state packets and draw packets (because preceding packets
74  *   can't be re-emitted at that point)
75  *
76  * - if shader resource "enabled_mask" is not up-to-date or there is
77  *   a different constraint disallowing a context flush
78  */
79 static inline unsigned
radeon_add_to_buffer_list_check_mem(struct r600_common_context * rctx,struct r600_ring * ring,struct r600_resource * rbo,unsigned usage,bool check_mem)80 radeon_add_to_buffer_list_check_mem(struct r600_common_context *rctx,
81 				    struct r600_ring *ring,
82 				    struct r600_resource *rbo,
83 				    unsigned usage,
84 				    bool check_mem)
85 {
86 	if (check_mem &&
87 	    !radeon_cs_memory_below_limit(rctx->screen, &ring->cs,
88 					  rctx->vram + rbo->vram_usage,
89 					  rctx->gtt + rbo->gart_usage))
90 		ring->flush(rctx, PIPE_FLUSH_ASYNC, NULL);
91 
92 	return radeon_add_to_buffer_list(rctx, ring, rbo, usage);
93 }
94 
r600_emit_reloc(struct r600_common_context * rctx,struct r600_ring * ring,struct r600_resource * rbo,unsigned usage)95 static inline void r600_emit_reloc(struct r600_common_context *rctx,
96 				   struct r600_ring *ring, struct r600_resource *rbo,
97 				   unsigned usage)
98 {
99 	struct radeon_cmdbuf *cs = &ring->cs;
100 	bool has_vm = ((struct r600_common_screen*)rctx->b.screen)->info.r600_has_virtual_memory;
101 	unsigned reloc = radeon_add_to_buffer_list(rctx, ring, rbo, usage);
102 
103 	if (!has_vm) {
104 		radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
105 		radeon_emit(cs, reloc);
106 	}
107 }
108 
radeon_set_config_reg_seq(struct radeon_cmdbuf * cs,unsigned reg,unsigned num)109 static inline void radeon_set_config_reg_seq(struct radeon_cmdbuf *cs, unsigned reg, unsigned num)
110 {
111 	assert(reg < R600_CONTEXT_REG_OFFSET);
112 	assert(cs->current.cdw + 2 + num <= cs->current.max_dw);
113 	radeon_emit(cs, PKT3(PKT3_SET_CONFIG_REG, num, 0));
114 	radeon_emit(cs, (reg - R600_CONFIG_REG_OFFSET) >> 2);
115 }
116 
radeon_set_config_reg(struct radeon_cmdbuf * cs,unsigned reg,unsigned value)117 static inline void radeon_set_config_reg(struct radeon_cmdbuf *cs, unsigned reg, unsigned value)
118 {
119 	radeon_set_config_reg_seq(cs, reg, 1);
120 	radeon_emit(cs, value);
121 }
122 
radeon_set_context_reg_seq(struct radeon_cmdbuf * cs,unsigned reg,unsigned num)123 static inline void radeon_set_context_reg_seq(struct radeon_cmdbuf *cs, unsigned reg, unsigned num)
124 {
125 	assert(reg >= R600_CONTEXT_REG_OFFSET);
126 	assert(cs->current.cdw + 2 + num <= cs->current.max_dw);
127 	radeon_emit(cs, PKT3(PKT3_SET_CONTEXT_REG, num, 0));
128 	radeon_emit(cs, (reg - R600_CONTEXT_REG_OFFSET) >> 2);
129 }
130 
radeon_set_context_reg(struct radeon_cmdbuf * cs,unsigned reg,unsigned value)131 static inline void radeon_set_context_reg(struct radeon_cmdbuf *cs, unsigned reg, unsigned value)
132 {
133 	radeon_set_context_reg_seq(cs, reg, 1);
134 	radeon_emit(cs, value);
135 }
136 
radeon_set_context_reg_idx(struct radeon_cmdbuf * cs,unsigned reg,unsigned idx,unsigned value)137 static inline void radeon_set_context_reg_idx(struct radeon_cmdbuf *cs,
138 					      unsigned reg, unsigned idx,
139 					      unsigned value)
140 {
141 	assert(reg >= R600_CONTEXT_REG_OFFSET);
142 	assert(cs->current.cdw + 3 <= cs->current.max_dw);
143 	radeon_emit(cs, PKT3(PKT3_SET_CONTEXT_REG, 1, 0));
144 	radeon_emit(cs, (reg - R600_CONTEXT_REG_OFFSET) >> 2 | (idx << 28));
145 	radeon_emit(cs, value);
146 }
147 
radeon_set_sh_reg_seq(struct radeon_cmdbuf * cs,unsigned reg,unsigned num)148 static inline void radeon_set_sh_reg_seq(struct radeon_cmdbuf *cs, unsigned reg, unsigned num)
149 {
150 	assert(reg >= SI_SH_REG_OFFSET && reg < SI_SH_REG_END);
151 	assert(cs->current.cdw + 2 + num <= cs->current.max_dw);
152 	radeon_emit(cs, PKT3(PKT3_SET_SH_REG, num, 0));
153 	radeon_emit(cs, (reg - SI_SH_REG_OFFSET) >> 2);
154 }
155 
radeon_set_sh_reg(struct radeon_cmdbuf * cs,unsigned reg,unsigned value)156 static inline void radeon_set_sh_reg(struct radeon_cmdbuf *cs, unsigned reg, unsigned value)
157 {
158 	radeon_set_sh_reg_seq(cs, reg, 1);
159 	radeon_emit(cs, value);
160 }
161 
radeon_set_uconfig_reg_seq(struct radeon_cmdbuf * cs,unsigned reg,unsigned num)162 static inline void radeon_set_uconfig_reg_seq(struct radeon_cmdbuf *cs, unsigned reg, unsigned num)
163 {
164 	assert(reg >= CIK_UCONFIG_REG_OFFSET && reg < CIK_UCONFIG_REG_END);
165 	assert(cs->current.cdw + 2 + num <= cs->current.max_dw);
166 	radeon_emit(cs, PKT3(PKT3_SET_UCONFIG_REG, num, 0));
167 	radeon_emit(cs, (reg - CIK_UCONFIG_REG_OFFSET) >> 2);
168 }
169 
radeon_set_uconfig_reg(struct radeon_cmdbuf * cs,unsigned reg,unsigned value)170 static inline void radeon_set_uconfig_reg(struct radeon_cmdbuf *cs, unsigned reg, unsigned value)
171 {
172 	radeon_set_uconfig_reg_seq(cs, reg, 1);
173 	radeon_emit(cs, value);
174 }
175 
radeon_set_uconfig_reg_idx(struct radeon_cmdbuf * cs,unsigned reg,unsigned idx,unsigned value)176 static inline void radeon_set_uconfig_reg_idx(struct radeon_cmdbuf *cs,
177 					      unsigned reg, unsigned idx,
178 					      unsigned value)
179 {
180 	assert(reg >= CIK_UCONFIG_REG_OFFSET && reg < CIK_UCONFIG_REG_END);
181 	assert(cs->current.cdw + 3 <= cs->current.max_dw);
182 	radeon_emit(cs, PKT3(PKT3_SET_UCONFIG_REG, 1, 0));
183 	radeon_emit(cs, (reg - CIK_UCONFIG_REG_OFFSET) >> 2 | (idx << 28));
184 	radeon_emit(cs, value);
185 }
186 
187 #endif
188