pvr: setup csc tables

Reviewed-by: Simon Perretta <simon.perretta@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39231>
This commit is contained in:
Ella Stanforth 2026-01-06 11:46:08 +00:00 committed by Marge Bot
parent c856d34056
commit 3495831d72
7 changed files with 159 additions and 0 deletions

View file

@ -11,6 +11,7 @@ libpowervr_common = static_library(
'pvr_dump.c',
'pvr_dump_info.c',
'pvr_util.c',
'pvr_ycbcr.c',
sha1_h,
],
include_directories : [

View file

@ -0,0 +1,101 @@
/*
* Copyright © 2026 Imagination Technologies Ltd.
* SPDX-License-Identifier: MIT
*/
#include "pvr_ycbcr.h"
#include "util/macros.h"
/* number of slots occupied */
#define PVR_YCBCR_SLOTS 9
struct pvr_ycbcr_csc_table_entry {
uint16_t value[32];
} PACKED;
struct pvr_ycbcr_csc_table {
struct pvr_ycbcr_csc_table_entry slots[PVR_YCBCR_SLOTS];
} PACKED;
/* clang-format off */
static const uint16_t RGB_IDENTITY[] = {
0x0000, 0x1ffc, 0x0000,
0x0000, 0x0000, 0x1ffc,
0x1ffc, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000,
};
static const uint16_t YCBCR_IDENTITY_FULL[] = {
0x0000, 0x1ffc, 0x0000,
0x0000, 0x0000, 0x1ffc,
0x1ffc, 0x0000, 0x0000,
0xfff0, 0x0000, 0xfff0,
};
static const uint16_t YCBCR_IDENTITY[] = {
0x0000, 0x253e, 0x0000,
0x0000, 0x0000, 0x2469,
0x2469, 0x0000, 0x0000,
0xfdb9, 0xfdac, 0xfdb9,
};
static const uint16_t YCBCR_709_FULL[] = {
0x1ffc, 0x1ffc, 0x1ffc,
0x0000, 0xfa02, 0x3b5a,
0x325e, 0xf107, 0x0000,
0xe6d1, 0x0a7b, 0xe253,
};
static const uint16_t YCBCR_709[] = {
0x253e, 0x253e, 0x253e,
0x0000, 0xf92e, 0x4390,
0x3957, 0xeef5, 0x0000,
0xe101, 0x099b, 0xdbe4,
};
static const uint16_t YCBCR_601_FULL[] = {
0x1ffc, 0x1ffc, 0x1ffc,
0x0000, 0xf4fe, 0x38ad,
0x2cd8, 0xe929, 0x0000,
0xe994, 0x10ed, 0xe3a9,
};
static const uint16_t YCBCR_601[] = {
0x253e, 0x253e, 0x253e,
0x0000, 0xf378, 0x4085,
0x330c, 0xe5ff, 0x0000,
0xe426, 0x10f0, 0xdd6a,
};
static const uint16_t YCBCR_2020_FULL[] = {
0x1ffc, 0x1ffc, 0x1ffc,
0x0000, 0xfabd, 0x3c2d,
0x2f2a, 0xedba, 0x0000,
0xe86b, 0x0bc5, 0xe1ea,
};
static const uint16_t YCBCR_2020[] = {
0x253e, 0x253e, 0x253e,
0x0000, 0xfa02, 0x4481,
0x35b1, 0xeb32, 0x0000,
0xe2d4, 0x0b12, 0xdb6c,
};
/* clang-format on */
#define fill_slot(table, entry) \
memcpy(&table->slots[PVR_YCBCR_SLOT_##entry].value, entry, sizeof(entry))
void pvr_setup_static_yuv_csc_table(uint8_t *map, uint64_t offset)
{
struct pvr_ycbcr_csc_table *table =
(struct pvr_ycbcr_csc_table *)(&map[offset]);
fill_slot(table, RGB_IDENTITY);
fill_slot(table, YCBCR_IDENTITY_FULL);
fill_slot(table, YCBCR_IDENTITY);
fill_slot(table, YCBCR_709_FULL);
fill_slot(table, YCBCR_709);
fill_slot(table, YCBCR_601_FULL);
fill_slot(table, YCBCR_601);
fill_slot(table, YCBCR_2020_FULL);
fill_slot(table, YCBCR_2020);
}

View file

@ -0,0 +1,23 @@
/*
* Copyright © 2026 Imagination Technologies Ltd.
* SPDX-License-Identifier: MIT
*/
#ifndef PVR_YCBCR_H
#define PVR_YCBCR_H
#include <stdint.h>
void pvr_setup_static_yuv_csc_table(uint8_t *const heap_ptr,
uint64_t yuv_table_offset_in_bytes);
#define PVR_YCBCR_SLOT_RGB_IDENTITY 0
#define PVR_YCBCR_SLOT_YCBCR_IDENTITY_FULL 1
#define PVR_YCBCR_SLOT_YCBCR_IDENTITY 2
#define PVR_YCBCR_SLOT_YCBCR_709_FULL 3
#define PVR_YCBCR_SLOT_YCBCR_709 4
#define PVR_YCBCR_SLOT_YCBCR_601_FULL 5
#define PVR_YCBCR_SLOT_YCBCR_601 6
#define PVR_YCBCR_SLOT_YCBCR_2020_FULL 7
#define PVR_YCBCR_SLOT_YCBCR_2020 8
#endif /* PVR_YCBCR_H */

View file

@ -19,6 +19,7 @@
#include "pvr_macros.h"
#include "pvr_physical_device.h"
#include "pvr_tex_state.h"
#include "pvr_ycbcr.h"
static void pvr_adjust_non_compressed_view(const struct pvr_image *image,
const struct pvr_image_plane *plane,
@ -44,6 +45,26 @@ static void pvr_adjust_non_compressed_view(const struct pvr_image *image,
info->base_level = 0;
}
static unsigned int pvr_ycbcr_csc_index(struct vk_ycbcr_conversion *conversion)
{
#define MAPPING(vk, slot_full, slot_narrow) \
[VK_SAMPLER_YCBCR_MODEL_CONVERSION_##vk] = { \
PVR_YCBCR_SLOT_##slot_full, \
PVR_YCBCR_SLOT_##slot_narrow \
}
static unsigned int mapping[][2] = {
MAPPING(RGB_IDENTITY, RGB_IDENTITY, RGB_IDENTITY),
MAPPING(YCBCR_IDENTITY, YCBCR_IDENTITY_FULL, YCBCR_IDENTITY),
MAPPING(YCBCR_709, YCBCR_709_FULL, YCBCR_709),
MAPPING(YCBCR_601, YCBCR_601_FULL, YCBCR_601),
MAPPING(YCBCR_2020, YCBCR_2020_FULL, YCBCR_2020),
};
return mapping[conversion->state.ycbcr_model][conversion->state.ycbcr_range];
#undef MAPPING
}
VkResult PVR_PER_ARCH(CreateImageView)(VkDevice _device,
const VkImageViewCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
@ -127,6 +148,8 @@ VkResult PVR_PER_ARCH(CreateImageView)(VkDevice _device,
input_swizzle[3] = PIPE_SWIZZLE_0;
}
info.csc_coeff_index = pvr_ycbcr_csc_index(conversion);
pvr_csb_pack (&iview->sampler_words[0], TEXSTATE_SAMPLER_WORD0, cfg) {
cfg.texaddr_plane2_lo =
PVR_DEV_ADDR_OFFSET(image->dev_addr, image->planes[1].offset);

View file

@ -278,6 +278,7 @@ VkResult pvr_arch_pack_tex_state(struct pvr_device *device,
word1.chroma_interpolation_u = 0;
word1.stride = info->extent.width - 1;
word1.texaddr = PVR_DEV_ADDR_OFFSET(info->addr, info->offset);
word1.csc_coeff_index = info->csc_coeff_index;
}
} else if (mem_layout == PVR_MEMLAYOUT_LINEAR) {
pvr_csb_pack (&state->words[1], TEXSTATE_STRIDE_IMAGE_WORD1, word1) {

View file

@ -107,6 +107,11 @@ struct pvr_texture_state_info {
uint32_t layer_size;
uint32_t buffer_elems;
uint32_t z_slice;
/**
* YCbCr CSC matrix
*/
uint8_t csc_coeff_index;
};
#ifdef PVR_PER_ARCH

View file

@ -34,6 +34,7 @@
#include "pvr_types.h"
#include "pvr_winsys.h"
#include "pvr_winsys_helper.h"
#include "pvr_ycbcr.h"
#include "util/u_atomic.h"
#include "vk_log.h"
@ -343,6 +344,10 @@ pvr_winsys_helper_fill_static_memory(struct pvr_winsys *const ws,
pvr_setup_static_pixel_event_program(pds_vma->bo->map,
pds_vma->heap->static_data_offsets.eot);
pvr_setup_static_yuv_csc_table(
general_vma->bo->map,
general_vma->heap->static_data_offsets.yuv_csc);
ws->ops->buffer_unmap(usc_vma->bo, false);
ws->ops->buffer_unmap(pds_vma->bo, false);
ws->ops->buffer_unmap(general_vma->bo, false);