radv/video: Implement VK_VALVE_video_encode_rgb_conversion

This is used by Steam Link VR (driver_vrlink) to avoid doing YUV conversion itself.

Signed-off-by: Autumn Ashton <misyl@froggi.es>
Reviewed-by: David Rosca <david.rosca@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37500>
This commit is contained in:
Autumn Ashton 2025-09-03 22:29:58 +01:00 committed by Marge Bot
parent 73a31dafbc
commit 2705d8bd8b
7 changed files with 191 additions and 52 deletions

View file

@ -716,7 +716,7 @@ Khronos extensions that are not part of any Vulkan version:
VK_MESA_image_alignment_control DONE (anv, nvk, radv)
VK_EXT_legacy_dithering DONE (anv, tu, vn)
VK_QCOM_fragment_density_map_offset DONE (tu)
VK_VALVE_video_encode_rgb_conversion DONE (radv)
Rusticl OpenCL 1.0 -- all DONE:
Image support DONE

View file

@ -9,3 +9,4 @@ VK_KHR_present_wait2 on HoneyKrisp
VK_KHR_maintenance10 on ANV, NVK, RADV
VK_EXT_shader_uniform_buffer_unsized_array on NVK, RADV
VK_EXT_device_memory_report on panvk
VK_VALVE_video_encode_rgb_conversion on radv

View file

@ -814,6 +814,8 @@ radv_physical_device_get_supported_extensions(const struct radv_physical_device
.NV_compute_shader_derivatives = true,
.NV_cooperative_matrix2 = radv_cooperative_matrix2_nv_enabled(pdev),
.VALVE_mutable_descriptor_type = true,
.VALVE_video_encode_rgb_conversion =
pdev->video_encode_enabled && pdev->info.vcn_ip_version >= VCN_2_0_0 && pdev->info.vcn_ip_version != VCN_2_2_0,
};
*out_ext = ext;
}
@ -1428,6 +1430,9 @@ radv_physical_device_get_features(const struct radv_physical_device *pdev, struc
/* VK_KHR_maintenance10 */
.maintenance10 = true,
/* VK_VALVE_video_encode_rgb_conversion */
.videoEncodeRgbConversion = true,
};
}

View file

@ -928,6 +928,8 @@ radv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, cons
vk_find_struct(pCapabilities->pNext, VIDEO_ENCODE_INTRA_REFRESH_CAPABILITIES_KHR);
struct VkVideoEncodeQuantizationMapCapabilitiesKHR *qp_map_caps =
vk_find_struct(pCapabilities->pNext, VIDEO_ENCODE_QUANTIZATION_MAP_CAPABILITIES_KHR);
struct VkVideoEncodeRgbConversionCapabilitiesVALVE *rgb_caps =
vk_find_struct(pCapabilities->pNext, VIDEO_ENCODE_RGB_CONVERSION_CAPABILITIES_VALVE);
if (enc_caps) {
enc_caps->flags = 0;
@ -958,6 +960,15 @@ radv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, cons
qp_map_caps->maxQuantizationMapExtent.width = pCapabilities->maxCodedExtent.width / qp_map_texel_size;
qp_map_caps->maxQuantizationMapExtent.height = pCapabilities->maxCodedExtent.height / qp_map_texel_size;
}
if (rgb_caps) {
rgb_caps->rgbModels = VK_VIDEO_ENCODE_RGB_MODEL_CONVERSION_YCBCR_709_BIT_VALVE |
VK_VIDEO_ENCODE_RGB_MODEL_CONVERSION_YCBCR_2020_BIT_VALVE;
rgb_caps->rgbRanges = VK_VIDEO_ENCODE_RGB_RANGE_COMPRESSION_FULL_RANGE_BIT_VALVE |
VK_VIDEO_ENCODE_RGB_RANGE_COMPRESSION_NARROW_RANGE_BIT_VALVE;
rgb_caps->xChromaOffsets = VK_VIDEO_ENCODE_RGB_CHROMA_OFFSET_COSITED_EVEN_BIT_VALVE;
rgb_caps->yChromaOffsets = VK_VIDEO_ENCODE_RGB_CHROMA_OFFSET_MIDPOINT_BIT_VALVE |
VK_VIDEO_ENCODE_RGB_CHROMA_OFFSET_COSITED_EVEN_BIT_VALVE;
}
pCapabilities->minBitstreamBufferOffsetAlignment = 256;
pCapabilities->minBitstreamBufferSizeAlignment = 8;
if (pdev->info.vcn_ip_version >= VCN_5_0_0)
@ -1241,13 +1252,17 @@ radv_GetPhysicalDeviceVideoFormatPropertiesKHR(VkPhysicalDevice physicalDevice,
(VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR | VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR))
return VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR;
VkFormat format = VK_FORMAT_UNDEFINED;
VkFormat formats[2] = {VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED};
uint32_t qp_map_texel_size = 0;
const struct VkVideoProfileListInfoKHR *prof_list =
(struct VkVideoProfileListInfoKHR *)vk_find_struct_const(pVideoFormatInfo->pNext, VIDEO_PROFILE_LIST_INFO_KHR);
if (prof_list) {
for (unsigned i = 0; i < prof_list->profileCount; i++) {
const VkVideoProfileInfoKHR *profile = &prof_list->pProfiles[i];
const VkVideoEncodeProfileRgbConversionInfoVALVE *rgbProfile =
vk_find_struct_const(profile, VIDEO_ENCODE_PROFILE_RGB_CONVERSION_INFO_VALVE);
bool rgb = rgbProfile && rgbProfile->performEncodeRgbConversion &&
(pVideoFormatInfo->imageUsage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR);
/* "If any of the video profiles specified via VkVideoProfileListInfoKHR::pProfiles are not
* supported, then this command returns one of the video-profile-specific error codes."
@ -1256,8 +1271,7 @@ radv_GetPhysicalDeviceVideoFormatPropertiesKHR(VkPhysicalDevice physicalDevice,
if (res != VK_SUCCESS)
return res;
VkFormat profile_format = VK_FORMAT_UNDEFINED;
VkFormat profile_formats[2] = {VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED};
if (pVideoFormatInfo->imageUsage & VK_IMAGE_USAGE_VIDEO_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR) {
const uint32_t profile_qp_map_texel_size = radv_video_get_qp_map_texel_size(profile->videoCodecOperation);
@ -1267,31 +1281,41 @@ radv_GetPhysicalDeviceVideoFormatPropertiesKHR(VkPhysicalDevice physicalDevice,
qp_map_texel_size = profile_qp_map_texel_size;
profile_format = pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5 ? VK_FORMAT_R16_SINT : VK_FORMAT_R32_SINT;
profile_formats[0] = pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5 ? VK_FORMAT_R16_SINT : VK_FORMAT_R32_SINT;
} else if (rgb) {
if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR) {
profile_formats[0] = VK_FORMAT_B8G8R8A8_UNORM;
profile_formats[1] = VK_FORMAT_R8G8B8A8_UNORM;
} else if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR) {
profile_formats[0] = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
profile_formats[1] = VK_FORMAT_A2R10G10B10_UNORM_PACK32;
}
} else {
if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR)
profile_format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
profile_formats[0] = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
else if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR)
profile_format = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16;
profile_formats[0] = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16;
else if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR)
profile_format = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16;
profile_formats[0] = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16;
}
/* All profiles must share the same format. */
if (format != VK_FORMAT_UNDEFINED && format != profile_format)
return VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR;
for (int j = 0; j < 2; j++) {
/* All profiles must share the same format. */
if (formats[j] != VK_FORMAT_UNDEFINED && formats[j] != profile_formats[j])
return VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR;
format = profile_format;
formats[j] = profile_formats[j];
}
}
} else {
/* On AMD, we need a codec specified for qp map as the extents differ. */
if (pVideoFormatInfo->imageUsage & VK_IMAGE_USAGE_VIDEO_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR)
return VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR;
format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
formats[0] = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
}
if (format == VK_FORMAT_UNDEFINED)
if (formats[0] == VK_FORMAT_UNDEFINED)
return VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR;
const bool qp_map = pVideoFormatInfo->imageUsage & VK_IMAGE_USAGE_VIDEO_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR;
@ -1320,35 +1344,40 @@ radv_GetPhysicalDeviceVideoFormatPropertiesKHR(VkPhysicalDevice physicalDevice,
VK_OUTARRAY_MAKE_TYPED(VkVideoFormatPropertiesKHR, out, pVideoFormatProperties, pVideoFormatPropertyCount);
for (uint32_t i = 0; i < num_tiling; i++) {
vk_outarray_append_typed(VkVideoFormatPropertiesKHR, &out, p)
{
p->format = format;
p->componentMapping.r = VK_COMPONENT_SWIZZLE_IDENTITY;
p->componentMapping.g = VK_COMPONENT_SWIZZLE_IDENTITY;
p->componentMapping.b = VK_COMPONENT_SWIZZLE_IDENTITY;
p->componentMapping.a = VK_COMPONENT_SWIZZLE_IDENTITY;
p->imageCreateFlags = 0;
if (src_dst || qp_map)
p->imageCreateFlags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
p->imageType = VK_IMAGE_TYPE_2D;
p->imageTiling = tiling[i];
p->imageUsageFlags = usage_flags;
for (uint32_t i = 0; i < 2; i++) {
VkFormat format = formats[i];
if (format == VK_FORMAT_UNDEFINED)
break;
for (uint32_t j = 0; j < num_tiling; j++) {
vk_outarray_append_typed(VkVideoFormatPropertiesKHR, &out, p)
{
p->format = format;
p->componentMapping.r = VK_COMPONENT_SWIZZLE_IDENTITY;
p->componentMapping.g = VK_COMPONENT_SWIZZLE_IDENTITY;
p->componentMapping.b = VK_COMPONENT_SWIZZLE_IDENTITY;
p->componentMapping.a = VK_COMPONENT_SWIZZLE_IDENTITY;
p->imageCreateFlags = 0;
if (src_dst || qp_map)
p->imageCreateFlags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
p->imageType = VK_IMAGE_TYPE_2D;
p->imageTiling = tiling[j];
p->imageUsageFlags = usage_flags;
if (qp_map) {
struct VkVideoFormatQuantizationMapPropertiesKHR *qp_map_props =
vk_find_struct(p->pNext, VIDEO_FORMAT_QUANTIZATION_MAP_PROPERTIES_KHR);
struct VkVideoFormatH265QuantizationMapPropertiesKHR *qp_map_h265_props =
vk_find_struct(p->pNext, VIDEO_FORMAT_H265_QUANTIZATION_MAP_PROPERTIES_KHR);
struct VkVideoFormatAV1QuantizationMapPropertiesKHR *qp_map_av1_props =
vk_find_struct(p->pNext, VIDEO_FORMAT_AV1_QUANTIZATION_MAP_PROPERTIES_KHR);
if (qp_map) {
struct VkVideoFormatQuantizationMapPropertiesKHR *qp_map_props =
vk_find_struct(p->pNext, VIDEO_FORMAT_QUANTIZATION_MAP_PROPERTIES_KHR);
struct VkVideoFormatH265QuantizationMapPropertiesKHR *qp_map_h265_props =
vk_find_struct(p->pNext, VIDEO_FORMAT_H265_QUANTIZATION_MAP_PROPERTIES_KHR);
struct VkVideoFormatAV1QuantizationMapPropertiesKHR *qp_map_av1_props =
vk_find_struct(p->pNext, VIDEO_FORMAT_AV1_QUANTIZATION_MAP_PROPERTIES_KHR);
if (qp_map_props)
qp_map_props->quantizationMapTexelSize = (VkExtent2D){qp_map_texel_size, qp_map_texel_size};
if (qp_map_h265_props)
qp_map_h265_props->compatibleCtbSizes = VK_VIDEO_ENCODE_H265_CTB_SIZE_64_BIT_KHR;
if (qp_map_av1_props)
qp_map_av1_props->compatibleSuperblockSizes = VK_VIDEO_ENCODE_AV1_SUPERBLOCK_SIZE_64_BIT_KHR;
if (qp_map_props)
qp_map_props->quantizationMapTexelSize = (VkExtent2D){qp_map_texel_size, qp_map_texel_size};
if (qp_map_h265_props)
qp_map_h265_props->compatibleCtbSizes = VK_VIDEO_ENCODE_H265_CTB_SIZE_64_BIT_KHR;
if (qp_map_av1_props)
qp_map_av1_props->compatibleSuperblockSizes = VK_VIDEO_ENCODE_AV1_SUPERBLOCK_SIZE_64_BIT_KHR;
}
}
}
}

View file

@ -1845,8 +1845,9 @@ radv_enc_params(struct radv_cmd_buffer *cmd_buffer, const VkVideoEncodeInfoKHR *
uint64_t va = src_img->bindings[0].addr;
uint64_t luma_va = va + src_img->planes[0].surface.u.gfx9.surf_offset +
array_idx * src_img->planes[0].surface.u.gfx9.surf_slice_size;
uint64_t chroma_va = va + src_img->planes[1].surface.u.gfx9.surf_offset +
array_idx * src_img->planes[1].surface.u.gfx9.surf_slice_size;
uint64_t chroma_va = src_img->plane_count > 1 ? (va + src_img->planes[1].surface.u.gfx9.surf_offset +
array_idx * src_img->planes[1].surface.u.gfx9.surf_slice_size)
: 0;
uint32_t pic_type;
unsigned int slot_idx = 0xffffffff;
unsigned int max_layers = cmd_buffer->video.vid->rc_layer_control.max_num_temporal_layers;
@ -1903,7 +1904,7 @@ radv_enc_params(struct radv_cmd_buffer *cmd_buffer, const VkVideoEncodeInfoKHR *
RADEON_ENC_CS(chroma_va >> 32);
RADEON_ENC_CS(chroma_va & 0xffffffff);
RADEON_ENC_CS(src_img->planes[0].surface.u.gfx9.surf_pitch); // luma pitch
RADEON_ENC_CS(src_img->planes[1].surface.u.gfx9.surf_pitch); // chroma pitch
RADEON_ENC_CS(src_img->plane_count > 1 ? src_img->planes[1].surface.u.gfx9.surf_pitch : 0); // chroma pitch
RADEON_ENC_CS(src_img->planes[0].surface.u.gfx9.swizzle_mode); // swizzle mode
if (pdev->enc_hw_ver < RADV_VIDEO_ENC_HW_5)
@ -2103,35 +2104,109 @@ radv_enc_op_preset(struct radv_cmd_buffer *cmd_buffer, const VkVideoEncodeInfoKH
RADEON_ENC_END();
}
static uint32_t
radv_get_encode_color_volume(VkVideoEncodeRgbModelConversionFlagBitsVALVE model)
{
switch (model) {
case VK_VIDEO_ENCODE_RGB_MODEL_CONVERSION_YCBCR_709_BIT_VALVE:
return RENCODE_COLOR_VOLUME_G22_BT709;
case VK_VIDEO_ENCODE_RGB_MODEL_CONVERSION_YCBCR_2020_BIT_VALVE:
return RENCODE_COLOR_VOLUME_G2084_BT2020;
default:
UNREACHABLE("Unsupported rgb model conversion.");
}
}
static uint32_t
radv_get_encode_color_range(VkVideoEncodeRgbRangeCompressionFlagBitsVALVE range)
{
switch (range) {
case VK_VIDEO_ENCODE_RGB_RANGE_COMPRESSION_FULL_RANGE_BIT_VALVE:
return RENCODE_COLOR_RANGE_FULL;
case VK_VIDEO_ENCODE_RGB_RANGE_COMPRESSION_NARROW_RANGE_BIT_VALVE:
return RENCODE_COLOR_RANGE_STUDIO;
default:
UNREACHABLE("Unsupported rgb range compression.");
}
}
static uint32_t
radv_get_encode_chroma_location(VkVideoEncodeRgbChromaOffsetFlagBitsVALVE location)
{
switch (location) {
case VK_VIDEO_ENCODE_RGB_CHROMA_OFFSET_COSITED_EVEN_BIT_VALVE:
return RENCODE_CHROMA_LOCATION_CO_SITE;
case VK_VIDEO_ENCODE_RGB_CHROMA_OFFSET_MIDPOINT_BIT_VALVE:
return RENCODE_CHROMA_LOCATION_INTERSTITIAL;
default:
UNREACHABLE("Unsupported chroma offset.");
}
}
static void
radv_enc_input_format(struct radv_cmd_buffer *cmd_buffer)
{
struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
const struct radv_physical_device *pdev = radv_device_physical(device);
struct radv_video_session *vid = cmd_buffer->video.vid;
uint32_t color_space;
uint32_t color_bit_depth;
uint32_t color_packing_format;
uint32_t chroma_subsampling;
switch (vid->vk.picture_format) {
case VK_FORMAT_B8G8R8A8_UNORM:
color_bit_depth = RENCODE_COLOR_BIT_DEPTH_8_BIT;
color_packing_format = RENCODE_COLOR_PACKING_FORMAT_A8R8G8B8;
chroma_subsampling = RENCODE_CHROMA_SUBSAMPLING_4_4_4;
color_space = RENCODE_COLOR_SPACE_RGB;
break;
case VK_FORMAT_R8G8B8A8_UNORM:
color_bit_depth = RENCODE_COLOR_BIT_DEPTH_8_BIT;
color_packing_format = RENCODE_COLOR_PACKING_FORMAT_A8B8G8R8;
chroma_subsampling = RENCODE_CHROMA_SUBSAMPLING_4_4_4;
color_space = RENCODE_COLOR_SPACE_RGB;
break;
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
color_bit_depth = RENCODE_COLOR_BIT_DEPTH_10_BIT;
color_packing_format = RENCODE_COLOR_PACKING_FORMAT_A2B10G10R10;
chroma_subsampling = RENCODE_CHROMA_SUBSAMPLING_4_4_4;
color_space = RENCODE_COLOR_SPACE_RGB;
break;
case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
color_bit_depth = RENCODE_COLOR_BIT_DEPTH_10_BIT;
color_packing_format = RENCODE_COLOR_PACKING_FORMAT_A2R10G10B10;
chroma_subsampling = RENCODE_CHROMA_SUBSAMPLING_4_4_4;
color_space = RENCODE_COLOR_SPACE_RGB;
break;
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
color_bit_depth = RENCODE_COLOR_BIT_DEPTH_8_BIT;
color_packing_format = RENCODE_COLOR_PACKING_FORMAT_NV12;
chroma_subsampling = RENCODE_CHROMA_SUBSAMPLING_4_2_0;
color_space = RENCODE_COLOR_SPACE_YUV;
break;
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
color_bit_depth = RENCODE_COLOR_BIT_DEPTH_10_BIT;
color_packing_format = RENCODE_COLOR_PACKING_FORMAT_P010;
chroma_subsampling = RENCODE_CHROMA_SUBSAMPLING_4_2_0;
color_space = RENCODE_COLOR_SPACE_YUV;
break;
default:
assert(0);
return;
}
// Color volume should match between input and output
uint32_t color_volume = RENCODE_COLOR_VOLUME_G22_BT709;
if (vid->vk.perform_rgb_conversion)
color_volume = radv_get_encode_color_volume(vid->vk.rgb_conv.rgb_model);
RADEON_ENC_BEGIN(pdev->vcn_enc_cmds.input_format);
RADEON_ENC_CS(0); // input color volume
RADEON_ENC_CS(0); // input color space
RADEON_ENC_CS(RENCODE_COLOR_RANGE_STUDIO); // input color range
RADEON_ENC_CS(0); // input chroma subsampling
RADEON_ENC_CS(0); // input chroma location
RADEON_ENC_CS(color_volume); // input color volume
RADEON_ENC_CS(color_space); // input color space
RADEON_ENC_CS(0); // input color range (ignored)
RADEON_ENC_CS(chroma_subsampling); // input chroma subsampling
RADEON_ENC_CS(0); // input chroma location (ignored for RGB)
RADEON_ENC_CS(color_bit_depth); // input color bit depth
RADEON_ENC_CS(color_packing_format); // input color packing format
RADEON_ENC_END();
@ -2166,12 +2241,21 @@ radv_enc_output_format(struct radv_cmd_buffer *cmd_buffer)
return;
}
uint32_t color_volume = 0;
uint32_t color_range = RENCODE_COLOR_RANGE_STUDIO;
uint32_t chroma_location = 0;
if (vid->vk.perform_rgb_conversion) {
color_volume = radv_get_encode_color_volume(vid->vk.rgb_conv.rgb_model);
color_range = radv_get_encode_color_range(vid->vk.rgb_conv.rgb_range);
chroma_location = radv_get_encode_chroma_location(vid->vk.rgb_conv.y_chroma_offset);
}
RADEON_ENC_BEGIN(pdev->vcn_enc_cmds.output_format);
RADEON_ENC_CS(0); // output color volume
RADEON_ENC_CS(RENCODE_COLOR_RANGE_STUDIO); // output color range
RADEON_ENC_CS(color_volume); // output color volume
RADEON_ENC_CS(color_range); // output color range
if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5)
RADEON_ENC_CS(0); // output chroma subsampling
RADEON_ENC_CS(0); // output chroma location
RADEON_ENC_CS(chroma_location); // output chroma location
RADEON_ENC_CS(color_bit_depth); // output color bit depth
RADEON_ENC_END();
}

View file

@ -108,6 +108,8 @@ vk_video_session_init(struct vk_device *device,
vk_find_struct_const(create_info->pVideoProfile->pNext, VIDEO_ENCODE_USAGE_INFO_KHR);
const struct VkVideoEncodeSessionIntraRefreshCreateInfoKHR *intra_refresh =
vk_find_struct_const(create_info->pNext, VIDEO_ENCODE_SESSION_INTRA_REFRESH_CREATE_INFO_KHR);
const struct VkVideoEncodeProfileRgbConversionInfoVALVE *rgb_profile_info =
vk_find_struct_const(create_info->pVideoProfile->pNext, VIDEO_ENCODE_PROFILE_RGB_CONVERSION_INFO_VALVE);
if (encode_usage_profile) {
vid->enc_usage.video_usage_hints = encode_usage_profile->videoUsageHints;
vid->enc_usage.video_content_hints = encode_usage_profile->videoContentHints;
@ -119,6 +121,16 @@ vk_video_session_init(struct vk_device *device,
}
if (intra_refresh)
vid->intra_refresh_mode = intra_refresh->intraRefreshMode;
if (rgb_profile_info && rgb_profile_info->performEncodeRgbConversion) {
const struct VkVideoEncodeSessionRgbConversionCreateInfoVALVE *rgb_info =
vk_find_struct_const(create_info->pNext, VIDEO_ENCODE_SESSION_RGB_CONVERSION_CREATE_INFO_VALVE);
vid->perform_rgb_conversion = true;
vid->rgb_conv.rgb_model = rgb_info->rgbModel;
vid->rgb_conv.rgb_range = rgb_info->rgbRange;
vid->rgb_conv.x_chroma_offset = rgb_info->xChromaOffset;
vid->rgb_conv.y_chroma_offset = rgb_info->yChromaOffset;
}
}
return VK_SUCCESS;

View file

@ -91,6 +91,14 @@ struct vk_video_session {
uint32_t max_active_ref_pics;
VkVideoEncodeIntraRefreshModeFlagBitsKHR intra_refresh_mode;
bool perform_rgb_conversion;
struct {
VkVideoEncodeRgbModelConversionFlagBitsVALVE rgb_model;
VkVideoEncodeRgbRangeCompressionFlagBitsVALVE rgb_range;
VkVideoEncodeRgbChromaOffsetFlagBitsVALVE x_chroma_offset;
VkVideoEncodeRgbChromaOffsetFlagBitsVALVE y_chroma_offset;
} rgb_conv;
struct {
VkVideoEncodeUsageFlagsKHR video_usage_hints;
VkVideoEncodeContentFlagsKHR video_content_hints;