From 9caa563bc928f13a3e8a831a2095bc41c25f9990 Mon Sep 17 00:00:00 2001 From: Radu Costas Date: Fri, 20 Feb 2026 12:16:04 +0200 Subject: [PATCH] pvr, pco: Commonize texture packing code Format extraction moved to separate function Removed some magic numbers Signed-off-by: Radu Costas Reviewed-by: Simon Perretta Part-of: --- src/imagination/common/pvr_iface.h | 13 +++ src/imagination/pco/pco.c | 76 +++++++++++++ src/imagination/pco/pco.h | 5 + src/imagination/pco/pco_nir_tex.c | 119 +++----------------- src/imagination/vulkan/pvr_arch_tex_state.c | 80 ++----------- 5 files changed, 118 insertions(+), 175 deletions(-) diff --git a/src/imagination/common/pvr_iface.h b/src/imagination/common/pvr_iface.h index d28a155474d..5d28d42a4ed 100644 --- a/src/imagination/common/pvr_iface.h +++ b/src/imagination/common/pvr_iface.h @@ -128,4 +128,17 @@ enum pvr_idfwdf_sr_data { #define PVR_IDFWDF_TEX_HEIGHT 2U #define PVR_IDFWDF_TEX_STRIDE 4U +/** pck_info and pck_format bitfield helpers. */ +#define PVR_PCK_FORMAT_INVALID 0b11111U +#define PVR_PCK_INFO_FORMAT_LENGTH 5U +#define PVR_PCK_INFO_FORMAT_OFFSET 0U +#define PVR_PCK_INFO_SPLIT_OFFSET 5U +#define PVR_PCK_INFO_SCALE_OFFSET 6U +#define PVR_PCK_INFO_ROUNDZERO_OFFSET 7U +#define PVR_PCK_INFO_UNORM_OFFSET 8U +#define PVR_PCK_INFO_SPLIT_BIT BITFIELD_BIT(PVR_PCK_INFO_SPLIT_OFFSET) +#define PVR_PCK_INFO_SCALE_BIT BITFIELD_BIT(PVR_PCK_INFO_SCALE_OFFSET) +#define PVR_PCK_INFO_ROUNDZERO_BIT BITFIELD_BIT(PVR_PCK_INFO_ROUNDZERO_OFFSET) +#define PVR_PCK_INFO_UNORM_BIT BITFIELD_BIT(PVR_PCK_INFO_UNORM_OFFSET) + #endif /* PVR_IFACE_H */ diff --git a/src/imagination/pco/pco.c b/src/imagination/pco/pco.c index 4274442b362..4866e1e0d6a 100644 --- a/src/imagination/pco/pco.c +++ b/src/imagination/pco/pco.c @@ -379,3 +379,79 @@ struct pvr_stats pco_get_pvr_stats(pco_shader *shader) }, }; } + +enum pco_pck_format pco_pipe_to_pck_format(enum pipe_format format, + bool *scale, + bool *roundzero, + bool *split) +{ + enum pco_pck_format pck_format = ~0; + *scale = false; + *roundzero = false; + *split = false; + + switch (format) { + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R8G8_UNORM: + case PIPE_FORMAT_R8G8B8_UNORM: + case PIPE_FORMAT_R8G8B8A8_UNORM: + pck_format = PCO_PCK_FORMAT_U8888; + *scale = true; + break; + + case PIPE_FORMAT_R8_SNORM: + case PIPE_FORMAT_R8G8_SNORM: + case PIPE_FORMAT_R8G8B8_SNORM: + case PIPE_FORMAT_R8G8B8A8_SNORM: + pck_format = PCO_PCK_FORMAT_S8888; + *scale = true; + break; + + case PIPE_FORMAT_R11G11B10_FLOAT: + pck_format = PCO_PCK_FORMAT_F111110; + break; + + /* TODO: better way to do the 1x2 component. */ + case PIPE_FORMAT_R10G10B10A2_UNORM: + pck_format = PCO_PCK_FORMAT_U1010102; + *scale = true; + break; + + /* TODO: better way to do the 1x2 component. */ + case PIPE_FORMAT_R10G10B10A2_SNORM: + pck_format = PCO_PCK_FORMAT_S1010102; + *scale = true; + break; + + case PIPE_FORMAT_R16_FLOAT: + case PIPE_FORMAT_R16G16_FLOAT: + case PIPE_FORMAT_R16G16B16_FLOAT: + case PIPE_FORMAT_R16G16B16A16_FLOAT: + pck_format = PCO_PCK_FORMAT_F16F16; + *split = true; + break; + + case PIPE_FORMAT_R16_UNORM: + case PIPE_FORMAT_R16G16_UNORM: + case PIPE_FORMAT_R16G16B16_UNORM: + case PIPE_FORMAT_R16G16B16A16_UNORM: + pck_format = PCO_PCK_FORMAT_U1616; + *scale = true; + *split = true; + break; + + case PIPE_FORMAT_R16_SNORM: + case PIPE_FORMAT_R16G16_SNORM: + case PIPE_FORMAT_R16G16B16_SNORM: + case PIPE_FORMAT_R16G16B16A16_SNORM: + pck_format = PCO_PCK_FORMAT_S1616; + *scale = true; + *split = true; + break; + + default: + break; + } + + return pck_format; +} diff --git a/src/imagination/pco/pco.h b/src/imagination/pco/pco.h index 4b528e1b121..f9710f73595 100644 --- a/src/imagination/pco/pco.h +++ b/src/imagination/pco/pco.h @@ -95,4 +95,9 @@ typedef struct _pco_smp_params { bool int_mode; } pco_smp_params; nir_intrinsic_instr *pco_emit_nir_smp(nir_builder *b, pco_smp_params *params); + +enum pco_pck_format pco_pipe_to_pck_format(enum pipe_format format, + bool *scale, + bool *roundzero, + bool *split); #endif /* PCO_H */ diff --git a/src/imagination/pco/pco_nir_tex.c b/src/imagination/pco/pco_nir_tex.c index a15e21d00e9..b7913840c66 100644 --- a/src/imagination/pco/pco_nir_tex.c +++ b/src/imagination/pco/pco_nir_tex.c @@ -19,6 +19,7 @@ #include "pco_common.h" #include "pco_internal.h" #include "pco_usclib.h" +#include "pvr_iface.h" #include "util/macros.h" #include @@ -926,108 +927,11 @@ static nir_def *lower_image(nir_builder *b, nir_instr *instr, void *cb_data) nir_type_to_pipe_format(type, desc->nr_channels); if (format != data_format) { - enum pco_pck_format pck_format = ~0; bool scale = false; bool roundzero = false; bool split = false; - - switch (format) { - case PIPE_FORMAT_R8_UNORM: - case PIPE_FORMAT_R8G8_UNORM: - case PIPE_FORMAT_R8G8B8_UNORM: - case PIPE_FORMAT_R8G8B8A8_UNORM: - pck_format = PCO_PCK_FORMAT_U8888; - scale = true; - break; - - case PIPE_FORMAT_R8_SNORM: - case PIPE_FORMAT_R8G8_SNORM: - case PIPE_FORMAT_R8G8B8_SNORM: - case PIPE_FORMAT_R8G8B8A8_SNORM: - pck_format = PCO_PCK_FORMAT_S8888; - scale = true; - break; - - case PIPE_FORMAT_R11G11B10_FLOAT: - pck_format = PCO_PCK_FORMAT_F111110; - break; - - case PIPE_FORMAT_R10G10B10A2_UNORM: - pck_format = PCO_PCK_FORMAT_U1010102; - scale = true; - break; - - case PIPE_FORMAT_R10G10B10A2_SNORM: - pck_format = PCO_PCK_FORMAT_S1010102; - scale = true; - break; - - case PIPE_FORMAT_R16_FLOAT: - case PIPE_FORMAT_R16G16_FLOAT: - case PIPE_FORMAT_R16G16B16_FLOAT: - case PIPE_FORMAT_R16G16B16A16_FLOAT: - pck_format = PCO_PCK_FORMAT_F16F16; - split = true; - break; - - case PIPE_FORMAT_R16_UNORM: - case PIPE_FORMAT_R16G16_UNORM: - case PIPE_FORMAT_R16G16B16_UNORM: - case PIPE_FORMAT_R16G16B16A16_UNORM: - pck_format = PCO_PCK_FORMAT_U1616; - scale = true; - split = true; - break; - - case PIPE_FORMAT_R16_SNORM: - case PIPE_FORMAT_R16G16_SNORM: - case PIPE_FORMAT_R16G16B16_SNORM: - case PIPE_FORMAT_R16G16B16A16_SNORM: - pck_format = PCO_PCK_FORMAT_S1616; - scale = true; - split = true; - break; - - case PIPE_FORMAT_R8_UINT: - case PIPE_FORMAT_R8G8_UINT: - case PIPE_FORMAT_R8G8B8_UINT: - case PIPE_FORMAT_R8G8B8A8_UINT: - - case PIPE_FORMAT_R8_SINT: - case PIPE_FORMAT_R8G8_SINT: - case PIPE_FORMAT_R8G8B8_SINT: - case PIPE_FORMAT_R8G8B8A8_SINT: - - case PIPE_FORMAT_R10G10B10A2_UINT: - case PIPE_FORMAT_R10G10B10A2_SINT: - - case PIPE_FORMAT_R16_UINT: - case PIPE_FORMAT_R16G16_UINT: - case PIPE_FORMAT_R16G16B16_UINT: - case PIPE_FORMAT_R16G16B16A16_UINT: - - case PIPE_FORMAT_R16_SINT: - case PIPE_FORMAT_R16G16_SINT: - case PIPE_FORMAT_R16G16B16_SINT: - case PIPE_FORMAT_R16G16B16A16_SINT: - - case PIPE_FORMAT_R32_UINT: - case PIPE_FORMAT_R32G32_UINT: - case PIPE_FORMAT_R32G32B32_UINT: - case PIPE_FORMAT_R32G32B32A32_UINT: - - case PIPE_FORMAT_R32_SINT: - case PIPE_FORMAT_R32G32_SINT: - case PIPE_FORMAT_R32G32B32_SINT: - case PIPE_FORMAT_R32G32B32A32_SINT: - /* No conversion needed. */ - break; - - default: - printf("Unsupported image write pack format %s.\n", - util_format_name(format)); - UNREACHABLE(""); - } + enum pco_pck_format pck_format = + pco_pipe_to_pck_format(data_format, &scale, &roundzero, &split); if (pck_format != ~0) { if (split) { @@ -1067,13 +971,20 @@ static nir_def *lower_image(nir_builder *b, nir_instr *instr, void *cb_data) .binding = binding); nir_def *pck_info = nir_channel(b, tex_meta, PCO_IMAGE_META_PCK_INFO); - nir_def *pck_format = nir_ubitfield_extract_imm(b, pck_info, 0, 5); - nir_def *pck_skip = nir_ieq_imm(b, pck_format, 0b11111); - nir_def *pck_split = nir_ubitfield_extract_imm(b, pck_info, 5, 1); + nir_def *pck_format = + nir_ubitfield_extract_imm(b, + pck_info, + PVR_PCK_INFO_FORMAT_OFFSET, + PVR_PCK_INFO_FORMAT_LENGTH); + nir_def *pck_skip = nir_ieq_imm(b, pck_format, PVR_PCK_FORMAT_INVALID); + nir_def *pck_split = + nir_ubitfield_extract_imm(b, pck_info, PVR_PCK_INFO_SPLIT_OFFSET, 1); pck_split = nir_ine_imm(b, pck_split, 0); - nir_def *pck_scale = nir_ubitfield_extract_imm(b, pck_info, 6, 1); + nir_def *pck_scale = + nir_ubitfield_extract_imm(b, pck_info, PVR_PCK_INFO_SCALE_OFFSET, 1); pck_scale = nir_ine_imm(b, pck_scale, 0); - /* nir_def *pck_roundzero = nir_ubitfield_extract_imm(b, pck_info, 7, + /* nir_def *pck_roundzero = nir_ubitfield_extract_imm(b, pck_info, + * PVR_PCK_INFO_ROUNDZERO_OFFSET, * 1); */ /* pck_roundzero = nir_ine_imm(b, pck_roundzero, 0); */ diff --git a/src/imagination/vulkan/pvr_arch_tex_state.c b/src/imagination/vulkan/pvr_arch_tex_state.c index 255c16156c2..8233913f926 100644 --- a/src/imagination/vulkan/pvr_arch_tex_state.c +++ b/src/imagination/vulkan/pvr_arch_tex_state.c @@ -83,92 +83,30 @@ pvr_chroma_swap_format(enum ROGUE_TEXSTATE_FORMAT format) static uint32_t setup_pck_info(VkFormat vk_format) { - /* TODO NEXT: commonize this.*/ enum pipe_format format = vk_format_to_pipe_format(vk_format); - enum pco_pck_format pck_format = ~0; bool scale = false; bool roundzero = false; bool split = false; + enum pco_pck_format pck_format = + pco_pipe_to_pck_format(format, &scale, &roundzero, &split); - switch (format) { - case PIPE_FORMAT_R8_UNORM: - case PIPE_FORMAT_R8G8_UNORM: - case PIPE_FORMAT_R8G8B8_UNORM: - case PIPE_FORMAT_R8G8B8A8_UNORM: - pck_format = PCO_PCK_FORMAT_U8888; - scale = true; - break; - - case PIPE_FORMAT_R8_SNORM: - case PIPE_FORMAT_R8G8_SNORM: - case PIPE_FORMAT_R8G8B8_SNORM: - case PIPE_FORMAT_R8G8B8A8_SNORM: - pck_format = PCO_PCK_FORMAT_S8888; - scale = true; - break; - - case PIPE_FORMAT_R11G11B10_FLOAT: - pck_format = PCO_PCK_FORMAT_F111110; - break; - - /* TODO: better way to do the 1x2 component. */ - case PIPE_FORMAT_R10G10B10A2_UNORM: - pck_format = PCO_PCK_FORMAT_U1010102; - scale = true; - break; - - /* TODO: better way to do the 1x2 component. */ - case PIPE_FORMAT_R10G10B10A2_SNORM: - pck_format = PCO_PCK_FORMAT_S1010102; - scale = true; - break; - - case PIPE_FORMAT_R16_FLOAT: - case PIPE_FORMAT_R16G16_FLOAT: - case PIPE_FORMAT_R16G16B16_FLOAT: - case PIPE_FORMAT_R16G16B16A16_FLOAT: - pck_format = PCO_PCK_FORMAT_F16F16; - split = true; - break; - - case PIPE_FORMAT_R16_UNORM: - case PIPE_FORMAT_R16G16_UNORM: - case PIPE_FORMAT_R16G16B16_UNORM: - case PIPE_FORMAT_R16G16B16A16_UNORM: - pck_format = PCO_PCK_FORMAT_U1616; - scale = true; - split = true; - break; - - case PIPE_FORMAT_R16_SNORM: - case PIPE_FORMAT_R16G16_SNORM: - case PIPE_FORMAT_R16G16B16_SNORM: - case PIPE_FORMAT_R16G16B16A16_SNORM: - pck_format = PCO_PCK_FORMAT_S1616; - scale = true; - split = true; - break; - - default: - break; - } - - /* Invalidate the format bits, but clear the rest so they can still be set. */ + /* Invalidate the format bits, but clear the rest so they can still be set. + */ if (pck_format == ~0) - pck_format = 0b11111; + pck_format = PVR_PCK_FORMAT_INVALID; uint32_t pck_info = pck_format; if (split) - pck_info |= BITFIELD_BIT(5); + pck_info |= PVR_PCK_INFO_SPLIT_BIT; if (scale) - pck_info |= BITFIELD_BIT(6); + pck_info |= PVR_PCK_INFO_SCALE_BIT; if (roundzero) - pck_info |= BITFIELD_BIT(7); + pck_info |= PVR_PCK_INFO_ROUNDZERO_BIT; if (util_format_is_unorm(format)) - pck_info |= BITFIELD_BIT(8); + pck_info |= PVR_PCK_INFO_UNORM_BIT; return pck_info; }