d3d12: Add support for Y210, Y410, YUY2 and HEVC 422 8/10b, HEVC 444 10b profiles

Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Reviewed by: Pohsiang (John) Hsu <pohhsu@microsoft.com>

Reviewed-by: Jesse Natalie <None>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33312>
This commit is contained in:
Sil Vilerino
2025-01-16 09:08:07 -05:00
committed by Marge Bot
parent df27e09267
commit 123374c1d7
5 changed files with 84 additions and 10 deletions
+10 -1
View File
@@ -173,7 +173,10 @@
\
MAP_FORMAT_YUV(NV12) \
MAP_FORMAT_YUV(P010) \
MAP_FORMAT_YUV(AYUV)
MAP_FORMAT_YUV(AYUV) \
MAP_FORMAT_YUV(Y410) \
[PIPE_FORMAT_YUYV] = DXGI_FORMAT_YUY2, \
MAP_FORMAT_YUV(Y210)
static const DXGI_FORMAT formats[PIPE_FORMAT_COUNT] = {
FORMAT_TABLE()
@@ -627,6 +630,12 @@ d3d12_convert_pipe_video_profile_to_dxgi_format(enum pipe_video_profile profile)
return DXGI_FORMAT_P010;
case PIPE_VIDEO_PROFILE_HEVC_MAIN_444:
return DXGI_FORMAT_AYUV;
case PIPE_VIDEO_PROFILE_HEVC_MAIN10_444:
return DXGI_FORMAT_Y410;
case PIPE_VIDEO_PROFILE_HEVC_MAIN_422:
return DXGI_FORMAT_YUY2;
case PIPE_VIDEO_PROFILE_HEVC_MAIN10_422:
return DXGI_FORMAT_Y210;
default:
{
unreachable("Unsupported pipe video profile");
@@ -363,7 +363,10 @@ d3d12_video_encoder_update_current_frame_pic_params_info_hevc(struct d3d12_video
picParams.pHEVCPicData->Flags |= D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_HEVC_FLAG_REQUEST_NUM_REF_IDX_ACTIVE_OVERRIDE_FLAG_SLICE;
}
if (hevcPic->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_444)
if ((hevcPic->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_444) ||
(hevcPic->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN10_444) ||
(hevcPic->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_422) ||
(hevcPic->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN10_422))
{
assert(picParams.DataSize == sizeof(D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_HEVC1));
@@ -880,7 +883,10 @@ d3d12_video_encoder_convert_hevc_codec_configuration(struct d3d12_video_encoder
if (picture->pic.constrained_intra_pred_flag)
config.ConfigurationFlags |= D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_USE_CONSTRAINED_INTRAPREDICTION;
if (picture->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_444)
if ((picture->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_444) ||
(picture->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN10_444) ||
(picture->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_422) ||
(picture->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN10_422))
{
if (picture->seq.sps_range_extension.transform_skip_rotation_enabled_flag)
config.ConfigurationFlags |= D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_TRANSFORM_SKIP_ROTATION;
@@ -1410,6 +1416,15 @@ d3d12_video_encoder_convert_profile_to_d3d12_enc_profile_hevc(enum pipe_video_pr
{
return D3D12_VIDEO_ENCODER_PROFILE_HEVC_MAIN_444;
} break;
case PIPE_VIDEO_PROFILE_HEVC_MAIN10_444:
{
return D3D12_VIDEO_ENCODER_PROFILE_HEVC_MAIN10_444;
} break;
case PIPE_VIDEO_PROFILE_HEVC_MAIN_422:
case PIPE_VIDEO_PROFILE_HEVC_MAIN10_422:
{
return D3D12_VIDEO_ENCODER_PROFILE_HEVC_MAIN10_422;
} break;
default:
{
unreachable("Unsupported pipe_video_profile");
@@ -37,7 +37,9 @@ convert_profile12_to_stdprofile(D3D12_VIDEO_ENCODER_PROFILE_HEVC profile)
{
return 2;
} break;
case D3D12_VIDEO_ENCODER_PROFILE_HEVC_MAIN10_422:
case D3D12_VIDEO_ENCODER_PROFILE_HEVC_MAIN_444:
case D3D12_VIDEO_ENCODER_PROFILE_HEVC_MAIN10_444:
{
return 4;
} break;
@@ -48,11 +50,30 @@ convert_profile12_to_stdprofile(D3D12_VIDEO_ENCODER_PROFILE_HEVC profile)
}
}
static int
dxgi_format_to_pix_bits(DXGI_FORMAT fmt)
{
switch (fmt) {
default:
unreachable("Unsupported DXGI_FORMAT");
case DXGI_FORMAT_AYUV:
case DXGI_FORMAT_NV12:
case DXGI_FORMAT_YUY2:
return 8;
case DXGI_FORMAT_P010:
case DXGI_FORMAT_Y210:
case DXGI_FORMAT_Y410:
return 10;
}
}
void
d3d12_video_bitstream_builder_hevc::init_profile_tier_level(HEVCProfileTierLevel *ptl,
uint8_t HEVCProfileIdc,
uint32_t HEVCLevelIdc,
bool isHighTier)
bool isHighTier,
uint32_t pix_bits)
{
memset(ptl, 0, sizeof(HEVCProfileTierLevel));
@@ -72,9 +93,9 @@ d3d12_video_bitstream_builder_hevc::init_profile_tier_level(HEVCProfileTierLevel
if (ptl->general_profile_idc == 4 /*MAIN444*/)
{
ptl->general_intra_constraint_flag = 1;
ptl->general_max_12bit_constraint_flag = 1;
ptl->general_max_10bit_constraint_flag = 1;
ptl->general_max_8bit_constraint_flag = 1;
ptl->general_max_12bit_constraint_flag = pix_bits <= 12;
ptl->general_max_10bit_constraint_flag = pix_bits <= 10;
ptl->general_max_8bit_constraint_flag = pix_bits <= 8;
}
}
@@ -356,7 +377,7 @@ d3d12_video_bitstream_builder_hevc::build_vps(const struct pipe_h265_enc_vid_par
m_latest_vps.vps_max_sub_layers_minus1 = 0u;
m_latest_vps.vps_temporal_id_nesting_flag = 1u;
m_latest_vps.vps_reserved_0xffff_16bits = 0xFFFF;
init_profile_tier_level(&m_latest_vps.ptl, HEVCProfileIdc, HEVCLevelIdc, isHighTier);
init_profile_tier_level(&m_latest_vps.ptl, HEVCProfileIdc, HEVCLevelIdc, isHighTier, dxgi_format_to_pix_bits(inputFmt));
m_latest_vps.vps_sub_layer_ordering_info_present_flag = 0u;
for (int i = (m_latest_vps.vps_sub_layer_ordering_info_present_flag ? 0 : m_latest_vps.vps_max_sub_layers_minus1); i <= m_latest_vps.vps_max_sub_layers_minus1; i++) {
m_latest_vps.vps_max_dec_pic_buffering_minus1[i] = vidData.vps_max_dec_pic_buffering_minus1[i];
@@ -412,6 +433,27 @@ d3d12_video_bitstream_builder_hevc::build_sps(const HevcVideoParameterSet& paren
SubWidthC = 1u;
SubHeightC = 1u;
m_latest_sps.chroma_format_idc = 3u;
} else if (inputFmt == DXGI_FORMAT_Y410) {
// 444 10 bits
m_latest_sps.bit_depth_luma_minus8 = 2u;
m_latest_sps.bit_depth_chroma_minus8 = 2u;
SubWidthC = 1u;
SubHeightC = 1u;
m_latest_sps.chroma_format_idc = 3u;
} else if (inputFmt == DXGI_FORMAT_YUY2) {
// 422 8 bits
m_latest_sps.bit_depth_luma_minus8 = 0u;
m_latest_sps.bit_depth_chroma_minus8 = 0u;
SubWidthC = 2u;
SubHeightC = 1u;
m_latest_sps.chroma_format_idc = 2u;
} else if (inputFmt == DXGI_FORMAT_Y210) {
// 422 10 bits
m_latest_sps.bit_depth_luma_minus8 = 2u;
m_latest_sps.bit_depth_chroma_minus8 = 2u;
SubWidthC = 2u;
SubHeightC = 1u;
m_latest_sps.chroma_format_idc = 2u;
}
uint8_t minCuSize = d3d12_video_encoder_convert_12cusize_to_pixel_size_hevc(codecConfig.MinLumaCodingUnitSize);
@@ -119,7 +119,7 @@ class d3d12_video_bitstream_builder_hevc : public d3d12_video_bitstream_builder_
HevcSeqParameterSet m_active_sps = {};
HevcPicParameterSet m_active_pps = {};
void init_profile_tier_level(HEVCProfileTierLevel *ptl, uint8_t HEVCProfileIdc, uint32_t HEVCLevelIdc, bool isHighTier);
void init_profile_tier_level(HEVCProfileTierLevel *ptl, uint8_t HEVCProfileIdc, uint32_t HEVCLevelIdc, bool isHighTier, uint32_t pix_bits);
};
#endif
@@ -960,6 +960,9 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen,
case PIPE_VIDEO_PROFILE_HEVC_MAIN:
case PIPE_VIDEO_PROFILE_HEVC_MAIN_10:
case PIPE_VIDEO_PROFILE_HEVC_MAIN_444:
case PIPE_VIDEO_PROFILE_HEVC_MAIN10_444:
case PIPE_VIDEO_PROFILE_HEVC_MAIN_422:
case PIPE_VIDEO_PROFILE_HEVC_MAIN10_422:
{
D3D12_VIDEO_ENCODER_PROFILE_DESC profDesc = {};
D3D12_VIDEO_ENCODER_PROFILE_HEVC profHEVC =
@@ -2135,7 +2138,12 @@ is_d3d12_video_allowed_format(enum pipe_format format, enum pipe_video_entrypoin
if (entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) {
return ((format == PIPE_FORMAT_NV12) || (format == PIPE_FORMAT_P010));
} else if (entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
return ((format == PIPE_FORMAT_NV12) || (format == PIPE_FORMAT_P010) || (format == PIPE_FORMAT_AYUV));
return ((format == PIPE_FORMAT_NV12) ||
(format == PIPE_FORMAT_P010) ||
(format == PIPE_FORMAT_AYUV) ||
(format == PIPE_FORMAT_YUYV /*maps to DXGI_FORMAT_YUY2*/) ||
(format == PIPE_FORMAT_Y210) ||
(format == PIPE_FORMAT_Y410));
} else if (entrypoint == PIPE_VIDEO_ENTRYPOINT_PROCESSING) {
return (format == PIPE_FORMAT_NV12) || (format == PIPE_FORMAT_P010)
|| (format == PIPE_FORMAT_R8G8B8A8_UNORM) || (format == PIPE_FORMAT_R8G8B8A8_UINT)