tu,freedreno: Add pkt_field_{get,set} helper macro
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

It's very common needing to extract or overwrite a certain field
in an already packed register value, so add macros to do that
instead of manually doing that each time.

Signed-off-by: Karmjit Mahil <karmjit.mahil@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35088>
This commit is contained in:
Karmjit Mahil 2025-05-21 11:33:28 +01:00
parent 398f14ca3d
commit 688d8217a5
9 changed files with 82 additions and 88 deletions

View file

@ -115,6 +115,11 @@ pm4_calc_odd_parity_bit(unsigned val)
#define cp_type7_opcode(pkt) (((pkt) >> 16) & 0x7F)
#define type7_pkt_size(pkt) ((pkt)&0x3FFF)
#define pkt_field_get(reg_field, pkt) \
(((pkt)&CONCAT2(reg_field, __MASK)) >> CONCAT2(reg_field, __SHIFT))
#define pkt_field_set(reg_field, pkt, new_val) \
(((pkt) & ~CONCAT2(reg_field, __MASK)) | reg_field(new_val))
#ifdef __cplusplus
} /* end of extern "C" */
#endif

View file

@ -323,11 +323,9 @@ decompile_domain(uint32_t pkt, uint32_t *dwords, uint32_t sizedwords,
if (pkt == CP_LOAD_STATE6_FRAG || pkt == CP_LOAD_STATE6_GEOM) {
enum a6xx_state_type state_type =
(dwords[0] & CP_LOAD_STATE6_0_STATE_TYPE__MASK) >>
CP_LOAD_STATE6_0_STATE_TYPE__SHIFT;
pkt_field_get(CP_LOAD_STATE6_0_STATE_TYPE, dwords[0]);
enum a6xx_state_src state_src =
(dwords[0] & CP_LOAD_STATE6_0_STATE_SRC__MASK) >>
CP_LOAD_STATE6_0_STATE_SRC__SHIFT;
pkt_field_get(CP_LOAD_STATE6_0_STATE_SRC, dwords[0]);
/* TODO: decompile all other state */
if (state_type == ST6_SHADER && state_src == SS6_INDIRECT) {

View file

@ -276,14 +276,13 @@ r2d_src(struct tu_cmd_buffer *cmd,
if (filter != VK_FILTER_NEAREST)
src_info |= A6XX_SP_PS_2D_SRC_INFO_FILTER;
enum a6xx_format fmt = (enum a6xx_format)(
src_info & A6XX_SP_PS_2D_SRC_INFO_COLOR_FORMAT__MASK);
enum a6xx_format fmt = (enum a6xx_format) pkt_field_get(
A6XX_SP_PS_2D_SRC_INFO_COLOR_FORMAT, src_info);
enum pipe_format src_format = iview->format;
fixup_src_format(&src_format, dst_format, &fmt);
src_info =
(src_info & ~A6XX_SP_PS_2D_SRC_INFO_COLOR_FORMAT__MASK) |
A6XX_SP_PS_2D_SRC_INFO_COLOR_FORMAT(fmt);
pkt_field_set(A6XX_SP_PS_2D_SRC_INFO_COLOR_FORMAT, src_info, fmt);
tu_cs_emit_pkt4(cs, SP_PS_2D_SRC_INFO(CHIP,).reg, 5);
tu_cs_emit(cs, src_info);
@ -397,13 +396,12 @@ r2d_dst(struct tu_cs *cs, const struct fdl6_view *iview, uint32_t layer,
enum pipe_format src_format)
{
uint32_t dst_info = iview->RB_2D_DST_INFO;
enum a6xx_format fmt =
(enum a6xx_format)(dst_info & A6XX_RB_2D_DST_INFO_COLOR_FORMAT__MASK);
enum a6xx_format fmt = (enum a6xx_format) pkt_field_get(
A6XX_RB_2D_DST_INFO_COLOR_FORMAT, dst_info);
enum pipe_format dst_format = iview->format;
fixup_dst_format(src_format, &dst_format, &fmt);
dst_info =
(dst_info & ~A6XX_RB_2D_DST_INFO_COLOR_FORMAT__MASK) | fmt;
dst_info = pkt_field_set(A6XX_RB_2D_DST_INFO_COLOR_FORMAT, dst_info, fmt);
tu_cs_emit_pkt4(cs, REG_A6XX_RB_2D_DST_INFO, 4);
tu_cs_emit(cs, dst_info);
tu_cs_image_ref_2d<CHIP>(cs, iview, layer, false);
@ -1174,12 +1172,11 @@ r3d_src(struct tu_cmd_buffer *cmd,
uint32_t desc[A6XX_TEX_CONST_DWORDS];
memcpy(desc, iview->descriptor, sizeof(desc));
enum a6xx_format fmt = (enum a6xx_format)(
(desc[0] & A6XX_TEX_CONST_0_FMT__MASK) >> A6XX_TEX_CONST_0_FMT__SHIFT);
enum a6xx_format fmt =
(enum a6xx_format) pkt_field_get(A6XX_TEX_CONST_0_FMT, desc[0]);
enum pipe_format src_format = iview->format;
fixup_src_format(&src_format, dst_format, &fmt);
desc[0] = (desc[0] & ~A6XX_TEX_CONST_0_FMT__MASK) |
A6XX_TEX_CONST_0_FMT(fmt);
desc[0] = pkt_field_set(A6XX_TEX_CONST_0_FMT, desc[0], fmt);
r3d_src_common(cmd, cs, desc,
iview->layer_size * layer,
@ -1246,8 +1243,9 @@ r3d_src_depth(struct tu_cmd_buffer *cmd,
desc[2] =
A6XX_TEX_CONST_2_PITCH(iview->depth_pitch) |
A6XX_TEX_CONST_2_TYPE(A6XX_TEX_2D);
desc[3] = A6XX_TEX_CONST_3_ARRAY_PITCH(iview->depth_layer_size) |
(iview->view.descriptor[3] & ~A6XX_TEX_CONST_3_ARRAY_PITCH__MASK);
desc[3] =
pkt_field_set(A6XX_TEX_CONST_3_ARRAY_PITCH, iview->view.descriptor[3],
iview->depth_layer_size);
desc[4] = va;
desc[5] = va >> 32;
@ -1305,11 +1303,13 @@ r3d_src_gmem_load(struct tu_cmd_buffer *cmd,
if (format == PIPE_FORMAT_X24S8_UINT ||
format == PIPE_FORMAT_Z24X8_UNORM ||
format == PIPE_FORMAT_Z24_UNORM_S8_UINT) {
desc[0] &= ~A6XX_TEX_CONST_0_FMT__MASK;
enum a6xx_format tex_format;
if (iview->view.ubwc_enabled)
desc[0] |= A6XX_TEX_CONST_0_FMT(FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8);
tex_format = FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8;
else
desc[0] |= A6XX_TEX_CONST_0_FMT(FMT6_8_8_8_8_UNORM);
tex_format = FMT6_8_8_8_8_UNORM;
desc[0] = pkt_field_set(A6XX_TEX_CONST_0_FMT, desc[0], tex_format);
}
/* When loading/storing GMEM we always load the full image and don't do any
@ -1359,24 +1359,21 @@ r3d_src_gmem(struct tu_cmd_buffer *cmd,
A6XX_TEX_CONST_0_SWIZ_W(A6XX_TEX_W);
/* patched for gmem */
desc[0] &= ~A6XX_TEX_CONST_0_TILE_MODE__MASK;
desc[0] = pkt_field_set(A6XX_TEX_CONST_0_TILE_MODE, desc[0], TILE6_2);
if (!iview->view.is_mutable)
desc[0] &= ~A6XX_TEX_CONST_0_SWAP__MASK;
desc[0] |= A6XX_TEX_CONST_0_TILE_MODE(TILE6_2);
desc[0] = pkt_field_set(A6XX_TEX_CONST_0_SWAP, desc[0], WZYX);
/* If FDM offset is used, the last row and column extend beyond the
* framebuffer but are shifted over when storing. Expand the width and
* height to account for that.
*/
if (tu_enable_fdm_offset(cmd)) {
uint32_t width = desc[1] & A6XX_TEX_CONST_1_WIDTH__MASK;
uint32_t height = (desc[1] & A6XX_TEX_CONST_1_HEIGHT__MASK) >>
A6XX_TEX_CONST_1_HEIGHT__SHIFT;
uint32_t width = pkt_field_get(A6XX_TEX_CONST_1_WIDTH, desc[1]);
uint32_t height = pkt_field_get(A6XX_TEX_CONST_1_HEIGHT, desc[1]);
width += cmd->state.tiling->tile0.width;
height += cmd->state.tiling->tile0.height;
desc[1] = (desc[1] & ~(A6XX_TEX_CONST_1_WIDTH__MASK |
A6XX_TEX_CONST_1_HEIGHT__MASK)) |
A6XX_TEX_CONST_1_WIDTH(width) | A6XX_TEX_CONST_1_HEIGHT(height);
desc[1] = pkt_field_set(A6XX_TEX_CONST_1_WIDTH, desc[1], width);
desc[1] = pkt_field_set(A6XX_TEX_CONST_1_HEIGHT, desc[1], height);
}
desc[2] =
@ -1398,13 +1395,12 @@ r3d_dst(struct tu_cs *cs, const struct fdl6_view *iview, uint32_t layer,
{
uint32_t mrt_buf_info = iview->RB_MRT_BUF_INFO;
enum a6xx_format fmt = (enum a6xx_format)(
mrt_buf_info & A6XX_RB_MRT_BUF_INFO_COLOR_FORMAT__MASK);
enum a6xx_format fmt = (enum a6xx_format) pkt_field_get(
A6XX_RB_MRT_BUF_INFO_COLOR_FORMAT, mrt_buf_info);
enum pipe_format dst_format = iview->format;
fixup_dst_format(src_format, &dst_format, &fmt);
mrt_buf_info =
(mrt_buf_info & ~A6XX_RB_MRT_BUF_INFO_COLOR_FORMAT__MASK) |
A6XX_RB_MRT_BUF_INFO_COLOR_FORMAT(fmt);
pkt_field_set(A6XX_RB_MRT_BUF_INFO_COLOR_FORMAT, mrt_buf_info, fmt);
tu_cs_emit_regs(cs,
RB_MRT_BUF_INFO(CHIP, 0, .dword = mrt_buf_info),
@ -1512,8 +1508,8 @@ r3d_dst_gmem(struct tu_cmd_buffer *cmd, struct tu_cs *cs,
A6XX_RB_MRT_BASE(0, 0),
A6XX_RB_MRT_BASE_GMEM(0, gmem_offset));
enum a6xx_format color_format =
(enum a6xx_format)(RB_MRT_BUF_INFO & A6XX_RB_MRT_BUF_INFO_COLOR_FORMAT__MASK);
enum a6xx_format color_format = (enum a6xx_format) pkt_field_get(
A6XX_RB_MRT_BUF_INFO_COLOR_FORMAT, RB_MRT_BUF_INFO);
tu_cs_emit_regs(cs,
A6XX_GRAS_LRZ_MRT_BUF_INFO_0(.color_format = color_format));

View file

@ -2086,16 +2086,12 @@ tu_emit_input_attachments(struct tu_cmd_buffer *cmd,
* with how it is sampled in shader.
*/
enum a6xx_tex_type tex_type =
(enum a6xx_tex_type)((dst[2] & A6XX_TEX_CONST_2_TYPE__MASK) >>
A6XX_TEX_CONST_2_TYPE__SHIFT);
(enum a6xx_tex_type) pkt_field_get(A6XX_TEX_CONST_2_TYPE, dst[2]);
if (tex_type == A6XX_TEX_CUBE) {
dst[2] &= ~A6XX_TEX_CONST_2_TYPE__MASK;
dst[2] |= A6XX_TEX_CONST_2_TYPE(A6XX_TEX_2D);
dst[2] = pkt_field_set(A6XX_TEX_CONST_2_TYPE, dst[2], A6XX_TEX_2D);
uint32_t depth = (dst[5] & A6XX_TEX_CONST_5_DEPTH__MASK) >>
A6XX_TEX_CONST_5_DEPTH__SHIFT;
dst[5] &= ~A6XX_TEX_CONST_5_DEPTH__MASK;
dst[5] |= A6XX_TEX_CONST_5_DEPTH(depth * 6);
uint32_t depth = pkt_field_get(A6XX_TEX_CONST_5_DEPTH, dst[5]);
dst[5] = pkt_field_set(A6XX_TEX_CONST_5_DEPTH, dst[5], depth * 6);
}
if (i % 2 == 1 && att->format == VK_FORMAT_D24_UNORM_S8_UINT) {
@ -2125,10 +2121,10 @@ tu_emit_input_attachments(struct tu_cmd_buffer *cmd,
}
if (i % 2 == 1 && att->format == VK_FORMAT_D32_SFLOAT_S8_UINT) {
dst[0] &= ~A6XX_TEX_CONST_0_FMT__MASK;
dst[0] |= A6XX_TEX_CONST_0_FMT(FMT6_8_UINT);
dst[2] &= ~(A6XX_TEX_CONST_2_PITCHALIGN__MASK | A6XX_TEX_CONST_2_PITCH__MASK);
dst[2] |= A6XX_TEX_CONST_2_PITCH(iview->stencil_pitch);
dst[0] = pkt_field_set(A6XX_TEX_CONST_0_FMT, dst[0], FMT6_8_UINT);
dst[2] = pkt_field_set(A6XX_TEX_CONST_2_PITCHALIGN, dst[2], 0);
dst[2] = pkt_field_set(A6XX_TEX_CONST_2_PITCH, dst[2],
iview->stencil_pitch);
dst[3] = 0;
dst[4] = iview->stencil_base_addr;
dst[5] = (dst[5] & 0xffff) | iview->stencil_base_addr >> 32;
@ -2141,24 +2137,21 @@ tu_emit_input_attachments(struct tu_cmd_buffer *cmd,
continue;
/* patched for gmem */
dst[0] &= ~A6XX_TEX_CONST_0_TILE_MODE__MASK;
dst[0] = pkt_field_set(A6XX_TEX_CONST_0_TILE_MODE, dst[0], TILE6_2);
if (!iview->view.is_mutable)
dst[0] &= ~A6XX_TEX_CONST_0_SWAP__MASK;
dst[0] |= A6XX_TEX_CONST_0_TILE_MODE(TILE6_2);
dst[0] = pkt_field_set(A6XX_TEX_CONST_0_SWAP, dst[0], WZYX);
/* If FDM offset is used, the last row and column extend beyond the
* framebuffer but are shifted over when storing. Expand the width and
* height to account for that.
*/
if (tu_enable_fdm_offset(cmd)) {
uint32_t width = dst[1] & A6XX_TEX_CONST_1_WIDTH__MASK;
uint32_t height = (dst[1] & A6XX_TEX_CONST_1_HEIGHT__MASK) >>
A6XX_TEX_CONST_1_HEIGHT__SHIFT;
uint32_t width = pkt_field_get(A6XX_TEX_CONST_1_WIDTH, dst[1]);
uint32_t height = pkt_field_get(A6XX_TEX_CONST_1_HEIGHT, dst[1]);
width += cmd->state.tiling->tile0.width;
height += cmd->state.tiling->tile0.height;
dst[1] = (dst[1] & ~(A6XX_TEX_CONST_1_WIDTH__MASK |
A6XX_TEX_CONST_1_HEIGHT__MASK)) |
A6XX_TEX_CONST_1_WIDTH(width) | A6XX_TEX_CONST_1_HEIGHT(height);
dst[1] = pkt_field_set(A6XX_TEX_CONST_1_WIDTH, dst[1], width);
dst[1] = pkt_field_set(A6XX_TEX_CONST_1_HEIGHT, dst[1], height);
}
dst[2] =
@ -3636,17 +3629,14 @@ tu_bind_descriptor_sets(struct tu_cmd_buffer *cmd,
i++, dst_desc += A6XX_TEX_CONST_DWORDS) {
/* Note: A6XX_TEX_CONST_5_DEPTH is always 0 */
uint64_t va = dst_desc[4] | ((uint64_t)dst_desc[5] << 32);
uint32_t desc_offset =
(dst_desc[2] &
A6XX_TEX_CONST_2_STARTOFFSETTEXELS__MASK) >>
A6XX_TEX_CONST_2_STARTOFFSETTEXELS__SHIFT;
uint32_t desc_offset = pkt_field_get(
A6XX_TEX_CONST_2_STARTOFFSETTEXELS, dst_desc[2]);
/* Use descriptor's format to determine the shift amount
* that's to be used on the offset value.
*/
uint32_t format = (dst_desc[0] &
A6XX_TEX_CONST_0_FMT__MASK) >>
A6XX_TEX_CONST_0_FMT__SHIFT;
uint32_t format =
pkt_field_get(A6XX_TEX_CONST_0_FMT, dst_desc[0]);
unsigned offset_shift;
switch (format) {
case FMT6_16_UINT:
@ -3668,8 +3658,8 @@ tu_bind_descriptor_sets(struct tu_cmd_buffer *cmd,
dst_desc[4] = va;
dst_desc[5] = va >> 32;
dst_desc[2] =
(dst_desc[2] & ~A6XX_TEX_CONST_2_STARTOFFSETTEXELS__MASK) |
A6XX_TEX_CONST_2_STARTOFFSETTEXELS(new_offset);
pkt_field_set(A6XX_TEX_CONST_2_STARTOFFSETTEXELS,
dst_desc[2], new_offset);
}
}

View file

@ -451,8 +451,7 @@ tu_cond_exec_start(struct tu_cs *cs, uint32_t cond_flags)
assert(cs->cond_stack_depth < TU_COND_EXEC_STACK_SIZE);
ASSERTED enum compare_mode mode =
(enum compare_mode)((cond_flags & CP_COND_REG_EXEC_0_MODE__MASK) >>
CP_COND_REG_EXEC_0_MODE__SHIFT);
(enum compare_mode) pkt_field_get(CP_COND_REG_EXEC_0_MODE, cond_flags);
assert(mode == PRED_TEST || mode == RENDER_MODE || mode == THREAD_MODE);
tu_cs_emit_pkt7(cs, CP_COND_REG_EXEC, 2);

View file

@ -15,11 +15,11 @@
#define TU_MAX_PLANE_COUNT 3
#define tu_fdl_view_stencil(view, x) \
(((view)->x & ~A6XX_##x##_COLOR_FORMAT__MASK) | A6XX_##x##_COLOR_FORMAT(FMT6_8_UINT))
#define tu_fdl_view_stencil(view, x) \
pkt_field_set(A6XX_##x##_COLOR_FORMAT, (view)->x, FMT6_8_UINT)
#define tu_fdl_view_depth(view, x) \
(((view)->x & ~A6XX_##x##_COLOR_FORMAT__MASK) | A6XX_##x##_COLOR_FORMAT(FMT6_32_FLOAT))
#define tu_fdl_view_depth(view, x) \
pkt_field_set(A6XX_##x##_COLOR_FORMAT, (view)->x, FMT6_32_FLOAT)
#define tu_image_view_stencil(iview, x) \
tu_fdl_view_stencil(&iview->view, x)

View file

@ -135,7 +135,6 @@ tu_DestroySampler(VkDevice _device,
{
VK_FROM_HANDLE(tu_device, device, _device);
VK_FROM_HANDLE(tu_sampler, sampler, _sampler);
uint32_t border_color;
if (!sampler)
return;
@ -143,7 +142,8 @@ tu_DestroySampler(VkDevice _device,
bool fast_border_color =
(sampler->descriptor[2] & A6XX_TEX_SAMP_2_FASTBORDERCOLOREN) != 0;
if (!fast_border_color) {
border_color = (sampler->descriptor[2] & A6XX_TEX_SAMP_2_BCOLOR__MASK) >> A6XX_TEX_SAMP_2_BCOLOR__SHIFT;
const uint32_t border_color =
pkt_field_get(A6XX_TEX_SAMP_2_BCOLOR, sampler->descriptor[2]);
/* if the sampler had a custom border color, free it. TODO: no lock */
mtx_lock(&device->mutex);
assert(!BITSET_TEST(device->custom_border_color, border_color));

View file

@ -763,8 +763,10 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
control |= A3XX_RB_MRT_CONTROL_ROP_CODE(ROP_COPY);
}
if (format == PIPE_FORMAT_NONE)
control &= ~A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE__MASK;
if (format == PIPE_FORMAT_NONE) {
control =
pkt_field_set(A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE, control, 0);
}
if (!has_alpha) {
control &= ~A3XX_RB_MRT_CONTROL_BLEND2;

View file

@ -8,6 +8,7 @@
#include "pipe/p_state.h"
#include "util/format/u_format.h"
#include "util/macros.h"
#include "util/u_helpers.h"
#include "util/u_memory.h"
#include "util/u_string.h"
@ -256,54 +257,57 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
/* Remap integer formats as unorm (will be fixed up in shader) */
if (util_format_is_pure_integer(view->base.format)) {
texconst0 &= ~A4XX_TEX_CONST_0_FMT__MASK;
enum a4xx_tex_fmt new_tex_fmt;
switch (fd4_pipe2tex(view->base.format)) {
case TFMT4_8_8_8_8_UINT:
case TFMT4_8_8_8_8_SINT:
texconst0 |= A4XX_TEX_CONST_0_FMT(TFMT4_8_8_8_8_UNORM);
new_tex_fmt = TFMT4_8_8_8_8_UNORM;
break;
case TFMT4_8_8_UINT:
case TFMT4_8_8_SINT:
texconst0 |= A4XX_TEX_CONST_0_FMT(TFMT4_8_8_UNORM);
new_tex_fmt = TFMT4_8_8_UNORM;
break;
case TFMT4_8_UINT:
case TFMT4_8_SINT:
texconst0 |= A4XX_TEX_CONST_0_FMT(TFMT4_8_UNORM);
new_tex_fmt = TFMT4_8_UNORM;
break;
case TFMT4_16_16_16_16_UINT:
case TFMT4_16_16_16_16_SINT:
texconst0 |= A4XX_TEX_CONST_0_FMT(TFMT4_16_16_16_16_UNORM);
new_tex_fmt = TFMT4_16_16_16_16_UNORM;
break;
case TFMT4_16_16_UINT:
case TFMT4_16_16_SINT:
texconst0 |= A4XX_TEX_CONST_0_FMT(TFMT4_16_16_UNORM);
new_tex_fmt = TFMT4_16_16_UNORM;
break;
case TFMT4_16_UINT:
case TFMT4_16_SINT:
texconst0 |= A4XX_TEX_CONST_0_FMT(TFMT4_16_UNORM);
new_tex_fmt = TFMT4_16_UNORM;
break;
case TFMT4_32_32_32_32_UINT:
case TFMT4_32_32_32_32_SINT:
texconst0 |= A4XX_TEX_CONST_0_FMT(TFMT4_32_32_32_32_FLOAT);
new_tex_fmt = TFMT4_32_32_32_32_FLOAT;
break;
case TFMT4_32_32_UINT:
case TFMT4_32_32_SINT:
texconst0 |= A4XX_TEX_CONST_0_FMT(TFMT4_32_32_FLOAT);
new_tex_fmt = TFMT4_32_32_FLOAT;
break;
case TFMT4_32_UINT:
case TFMT4_32_SINT:
texconst0 |= A4XX_TEX_CONST_0_FMT(TFMT4_32_FLOAT);
new_tex_fmt = TFMT4_32_FLOAT;
break;
case TFMT4_10_10_10_2_UINT:
texconst0 |= A4XX_TEX_CONST_0_FMT(TFMT4_10_10_10_2_UNORM);
new_tex_fmt = TFMT4_10_10_10_2_UNORM;
break;
default:
assert(0);
unreachable();
}
texconst0 =
pkt_field_set(A4XX_TEX_CONST_0_FMT, texconst0, new_tex_fmt);
}
OUT_RING(ring, texconst0);