pvr, pco: Commonize texture packing code
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

Format extraction moved to separate function
Removed some magic numbers

Signed-off-by: Radu Costas <radu.costas@imgtec.com>
Reviewed-by: Simon Perretta <simon.perretta@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40067>
This commit is contained in:
Radu Costas 2026-02-20 12:16:04 +02:00 committed by Marge Bot
parent d583339e79
commit 9caa563bc9
5 changed files with 118 additions and 175 deletions

View file

@ -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 */

View file

@ -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;
}

View file

@ -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 */

View file

@ -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 <assert.h>
@ -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); */

View file

@ -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;
}