Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/radeonsi/si_build_pm4.h
4570 views
1
/*
2
* Copyright 2013 Advanced Micro Devices, Inc.
3
* All Rights Reserved.
4
*
5
* Permission is hereby granted, free of charge, to any person obtaining a
6
* copy of this software and associated documentation files (the "Software"),
7
* to deal in the Software without restriction, including without limitation
8
* on the rights to use, copy, modify, merge, publish, distribute, sub
9
* license, and/or sell copies of the Software, and to permit persons to whom
10
* the Software is furnished to do so, subject to the following conditions:
11
*
12
* The above copyright notice and this permission notice (including the next
13
* paragraph) shall be included in all copies or substantial portions of the
14
* Software.
15
*
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22
* USE OR OTHER DEALINGS IN THE SOFTWARE.
23
*/
24
25
/**
26
* This file contains helpers for writing commands to commands streams.
27
*/
28
29
#ifndef SI_BUILD_PM4_H
30
#define SI_BUILD_PM4_H
31
32
#include "si_pipe.h"
33
#include "sid.h"
34
35
#if 0
36
#include "ac_shadowed_regs.h"
37
#define SI_CHECK_SHADOWED_REGS(reg_offset, count) ac_check_shadowed_regs(GFX10, CHIP_NAVI14, reg_offset, count)
38
#else
39
#define SI_CHECK_SHADOWED_REGS(reg_offset, count)
40
#endif
41
42
#define radeon_begin(cs) struct radeon_cmdbuf *__cs = (cs); \
43
unsigned __cs_num = __cs->current.cdw; \
44
UNUSED unsigned __cs_num_initial = __cs_num; \
45
uint32_t *__cs_buf = __cs->current.buf
46
47
#define radeon_begin_again(cs) do { \
48
assert(__cs == NULL); \
49
__cs = (cs); \
50
__cs_num = __cs->current.cdw; \
51
__cs_num_initial = __cs_num; \
52
__cs_buf = __cs->current.buf; \
53
} while (0)
54
55
#define radeon_end() do { \
56
__cs->current.cdw = __cs_num; \
57
assert(__cs->current.cdw <= __cs->current.max_dw); \
58
__cs = NULL; \
59
} while (0)
60
61
#define radeon_emit(cs, value) __cs_buf[__cs_num++] = (value)
62
#define radeon_packets_added() (__cs_num != __cs_num_initial)
63
64
#define radeon_end_update_context_roll(sctx) do { \
65
radeon_end(); \
66
if (radeon_packets_added()) \
67
(sctx)->context_roll = true; \
68
} while (0)
69
70
#define radeon_emit_array(cs, values, num) do { \
71
unsigned __n = (num); \
72
memcpy(__cs_buf + __cs_num, (values), __n * 4); \
73
__cs_num += __n; \
74
} while (0)
75
76
#define radeon_set_config_reg_seq(cs, reg, num) do { \
77
SI_CHECK_SHADOWED_REGS(reg, num); \
78
assert((reg) < SI_CONTEXT_REG_OFFSET); \
79
radeon_emit(cs, PKT3(PKT3_SET_CONFIG_REG, num, 0)); \
80
radeon_emit(cs, ((reg) - SI_CONFIG_REG_OFFSET) >> 2); \
81
} while (0)
82
83
#define radeon_set_config_reg(cs, reg, value) do { \
84
radeon_set_config_reg_seq(cs, reg, 1); \
85
radeon_emit(cs, value); \
86
} while (0)
87
88
#define radeon_set_context_reg_seq(cs, reg, num) do { \
89
SI_CHECK_SHADOWED_REGS(reg, num); \
90
assert((reg) >= SI_CONTEXT_REG_OFFSET); \
91
radeon_emit(cs, PKT3(PKT3_SET_CONTEXT_REG, num, 0)); \
92
radeon_emit(cs, ((reg) - SI_CONTEXT_REG_OFFSET) >> 2); \
93
} while (0)
94
95
#define radeon_set_context_reg(cs, reg, value) do { \
96
radeon_set_context_reg_seq(cs, reg, 1); \
97
radeon_emit(cs, value); \
98
} while (0)
99
100
#define radeon_set_context_reg_seq_array(cs, reg, num, values) do { \
101
radeon_set_context_reg_seq(cs, reg, num); \
102
radeon_emit_array(cs, values, num); \
103
} while (0)
104
105
#define radeon_set_context_reg_idx(cs, reg, idx, value) do { \
106
SI_CHECK_SHADOWED_REGS(reg, 1); \
107
assert((reg) >= SI_CONTEXT_REG_OFFSET); \
108
radeon_emit(cs, PKT3(PKT3_SET_CONTEXT_REG, 1, 0)); \
109
radeon_emit(cs, ((reg) - SI_CONTEXT_REG_OFFSET) >> 2 | ((idx) << 28)); \
110
radeon_emit(cs, value); \
111
} while (0)
112
113
#define radeon_set_sh_reg_seq(cs, reg, num) do { \
114
SI_CHECK_SHADOWED_REGS(reg, num); \
115
assert((reg) >= SI_SH_REG_OFFSET && (reg) < SI_SH_REG_END); \
116
radeon_emit(cs, PKT3(PKT3_SET_SH_REG, num, 0)); \
117
radeon_emit(cs, ((reg) - SI_SH_REG_OFFSET) >> 2); \
118
} while (0)
119
120
#define radeon_set_sh_reg(cs, reg, value) do { \
121
radeon_set_sh_reg_seq(cs, reg, 1); \
122
radeon_emit(cs, value); \
123
} while (0)
124
125
#define radeon_set_uconfig_reg_seq(cs, reg, num, perfctr) do { \
126
SI_CHECK_SHADOWED_REGS(reg, num); \
127
assert((reg) >= CIK_UCONFIG_REG_OFFSET && (reg) < CIK_UCONFIG_REG_END); \
128
radeon_emit(cs, PKT3(PKT3_SET_UCONFIG_REG, num, perfctr)); \
129
radeon_emit(cs, ((reg) - CIK_UCONFIG_REG_OFFSET) >> 2); \
130
} while (0)
131
132
#define radeon_set_uconfig_reg(cs, reg, value) do { \
133
radeon_set_uconfig_reg_seq(cs, reg, 1, false); \
134
radeon_emit(cs, value); \
135
} while (0)
136
137
#define radeon_set_uconfig_reg_perfctr(cs, reg, value) do { \
138
radeon_set_uconfig_reg_seq(cs, reg, 1, true); \
139
radeon_emit(cs, value); \
140
} while (0)
141
142
#define radeon_set_uconfig_reg_idx(cs, screen, chip_class, reg, idx, value) do { \
143
SI_CHECK_SHADOWED_REGS(reg, 1); \
144
assert((reg) >= CIK_UCONFIG_REG_OFFSET && (reg) < CIK_UCONFIG_REG_END); \
145
assert((idx) != 0); \
146
unsigned __opcode = PKT3_SET_UCONFIG_REG_INDEX; \
147
if ((chip_class) < GFX9 || \
148
((chip_class) == GFX9 && (screen)->info.me_fw_version < 26)) \
149
__opcode = PKT3_SET_UCONFIG_REG; \
150
radeon_emit(cs, PKT3(__opcode, 1, 0)); \
151
radeon_emit(cs, ((reg) - CIK_UCONFIG_REG_OFFSET) >> 2 | ((idx) << 28)); \
152
radeon_emit(cs, value); \
153
} while (0)
154
155
#define radeon_set_context_reg_rmw(cs, reg, value, mask) do { \
156
SI_CHECK_SHADOWED_REGS(reg, 1); \
157
assert((reg) >= SI_CONTEXT_REG_OFFSET); \
158
radeon_emit(cs, PKT3(PKT3_CONTEXT_REG_RMW, 2, 0)); \
159
radeon_emit(cs, ((reg) - SI_CONTEXT_REG_OFFSET) >> 2); \
160
radeon_emit(cs, mask); \
161
radeon_emit(cs, value); \
162
} while (0)
163
164
/* Emit PKT3_CONTEXT_REG_RMW if the register value is different. */
165
#define radeon_opt_set_context_reg_rmw(sctx, offset, reg, val, mask) do { \
166
unsigned __value = (val); \
167
assert((__value & ~mask) == 0); \
168
__value &= mask; \
169
if (((sctx->tracked_regs.reg_saved >> (reg)) & 0x1) != 0x1 || \
170
sctx->tracked_regs.reg_value[reg] != __value) { \
171
radeon_set_context_reg_rmw(&sctx->gfx_cs, offset, __value, mask); \
172
sctx->tracked_regs.reg_saved |= 0x1ull << (reg); \
173
sctx->tracked_regs.reg_value[reg] = __value; \
174
} \
175
} while (0)
176
177
/* Emit PKT3_SET_CONTEXT_REG if the register value is different. */
178
#define radeon_opt_set_context_reg(sctx, offset, reg, val) do { \
179
unsigned __value = val; \
180
if (((sctx->tracked_regs.reg_saved >> (reg)) & 0x1) != 0x1 || \
181
sctx->tracked_regs.reg_value[reg] != __value) { \
182
radeon_set_context_reg(&sctx->gfx_cs, offset, __value); \
183
sctx->tracked_regs.reg_saved |= 0x1ull << (reg); \
184
sctx->tracked_regs.reg_value[reg] = __value; \
185
} \
186
} while (0)
187
188
/**
189
* Set 2 consecutive registers if any registers value is different.
190
* @param offset starting register offset
191
* @param val1 is written to first register
192
* @param val2 is written to second register
193
*/
194
#define radeon_opt_set_context_reg2(sctx, offset, reg, val1, val2) do { \
195
unsigned __value1 = (val1), __value2 = (val2); \
196
if (((sctx->tracked_regs.reg_saved >> (reg)) & 0x3) != 0x3 || \
197
sctx->tracked_regs.reg_value[reg] != __value1 || \
198
sctx->tracked_regs.reg_value[(reg) + 1] != __value2) { \
199
radeon_set_context_reg_seq(&sctx->gfx_cs, offset, 2); \
200
radeon_emit(cs, __value1); \
201
radeon_emit(cs, __value2); \
202
sctx->tracked_regs.reg_value[reg] = __value1; \
203
sctx->tracked_regs.reg_value[(reg) + 1] = __value2; \
204
sctx->tracked_regs.reg_saved |= 0x3ull << (reg); \
205
} \
206
} while (0)
207
208
/**
209
* Set 3 consecutive registers if any registers value is different.
210
*/
211
#define radeon_opt_set_context_reg3(sctx, offset, reg, val1, val2, val3) do { \
212
unsigned __value1 = (val1), __value2 = (val2), __value3 = (val3); \
213
if (((sctx->tracked_regs.reg_saved >> (reg)) & 0x7) != 0x7 || \
214
sctx->tracked_regs.reg_value[reg] != __value1 || \
215
sctx->tracked_regs.reg_value[(reg) + 1] != __value2 || \
216
sctx->tracked_regs.reg_value[(reg) + 2] != __value3) { \
217
radeon_set_context_reg_seq(&sctx->gfx_cs, offset, 3); \
218
radeon_emit(cs, __value1); \
219
radeon_emit(cs, __value2); \
220
radeon_emit(cs, __value3); \
221
sctx->tracked_regs.reg_value[reg] = __value1; \
222
sctx->tracked_regs.reg_value[(reg) + 1] = __value2; \
223
sctx->tracked_regs.reg_value[(reg) + 2] = __value3; \
224
sctx->tracked_regs.reg_saved |= 0x7ull << (reg); \
225
} \
226
} while (0)
227
228
/**
229
* Set 4 consecutive registers if any registers value is different.
230
*/
231
#define radeon_opt_set_context_reg4(sctx, offset, reg, val1, val2, val3, val4) do { \
232
unsigned __value1 = (val1), __value2 = (val2), __value3 = (val3), __value4 = (val4); \
233
if (((sctx->tracked_regs.reg_saved >> (reg)) & 0xf) != 0xf || \
234
sctx->tracked_regs.reg_value[reg] != __value1 || \
235
sctx->tracked_regs.reg_value[(reg) + 1] != __value2 || \
236
sctx->tracked_regs.reg_value[(reg) + 2] != __value3 || \
237
sctx->tracked_regs.reg_value[(reg) + 3] != __value4) { \
238
radeon_set_context_reg_seq(&sctx->gfx_cs, offset, 4); \
239
radeon_emit(cs, __value1); \
240
radeon_emit(cs, __value2); \
241
radeon_emit(cs, __value3); \
242
radeon_emit(cs, __value4); \
243
sctx->tracked_regs.reg_value[reg] = __value1; \
244
sctx->tracked_regs.reg_value[(reg) + 1] = __value2; \
245
sctx->tracked_regs.reg_value[(reg) + 2] = __value3; \
246
sctx->tracked_regs.reg_value[(reg) + 3] = __value4; \
247
sctx->tracked_regs.reg_saved |= 0xfull << (reg); \
248
} \
249
} while (0)
250
251
/**
252
* Set consecutive registers if any registers value is different.
253
*/
254
#define radeon_opt_set_context_regn(sctx, offset, value, saved_val, num) do { \
255
for (unsigned i = 0; i < (num); i++) { \
256
if ((saved_val)[i] != (value)[i]) { \
257
radeon_set_context_reg_seq(&(sctx)->gfx_cs, offset, num); \
258
for (unsigned j = 0; j < (num); j++) \
259
radeon_emit(cs, value[j]); \
260
memcpy(saved_val, value, sizeof(uint32_t) * (num)); \
261
break; \
262
} \
263
} \
264
} while (0)
265
266
#define radeon_set_privileged_config_reg(cs, reg, value) do { \
267
assert((reg) < CIK_UCONFIG_REG_OFFSET); \
268
radeon_emit(cs, PKT3(PKT3_COPY_DATA, 4, 0)); \
269
radeon_emit(cs, COPY_DATA_SRC_SEL(COPY_DATA_IMM) | \
270
COPY_DATA_DST_SEL(COPY_DATA_PERF)); \
271
radeon_emit(cs, value); \
272
radeon_emit(cs, 0); /* unused */ \
273
radeon_emit(cs, (reg) >> 2); \
274
radeon_emit(cs, 0); /* unused */ \
275
} while (0)
276
277
#define radeon_emit_32bit_pointer(sscreen, cs, va) do { \
278
radeon_emit(cs, va); \
279
assert((va) == 0 || ((va) >> 32) == sscreen->info.address32_hi); \
280
} while (0)
281
282
#define radeon_emit_one_32bit_pointer(sctx, desc, sh_base) do { \
283
unsigned sh_offset = (sh_base) + (desc)->shader_userdata_offset; \
284
radeon_set_sh_reg_seq(&sctx->gfx_cs, sh_offset, 1); \
285
radeon_emit_32bit_pointer(sctx->screen, cs, (desc)->gpu_address); \
286
} while (0)
287
288
/* This should be evaluated at compile time if all parameters are constants. */
289
static ALWAYS_INLINE unsigned
290
si_get_user_data_base(enum chip_class chip_class, enum si_has_tess has_tess,
291
enum si_has_gs has_gs, enum si_has_ngg ngg,
292
enum pipe_shader_type shader)
293
{
294
switch (shader) {
295
case PIPE_SHADER_VERTEX:
296
/* VS can be bound as VS, ES, or LS. */
297
if (has_tess) {
298
if (chip_class >= GFX10) {
299
return R_00B430_SPI_SHADER_USER_DATA_HS_0;
300
} else if (chip_class == GFX9) {
301
return R_00B430_SPI_SHADER_USER_DATA_LS_0;
302
} else {
303
return R_00B530_SPI_SHADER_USER_DATA_LS_0;
304
}
305
} else if (chip_class >= GFX10) {
306
if (ngg || has_gs) {
307
return R_00B230_SPI_SHADER_USER_DATA_GS_0;
308
} else {
309
return R_00B130_SPI_SHADER_USER_DATA_VS_0;
310
}
311
} else if (has_gs) {
312
return R_00B330_SPI_SHADER_USER_DATA_ES_0;
313
} else {
314
return R_00B130_SPI_SHADER_USER_DATA_VS_0;
315
}
316
317
case PIPE_SHADER_TESS_CTRL:
318
if (chip_class == GFX9) {
319
return R_00B430_SPI_SHADER_USER_DATA_LS_0;
320
} else {
321
return R_00B430_SPI_SHADER_USER_DATA_HS_0;
322
}
323
324
case PIPE_SHADER_TESS_EVAL:
325
/* TES can be bound as ES, VS, or not bound. */
326
if (has_tess) {
327
if (chip_class >= GFX10) {
328
if (ngg || has_gs) {
329
return R_00B230_SPI_SHADER_USER_DATA_GS_0;
330
} else {
331
return R_00B130_SPI_SHADER_USER_DATA_VS_0;
332
}
333
} else if (has_gs) {
334
return R_00B330_SPI_SHADER_USER_DATA_ES_0;
335
} else {
336
return R_00B130_SPI_SHADER_USER_DATA_VS_0;
337
}
338
} else {
339
return 0;
340
}
341
342
case PIPE_SHADER_GEOMETRY:
343
if (chip_class == GFX9) {
344
return R_00B330_SPI_SHADER_USER_DATA_ES_0;
345
} else {
346
return R_00B230_SPI_SHADER_USER_DATA_GS_0;
347
}
348
349
default:
350
assert(0);
351
return 0;
352
}
353
}
354
355
#endif
356
357