ac,radv,radeonsi: add tracked register macros to common code

Because the tracked registers are really driver dependant, the driver
is expected to handle the tracked_registers struct itself.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38740>
This commit is contained in:
Samuel Pitoiset 2025-12-01 09:48:27 +01:00 committed by Marge Bot
parent c580fc667f
commit f8feed17e1
3 changed files with 237 additions and 184 deletions

View file

@ -500,6 +500,209 @@ struct ac_tracked_regs {
ac_gfx12_push_sh_reg(buf_regs, sh_offset + 4, va >> 32); \ ac_gfx12_push_sh_reg(buf_regs, sh_offset + 4, va >> 32); \
} while (0) } while (0)
/* Tracked registers. */
#define ac_cmdbuf_opt_set_context_reg(tracked_regs, reg, reg_enum, value) \
do { \
const uint32_t __value = (value); \
if (!BITSET_TEST(tracked_regs->reg_saved_mask, (reg_enum)) || \
tracked_regs->reg_value[(reg_enum)] != __value) { \
ac_cmdbuf_set_context_reg(reg, __value); \
BITSET_SET(tracked_regs->reg_saved_mask, (reg_enum)); \
tracked_regs->reg_value[(reg_enum)] = __value; \
__cs->context_roll = true; \
} \
} while (0)
#define ac_cmdbuf_opt_set_context_reg2(tracked_regs, reg, reg_enum, v1, v2) \
do { \
static_assert(BITSET_BITWORD(reg_enum) == BITSET_BITWORD(reg_enum + 1), \
"bit range crosses dword boundary"); \
const uint32_t __v1 = (v1); \
const uint32_t __v2 = (v2); \
if (!BITSET_TEST_RANGE_INSIDE_WORD(tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 1, 0x3) || \
tracked_regs->reg_value[(reg_enum)] != __v1 || tracked_regs->reg_value[(reg_enum) + 1] != __v2) { \
ac_cmdbuf_set_context_reg_seq(reg, 2); \
ac_cmdbuf_emit(__v1); \
ac_cmdbuf_emit(__v2); \
BITSET_SET_RANGE_INSIDE_WORD(tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 1); \
tracked_regs->reg_value[(reg_enum)] = __v1; \
tracked_regs->reg_value[(reg_enum) + 1] = __v2; \
__cs->context_roll = true; \
} \
} while (0)
#define ac_cmdbuf_opt_set_context_reg3(tracked_regs, reg, reg_enum, v1, v2, v3) \
do { \
static_assert(BITSET_BITWORD(reg_enum) == BITSET_BITWORD(reg_enum + 2), \
"bit range crosses dword boundary"); \
const uint32_t __v1 = (v1); \
const uint32_t __v2 = (v2); \
const uint32_t __v3 = (v3); \
if (!BITSET_TEST_RANGE_INSIDE_WORD(tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 2, 0x7) || \
tracked_regs->reg_value[(reg_enum)] != __v1 || tracked_regs->reg_value[(reg_enum) + 1] != __v2 || \
tracked_regs->reg_value[(reg_enum) + 2] != __v3) { \
ac_cmdbuf_set_context_reg_seq(reg, 3); \
ac_cmdbuf_emit(__v1); \
ac_cmdbuf_emit(__v2); \
ac_cmdbuf_emit(__v3); \
BITSET_SET_RANGE_INSIDE_WORD(__tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 2); \
tracked_regs->reg_value[(reg_enum)] = __v1; \
tracked_regs->reg_value[(reg_enum) + 1] = __v2; \
tracked_regs->reg_value[(reg_enum) + 2] = __v3; \
__cs->context_roll = true; \
} \
} while (0)
#define ac_cmdbuf_opt_set_context_reg4(tracked_regs, reg, reg_enum, v1, v2, v3, v4) \
do { \
static_assert(BITSET_BITWORD((reg_enum)) == BITSET_BITWORD((reg_enum) + 3), \
"bit range crosses dword boundary"); \
const uint32_t __v1 = (v1); \
const uint32_t __v2 = (v2); \
const uint32_t __v3 = (v3); \
const uint32_t __v4 = (v4); \
if (!BITSET_TEST_RANGE_INSIDE_WORD(tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 3, 0xf) || \
tracked_regs->reg_value[(reg_enum)] != __v1 || tracked_regs->reg_value[(reg_enum) + 1] != __v2 || \
tracked_regs->reg_value[(reg_enum) + 2] != __v3 || tracked_regs->reg_value[(reg_enum) + 3] != __v4) { \
ac_cmdbuf_set_context_reg_seq(reg, 4); \
ac_cmdbuf_emit(__v1); \
ac_cmdbuf_emit(__v2); \
ac_cmdbuf_emit(__v3); \
ac_cmdbuf_emit(__v4); \
BITSET_SET_RANGE_INSIDE_WORD(tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 3); \
tracked_regs->reg_value[(reg_enum)] = __v1; \
tracked_regs->reg_value[(reg_enum) + 1] = __v2; \
tracked_regs->reg_value[(reg_enum) + 2] = __v3; \
tracked_regs->reg_value[(reg_enum) + 3] = __v4; \
__cs->context_roll = true; \
} \
} while (0)
#define ac_cmdbuf_opt_set_context_regn(reg, values, saved_values, num) \
do { \
if (memcmp(values, saved_values, sizeof(uint32_t) * (num))) { \
ac_cmdbuf_set_context_reg_seq(reg, num); \
ac_cmdbuf_emit_array(values, num); \
memcpy(saved_values, values, sizeof(uint32_t) * (num)); \
__cs->context_roll = true; \
} \
} while (0)
/* GFX11 */
#define ac_gfx11_opt_push_reg(tracked_regs, reg, reg_enum, value, prefix_name, buffer, reg_count) \
do { \
const uint32_t __value = (value); \
if (!BITSET_TEST(tracked_regs->reg_saved_mask, (reg_enum)) || \
tracked_regs->reg_value[(reg_enum)] != __value) { \
ac_gfx11_push_reg((reg), __value, prefix_name, buffer, reg_count); \
BITSET_SET(tracked_regs->reg_saved_mask, (reg_enum)); \
tracked_regs->reg_value[(reg_enum)] = __value; \
} \
} while (0)
#define ac_gfx11_opt_push_reg2(tracked_regs, reg, reg_enum, v1, v2, prefix_name, buffer, reg_count) \
do { \
static_assert(BITSET_BITWORD(reg_enum) == BITSET_BITWORD(reg_enum + 1), \
"bit range crosses dword boundary"); \
const uint32_t __v1 = (v1); \
const uint32_t __v2 = (v2); \
if (!BITSET_TEST_RANGE_INSIDE_WORD(tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 1, 0x3) || \
tracked_regs->reg_value[(reg_enum)] != __v1 || tracked_regs->reg_value[(reg_enum) + 1] != __v2) { \
ac_gfx11_push_reg((reg), __v1, prefix_name, buffer, reg_count); \
ac_gfx11_push_reg((reg) + 4, __v2, prefix_name, buffer, reg_count); \
BITSET_SET_RANGE_INSIDE_WORD(tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 1); \
tracked_regs->reg_value[(reg_enum)] = __v1; \
tracked_regs->reg_value[(reg_enum) + 1] = __v2; \
} \
} while (0)
#define ac_gfx11_opt_push_reg4(tracked_regs, reg, reg_enum, v1, v2, v3, v4, prefix_name, buffer, reg_count) \
do { \
static_assert(BITSET_BITWORD((reg_enum)) == BITSET_BITWORD((reg_enum) + 3), \
"bit range crosses dword boundary"); \
const uint32_t __v1 = (v1); \
const uint32_t __v2 = (v2); \
const uint32_t __v3 = (v3); \
const uint32_t __v4 = (v4); \
if (!BITSET_TEST_RANGE_INSIDE_WORD(tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 3, 0xf) || \
tracked_regs->reg_value[(reg_enum)] != __v1 || \
tracked_regs->reg_value[(reg_enum) + 1] != __v2 || \
tracked_regs->reg_value[(reg_enum) + 2] != __v3 || \
tracked_regs->reg_value[(reg_enum) + 3] != __v4) { \
ac_gfx11_push_reg((reg), __v1, prefix_name, buffer, reg_count); \
ac_gfx11_push_reg((reg) + 4, __v2, prefix_name, buffer, reg_count); \
ac_gfx11_push_reg((reg) + 8, __v3, prefix_name, buffer, reg_count); \
ac_gfx11_push_reg((reg) + 12, __v4, prefix_name, buffer, reg_count); \
BITSET_SET_RANGE_INSIDE_WORD(tracked_regs->reg_saved_mask, \
(reg_enum), (reg_enum) + 3); \
tracked_regs->reg_value[(reg_enum)] = __v1; \
tracked_regs->reg_value[(reg_enum) + 1] = __v2; \
tracked_regs->reg_value[(reg_enum) + 2] = __v3; \
tracked_regs->reg_value[(reg_enum) + 3] = __v4; \
} \
} while (0)
#define ac_gfx11_opt_set_context_reg(tracked_regs, reg, reg_enum, value) \
ac_gfx11_opt_push_reg(tracked_regs, reg, reg_enum, value, SI_CONTEXT, __cs_context_regs, __cs_context_reg_count)
#define ac_gfx11_opt_set_context_reg2(tracked_regs, reg, reg_enum, v1, v2) \
ac_gfx11_opt_push_reg2(tracked_regs, reg, reg_enum, v1, v2, SI_CONTEXT, __cs_context_regs, __cs_context_reg_count)
/* GFX12 */
#define ac_gfx12_opt_set_reg(tracked_regs, reg, reg_enum, value, base_offset) \
do { \
const uint32_t __value = (value); \
if (!BITSET_TEST(tracked_regs->reg_saved_mask, (reg_enum)) || \
tracked_regs->reg_value[(reg_enum)] != __value) { \
ac_gfx12_set_reg((reg), __value, base_offset); \
BITSET_SET(tracked_regs->reg_saved_mask, (reg_enum)); \
tracked_regs->reg_value[(reg_enum)] = __value; \
} \
} while (0)
#define ac_gfx12_opt_set_reg2(tracked_regs, reg, reg_enum, v1, v2, base_offset) \
do { \
static_assert(BITSET_BITWORD(reg_enum) == BITSET_BITWORD(reg_enum + 1), \
"bit range crosses dword boundary"); \
const uint32_t __v1 = (v1); \
const uint32_t __v2 = (v2); \
if (!BITSET_TEST_RANGE_INSIDE_WORD(tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 1, 0x3) || \
tracked_regs->reg_value[(reg_enum)] != __v1 || tracked_regs->reg_value[(reg_enum) + 1] != __v2) { \
ac_gfx12_set_reg((reg), __v1, base_offset); \
ac_gfx12_set_reg((reg) + 4, __v2, base_offset); \
BITSET_SET_RANGE_INSIDE_WORD(tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 1); \
tracked_regs->reg_value[(reg_enum)] = __v1; \
tracked_regs->reg_value[(reg_enum) + 1] = __v2; \
} \
} while (0)
#define ac_gfx12_opt_set_reg4(tracked_regs, reg, reg_enum, v1, v2, v3, v4, base_offset) \
do { \
static_assert(BITSET_BITWORD((reg_enum)) == BITSET_BITWORD((reg_enum) + 3), \
"bit range crosses dword boundary"); \
const uint32_t __v1 = (v1); \
const uint32_t __v2 = (v2); \
const uint32_t __v3 = (v3); \
const uint32_t __v4 = (v4); \
if (!BITSET_TEST_RANGE_INSIDE_WORD(tracked_regs->reg_saved_mask, \
(reg_enum), (reg_enum) + 3, 0xf) || \
tracked_regs->reg_value[(reg_enum)] != __v1 || \
tracked_regs->reg_value[(reg_enum) + 1] != __v2 || \
tracked_regs->reg_value[(reg_enum) + 2] != __v3 || \
tracked_regs->reg_value[(reg_enum) + 3] != __v4) { \
ac_gfx12_set_reg((reg), __v1, (base_offset)); \
ac_gfx12_set_reg((reg) + 4, __v2, (base_offset)); \
ac_gfx12_set_reg((reg) + 8, __v3, (base_offset)); \
ac_gfx12_set_reg((reg) + 12, __v4, (base_offset)); \
BITSET_SET_RANGE_INSIDE_WORD(tracked_regs->reg_saved_mask, \
(reg_enum), (reg_enum) + 3); \
tracked_regs->reg_value[(reg_enum)] = __v1; \
tracked_regs->reg_value[(reg_enum) + 1] = __v2; \
tracked_regs->reg_value[(reg_enum) + 2] = __v3; \
tracked_regs->reg_value[(reg_enum) + 3] = __v4; \
} \
} while (0)
struct ac_preamble_state { struct ac_preamble_state {
uint64_t border_color_va; uint64_t border_color_va;

View file

@ -55,81 +55,29 @@ radeon_check_space(struct radeon_winsys *ws, struct ac_cmdbuf *cs, unsigned need
#define radeon_opt_set_context_reg(reg, reg_enum, value) \ #define radeon_opt_set_context_reg(reg, reg_enum, value) \
do { \ do { \
struct ac_tracked_regs *__tracked_regs = &__rcs->tracked_regs; \ struct ac_tracked_regs *__tracked_regs = &__rcs->tracked_regs; \
const uint32_t __value = (value); \ ac_cmdbuf_opt_set_context_reg(__tracked_regs, reg, reg_enum, value); \
if (!BITSET_TEST(__tracked_regs->reg_saved_mask, (reg_enum)) || \
__tracked_regs->reg_value[(reg_enum)] != __value) { \
radeon_set_context_reg(reg, __value); \
BITSET_SET(__tracked_regs->reg_saved_mask, (reg_enum)); \
__tracked_regs->reg_value[(reg_enum)] = __value; \
__cs->context_roll = true; \
} \
} while (0) } while (0)
#define radeon_opt_set_context_reg2(reg, reg_enum, v1, v2) \ #define radeon_opt_set_context_reg2(reg, reg_enum, v1, v2) \
do { \ do { \
struct ac_tracked_regs *__tracked_regs = &__rcs->tracked_regs; \ struct ac_tracked_regs *__tracked_regs = &__rcs->tracked_regs; \
const uint32_t __v1 = (v1), __v2 = (v2); \ ac_cmdbuf_opt_set_context_reg2(__tracked_regs, reg, reg_enum, v1, v2); \
if (!BITSET_TEST_RANGE_INSIDE_WORD(__tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 1, 0x3) || \
__tracked_regs->reg_value[(reg_enum)] != __v1 || __tracked_regs->reg_value[(reg_enum) + 1] != __v2) { \
radeon_set_context_reg_seq(reg, 2); \
radeon_emit(__v1); \
radeon_emit(__v2); \
BITSET_SET_RANGE_INSIDE_WORD(__tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 1); \
__tracked_regs->reg_value[(reg_enum)] = __v1; \
__tracked_regs->reg_value[(reg_enum) + 1] = __v2; \
__cs->context_roll = true; \
} \
} while (0) } while (0)
#define radeon_opt_set_context_reg3(reg, reg_enum, v1, v2, v3) \ #define radeon_opt_set_context_reg3(reg, reg_enum, v1, v2, v3) \
do { \ do { \
struct ac_tracked_regs *__tracked_regs = &__rcs->tracked_regs; \ struct ac_tracked_regs *__tracked_regs = &__rcs->tracked_regs; \
const uint32_t __v1 = (v1), __v2 = (v2), __v3 = (v3); \ ac_cmdbuf_opt_set_context_reg3(__tracked_regs, reg, reg_enum, v1, v2, v3); \
if (!BITSET_TEST_RANGE_INSIDE_WORD(__tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 2, 0x7) || \
__tracked_regs->reg_value[(reg_enum)] != __v1 || __tracked_regs->reg_value[(reg_enum) + 1] != __v2 || \
__tracked_regs->reg_value[(reg_enum) + 2] != __v3) { \
radeon_set_context_reg_seq(reg, 3); \
radeon_emit(__v1); \
radeon_emit(__v2); \
radeon_emit(__v3); \
BITSET_SET_RANGE_INSIDE_WORD(__tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 2); \
__tracked_regs->reg_value[(reg_enum)] = __v1; \
__tracked_regs->reg_value[(reg_enum) + 1] = __v2; \
__tracked_regs->reg_value[(reg_enum) + 2] = __v3; \
__cs->context_roll = true; \
} \
} while (0) } while (0)
#define radeon_opt_set_context_reg4(reg, reg_enum, v1, v2, v3, v4) \ #define radeon_opt_set_context_reg4(reg, reg_enum, v1, v2, v3, v4) \
do { \ do { \
struct ac_tracked_regs *__tracked_regs = &__rcs->tracked_regs; \ struct ac_tracked_regs *__tracked_regs = &__rcs->tracked_regs; \
const uint32_t __v1 = (v1), __v2 = (v2), __v3 = (v3), __v4 = (v4); \ ac_cmdbuf_opt_set_context_reg4(__tracked_regs, reg, reg_enum, v1, v2, v3, v4); \
if (!BITSET_TEST_RANGE_INSIDE_WORD(__tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 3, 0xf) || \
__tracked_regs->reg_value[(reg_enum)] != __v1 || __tracked_regs->reg_value[(reg_enum) + 1] != __v2 || \
__tracked_regs->reg_value[(reg_enum) + 2] != __v3 || __tracked_regs->reg_value[(reg_enum) + 3] != __v4) { \
radeon_set_context_reg_seq(reg, 4); \
radeon_emit(__v1); \
radeon_emit(__v2); \
radeon_emit(__v3); \
radeon_emit(__v4); \
BITSET_SET_RANGE_INSIDE_WORD(__tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 3); \
__tracked_regs->reg_value[(reg_enum)] = __v1; \
__tracked_regs->reg_value[(reg_enum) + 1] = __v2; \
__tracked_regs->reg_value[(reg_enum) + 2] = __v3; \
__tracked_regs->reg_value[(reg_enum) + 3] = __v4; \
__cs->context_roll = true; \
} \
} while (0) } while (0)
#define radeon_opt_set_context_regn(reg, values, saved_values, num) \ #define radeon_opt_set_context_regn(reg, values, saved_values, num) \
do { \ ac_cmdbuf_opt_set_context_regn(reg, values, saved_values, num)
if (memcmp(values, saved_values, sizeof(uint32_t) * (num))) { \
radeon_set_context_reg_seq(reg, num); \
radeon_emit_array(values, num); \
memcpy(saved_values, values, sizeof(uint32_t) * (num)); \
__cs->context_roll = true; \
} \
} while (0)
/* Packet building helpers for SH registers. */ /* Packet building helpers for SH registers. */
#define radeon_set_sh_reg_seq(reg, num) ac_cmdbuf_set_sh_reg_seq(reg, num) #define radeon_set_sh_reg_seq(reg, num) ac_cmdbuf_set_sh_reg_seq(reg, num)
@ -161,45 +109,22 @@ radeon_check_space(struct radeon_winsys *ws, struct ac_cmdbuf *cs, unsigned need
#define radeon_emit_64bit_pointer(sh_offset, va) ac_cmdbuf_emit_64bit_pointer(sh_offset, va) #define radeon_emit_64bit_pointer(sh_offset, va) ac_cmdbuf_emit_64bit_pointer(sh_offset, va)
/* GFX12 generic packet building helpers for PAIRS packets. Don't use these directly. */
/* Set 1 context register optimally. */
#define __gfx12_opt_set_reg(reg, reg_enum, value, base_offset) \
do { \
struct ac_tracked_regs *__tracked_regs = &__rcs->tracked_regs; \
const uint32_t __value = (value); \
if (!BITSET_TEST(__tracked_regs->reg_saved_mask, (reg_enum)) || \
__tracked_regs->reg_value[(reg_enum)] != __value) { \
ac_gfx12_set_reg((reg), __value, base_offset); \
BITSET_SET(__tracked_regs->reg_saved_mask, (reg_enum)); \
__tracked_regs->reg_value[(reg_enum)] = __value; \
} \
} while (0)
/* Set 2 context registers optimally. */
#define __gfx12_opt_set_reg2(reg, reg_enum, v1, v2, base_offset) \
do { \
struct ac_tracked_regs *__tracked_regs = &__rcs->tracked_regs; \
const uint32_t __v1 = (v1), __v2 = (v2); \
if (!BITSET_TEST_RANGE_INSIDE_WORD(__tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 1, 0x3) || \
__tracked_regs->reg_value[(reg_enum)] != __v1 || __tracked_regs->reg_value[(reg_enum) + 1] != __v2) { \
ac_gfx12_set_reg((reg), __v1, base_offset); \
ac_gfx12_set_reg((reg) + 4, __v2, base_offset); \
BITSET_SET_RANGE_INSIDE_WORD(__tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 1); \
__tracked_regs->reg_value[(reg_enum)] = __v1; \
__tracked_regs->reg_value[(reg_enum) + 1] = __v2; \
} \
} while (0)
/* GFX12 packet building helpers for PAIRS packets. */ /* GFX12 packet building helpers for PAIRS packets. */
#define gfx12_begin_context_regs() ac_gfx12_begin_context_regs() #define gfx12_begin_context_regs() ac_gfx12_begin_context_regs()
#define gfx12_set_context_reg(reg, value) ac_gfx12_set_context_reg(reg, value) #define gfx12_set_context_reg(reg, value) ac_gfx12_set_context_reg(reg, value)
#define gfx12_opt_set_context_reg(reg, reg_enum, value) __gfx12_opt_set_reg(reg, reg_enum, value, SI_CONTEXT_REG_OFFSET) #define gfx12_opt_set_context_reg(reg, reg_enum, value) \
do { \
struct ac_tracked_regs *__tracked_regs = &__rcs->tracked_regs; \
ac_gfx12_opt_set_reg(__tracked_regs, reg, reg_enum, value, SI_CONTEXT_REG_OFFSET); \
} while (0)
#define gfx12_opt_set_context_reg2(reg, reg_enum, v1, v2) \ #define gfx12_opt_set_context_reg2(reg, reg_enum, v1, v2) \
__gfx12_opt_set_reg2(reg, reg_enum, v1, v2, SI_CONTEXT_REG_OFFSET) do { \
struct ac_tracked_regs *__tracked_regs = &__rcs->tracked_regs; \
ac_gfx12_opt_set_reg2(__tracked_regs, reg, reg_enum, v1, v2, SI_CONTEXT_REG_OFFSET); \
} while (0)
#define gfx12_end_context_regs() ac_gfx12_end_context_regs() #define gfx12_end_context_regs() ac_gfx12_end_context_regs()
@ -216,37 +141,17 @@ radeon_check_space(struct radeon_winsys *ws, struct ac_cmdbuf *cs, unsigned need
#define gfx11_set_context_reg(reg, value) ac_gfx11_set_context_reg(reg, value) #define gfx11_set_context_reg(reg, value) ac_gfx11_set_context_reg(reg, value)
#define gfx11_end_packed_context_regs() ac_gfx11_end_packed_context_regs() #define gfx11_end_packed_context_regs() ac_gfx11_end_packed_context_regs()
#define gfx11_opt_push_reg(reg, reg_enum, value, prefix_name, buffer, reg_count) \
do { \
struct ac_tracked_regs *__tracked_regs = &__rcs->tracked_regs; \
const uint32_t __value = (value); \
if (!BITSET_TEST(__tracked_regs->reg_saved_mask, (reg_enum)) || \
__tracked_regs->reg_value[(reg_enum)] != __value) { \
ac_gfx11_push_reg((reg), __value, prefix_name, buffer, reg_count); \
BITSET_SET(__tracked_regs->reg_saved_mask, (reg_enum)); \
__tracked_regs->reg_value[(reg_enum)] = __value; \
} \
} while (0)
#define gfx11_opt_push_reg2(reg, reg_enum, v1, v2, prefix_name, buffer, reg_count) \
do { \
struct ac_tracked_regs *__tracked_regs = &__rcs->tracked_regs; \
const uint32_t __v1 = (v1), __v2 = (v2); \
if (!BITSET_TEST_RANGE_INSIDE_WORD(__tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 1, 0x3) || \
__tracked_regs->reg_value[(reg_enum)] != __v1 || __tracked_regs->reg_value[(reg_enum) + 1] != __v2) { \
ac_gfx11_push_reg((reg), __v1, prefix_name, buffer, reg_count); \
ac_gfx11_push_reg((reg) + 4, __v2, prefix_name, buffer, reg_count); \
BITSET_SET_RANGE_INSIDE_WORD(__tracked_regs->reg_saved_mask, (reg_enum), (reg_enum) + 1); \
__tracked_regs->reg_value[(reg_enum)] = __v1; \
__tracked_regs->reg_value[(reg_enum) + 1] = __v2; \
} \
} while (0)
#define gfx11_opt_set_context_reg(reg, reg_enum, value) \ #define gfx11_opt_set_context_reg(reg, reg_enum, value) \
gfx11_opt_push_reg(reg, reg_enum, value, SI_CONTEXT, __cs_context_regs, __cs_context_reg_count) do { \
struct ac_tracked_regs *__tracked_regs = &__rcs->tracked_regs; \
ac_gfx11_opt_set_context_reg(__tracked_regs, reg, reg_enum, value); \
} while (0)
#define gfx11_opt_set_context_reg2(reg, reg_enum, v1, v2) \ #define gfx11_opt_set_context_reg2(reg, reg_enum, v1, v2) \
gfx11_opt_push_reg2(reg, reg_enum, v1, v2, SI_CONTEXT, __cs_context_regs, __cs_context_reg_count) do { \
struct ac_tracked_regs *__tracked_regs = &__rcs->tracked_regs; \
ac_gfx11_opt_set_context_reg2(__tracked_regs, reg, reg_enum, v1, v2); \
} while (0)
ALWAYS_INLINE static void ALWAYS_INLINE static void
radv_gfx12_emit_buffered_regs(const struct radv_device *device, struct radv_cmd_stream *cs) radv_gfx12_emit_buffered_regs(const struct radv_device *device, struct radv_cmd_stream *cs)

View file

@ -288,39 +288,13 @@
/* GFX11 generic packet building helpers for buffered SH registers. Don't use these directly. */ /* GFX11 generic packet building helpers for buffered SH registers. Don't use these directly. */
#define gfx11_opt_push_reg(reg, reg_enum, value, prefix_name, buffer, reg_count) do { \ #define gfx11_opt_push_reg(reg, reg_enum, value, prefix_name, buffer, reg_count) do { \
unsigned __value = value; \ struct ac_tracked_regs *__tracked_regs = &sctx->tracked_regs; \
if (!BITSET_TEST(sctx->tracked_regs.reg_saved_mask, (reg_enum)) || \ ac_gfx11_opt_push_reg(__tracked_regs, reg, reg_enum, value, prefix_name, buffer, reg_count); \
sctx->tracked_regs.reg_value[reg_enum] != __value) { \
ac_gfx11_push_reg(reg, __value, prefix_name, buffer, reg_count); \
BITSET_SET(sctx->tracked_regs.reg_saved_mask, (reg_enum)); \
sctx->tracked_regs.reg_value[reg_enum] = __value; \
} \
} while (0) } while (0)
#define gfx11_opt_push_reg4(reg, reg_enum, v1, v2, v3, v4, prefix_name, buffer, reg_count) do { \ #define gfx11_opt_push_reg4(reg, reg_enum, v1, v2, v3, v4, prefix_name, buffer, reg_count) do { \
static_assert(BITSET_BITWORD((reg_enum)) == BITSET_BITWORD((reg_enum) + 3), \ struct ac_tracked_regs *__tracked_regs = &sctx->tracked_regs; \
"bit range crosses dword boundary"); \ ac_gfx11_opt_push_reg4(__tracked_regs, reg, reg_enum, v1, v2, v3, v4, prefix_name, buffer, reg_count); \
unsigned __v1 = (v1); \
unsigned __v2 = (v2); \
unsigned __v3 = (v3); \
unsigned __v4 = (v4); \
if (!BITSET_TEST_RANGE_INSIDE_WORD(sctx->tracked_regs.reg_saved_mask, \
(reg_enum), (reg_enum) + 3, 0xf) || \
sctx->tracked_regs.reg_value[(reg_enum)] != __v1 || \
sctx->tracked_regs.reg_value[(reg_enum) + 1] != __v2 || \
sctx->tracked_regs.reg_value[(reg_enum) + 2] != __v3 || \
sctx->tracked_regs.reg_value[(reg_enum) + 3] != __v4) { \
ac_gfx11_push_reg((reg), __v1, prefix_name, buffer, reg_count); \
ac_gfx11_push_reg((reg) + 4, __v2, prefix_name, buffer, reg_count); \
ac_gfx11_push_reg((reg) + 8, __v3, prefix_name, buffer, reg_count); \
ac_gfx11_push_reg((reg) + 12, __v4, prefix_name, buffer, reg_count); \
BITSET_SET_RANGE_INSIDE_WORD(sctx->tracked_regs.reg_saved_mask, \
(reg_enum), (reg_enum) + 3); \
sctx->tracked_regs.reg_value[(reg_enum)] = __v1; \
sctx->tracked_regs.reg_value[(reg_enum) + 1] = __v2; \
sctx->tracked_regs.reg_value[(reg_enum) + 2] = __v3; \
sctx->tracked_regs.reg_value[(reg_enum) + 3] = __v4; \
} \
} while (0) } while (0)
/* GFX11 packet building helpers for buffered SH registers. */ /* GFX11 packet building helpers for buffered SH registers. */
@ -362,39 +336,6 @@
/* GFX12 generic packet building helpers for PAIRS packets. Don't use these directly. */ /* GFX12 generic packet building helpers for PAIRS packets. Don't use these directly. */
#define gfx12_opt_set_reg(reg, reg_enum, value, base_offset) do { \
unsigned __value = value; \
if (!BITSET_TEST(sctx->tracked_regs.reg_saved_mask, (reg_enum)) || \
sctx->tracked_regs.reg_value[reg_enum] != __value) { \
ac_gfx12_set_reg(reg, __value, base_offset); \
BITSET_SET(sctx->tracked_regs.reg_saved_mask, (reg_enum)); \
sctx->tracked_regs.reg_value[reg_enum] = __value; \
} \
} while (0)
#define gfx12_opt_set_reg4(reg, reg_enum, v1, v2, v3, v4, base_offset) do { \
static_assert(BITSET_BITWORD((reg_enum)) == BITSET_BITWORD((reg_enum) + 3), \
"bit range crosses dword boundary"); \
unsigned __v1 = (v1), __v2 = (v2), __v3 = (v3), __v4 = (v4); \
if (!BITSET_TEST_RANGE_INSIDE_WORD(sctx->tracked_regs.reg_saved_mask, \
(reg_enum), (reg_enum) + 3, 0xf) || \
sctx->tracked_regs.reg_value[(reg_enum)] != __v1 || \
sctx->tracked_regs.reg_value[(reg_enum) + 1] != __v2 || \
sctx->tracked_regs.reg_value[(reg_enum) + 2] != __v3 || \
sctx->tracked_regs.reg_value[(reg_enum) + 3] != __v4) { \
ac_gfx12_set_reg((reg), __v1, (base_offset)); \
ac_gfx12_set_reg((reg) + 4, __v2, (base_offset)); \
ac_gfx12_set_reg((reg) + 8, __v3, (base_offset)); \
ac_gfx12_set_reg((reg) + 12, __v4, (base_offset)); \
BITSET_SET_RANGE_INSIDE_WORD(sctx->tracked_regs.reg_saved_mask, \
(reg_enum), (reg_enum) + 3); \
sctx->tracked_regs.reg_value[(reg_enum)] = __v1; \
sctx->tracked_regs.reg_value[(reg_enum) + 1] = __v2; \
sctx->tracked_regs.reg_value[(reg_enum) + 2] = __v3; \
sctx->tracked_regs.reg_value[(reg_enum) + 3] = __v4; \
} \
} while (0)
#define gfx12_opt_push_reg(reg, reg_enum, value, type) do { \ #define gfx12_opt_push_reg(reg, reg_enum, value, type) do { \
unsigned __value = value; \ unsigned __value = value; \
unsigned __reg_enum = reg_enum; \ unsigned __reg_enum = reg_enum; \
@ -413,11 +354,15 @@
#define gfx12_set_context_reg(reg, value) \ #define gfx12_set_context_reg(reg, value) \
ac_gfx12_set_context_reg(reg, value) ac_gfx12_set_context_reg(reg, value)
#define gfx12_opt_set_context_reg(reg, reg_enum, value) \ #define gfx12_opt_set_context_reg(reg, reg_enum, value) do { \
gfx12_opt_set_reg(reg, reg_enum, value, SI_CONTEXT_REG_OFFSET) struct ac_tracked_regs *__tracked_regs = &sctx->tracked_regs; \
ac_gfx12_opt_set_reg(__tracked_regs, reg, reg_enum, value, SI_CONTEXT_REG_OFFSET); \
} while (0)
#define gfx12_opt_set_context_reg4(reg, reg_enum, v1, v2, v3, v4) \ #define gfx12_opt_set_context_reg4(reg, reg_enum, v1, v2, v3, v4) do { \
gfx12_opt_set_reg4(reg, reg_enum, v1, v2, v3, v4, SI_CONTEXT_REG_OFFSET) struct ac_tracked_regs *__tracked_regs = &sctx->tracked_regs; \
ac_gfx12_opt_set_reg4(__tracked_regs, reg, reg_enum, v1, v2, v3, v4, SI_CONTEXT_REG_OFFSET); \
} while (0)
#define gfx12_end_context_regs() \ #define gfx12_end_context_regs() \
ac_gfx12_end_context_regs() ac_gfx12_end_context_regs()