aboutsummaryrefslogtreecommitdiff
path: root/icd/generated/function_definitions.h
diff options
context:
space:
mode:
authorDaniel Rakos <daniel.rakos@rastergrid.com>2023-12-20 13:48:52 +0100
committerSpencer Fricke <115671160+spencer-lunarg@users.noreply.github.com>2023-12-21 00:40:41 +0900
commit87130b22e74cb208bf8ecd755dcf40dabd365dad (patch)
tree6e164d21772a4af8f364db655129d5153e35a2cf /icd/generated/function_definitions.h
parent64d9218726083ece79099341249890c75a5c4491 (diff)
downloadusermoji-87130b22e74cb208bf8ecd755dcf40dabd365dad.tar.xz
icd: Add video support
Diffstat (limited to 'icd/generated/function_definitions.h')
-rw-r--r--icd/generated/function_definitions.h578
1 files changed, 541 insertions, 37 deletions
diff --git a/icd/generated/function_definitions.h b/icd/generated/function_definitions.h
index 8da94ffb..555e355c 100644
--- a/icd/generated/function_definitions.h
+++ b/icd/generated/function_definitions.h
@@ -108,6 +108,14 @@ static VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties(
// Don't set color bits for DS formats
*pFormatProperties = { 0x00FFFE7F, 0x00FFFE7F, 0x00FFFE7F };
break;
+ case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+ case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
+ case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
+ case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
+ case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM:
+ // Set decode/encode bits for these formats
+ *pFormatProperties = { 0x1EFFFDFF, 0x1EFFFDFF, 0x00FFFDFF };
+ break;
default:
break;
}
@@ -160,15 +168,15 @@ static VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties(
uint32_t* pQueueFamilyPropertyCount,
VkQueueFamilyProperties* pQueueFamilyProperties)
{
- if (!pQueueFamilyProperties) {
- *pQueueFamilyPropertyCount = 1;
- } else {
- if (*pQueueFamilyPropertyCount) {
- pQueueFamilyProperties[0].queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT | VK_QUEUE_SPARSE_BINDING_BIT | VK_QUEUE_PROTECTED_BIT;
- pQueueFamilyProperties[0].queueCount = 1;
- pQueueFamilyProperties[0].timestampValidBits = 16;
- pQueueFamilyProperties[0].minImageTransferGranularity = {1,1,1};
+ if (pQueueFamilyProperties) {
+ std::vector<VkQueueFamilyProperties2KHR> props2(*pQueueFamilyPropertyCount, {
+ VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR});
+ GetPhysicalDeviceQueueFamilyProperties2KHR(physicalDevice, pQueueFamilyPropertyCount, props2.data());
+ for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; ++i) {
+ pQueueFamilyProperties[i] = props2[i].queueFamilyProperties;
}
+ } else {
+ GetPhysicalDeviceQueueFamilyProperties2KHR(physicalDevice, pQueueFamilyPropertyCount, nullptr);
}
}
@@ -2729,19 +2737,326 @@ static VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceVideoCapabilitiesKHR(
const VkVideoProfileInfoKHR* pVideoProfile,
VkVideoCapabilitiesKHR* pCapabilities)
{
- // arbitrary
- auto *decode_caps = lvl_find_mod_in_chain<VkVideoDecodeCapabilitiesKHR>(pCapabilities->pNext);
- if (decode_caps) {
- decode_caps->flags = VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR | VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR;
+ // We include some reasonable set of capability combinations to cover a wide range of use cases
+ auto caps = pCapabilities;
+ auto caps_decode = lvl_find_mod_in_chain<VkVideoDecodeCapabilitiesKHR>(pCapabilities->pNext);
+ auto caps_decode_h264 = lvl_find_mod_in_chain<VkVideoDecodeH264CapabilitiesKHR>(pCapabilities->pNext);
+ auto caps_decode_h265 = lvl_find_mod_in_chain<VkVideoDecodeH265CapabilitiesKHR>(pCapabilities->pNext);
+ auto caps_encode = lvl_find_mod_in_chain<VkVideoEncodeCapabilitiesKHR>(pCapabilities->pNext);
+ auto caps_encode_h264 = lvl_find_mod_in_chain<VkVideoEncodeH264CapabilitiesKHR>(pCapabilities->pNext);
+ auto caps_encode_h265 = lvl_find_mod_in_chain<VkVideoEncodeH265CapabilitiesKHR>(pCapabilities->pNext);
+
+ switch (pVideoProfile->videoCodecOperation) {
+ case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR: {
+ auto profile = lvl_find_in_chain<VkVideoDecodeH264ProfileInfoKHR>(pVideoProfile->pNext);
+ if (profile->stdProfileIdc != STD_VIDEO_H264_PROFILE_IDC_BASELINE &&
+ profile->stdProfileIdc != STD_VIDEO_H264_PROFILE_IDC_MAIN) {
+ return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR;
+ }
+
+ caps->flags = VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR;
+ caps->minBitstreamBufferOffsetAlignment = 256;
+ caps->minBitstreamBufferSizeAlignment = 256;
+ caps->pictureAccessGranularity = {16,16};
+ caps->minCodedExtent = {16,16};
+ caps->maxCodedExtent = {1920,1080};
+ caps->maxDpbSlots = 33;
+ caps->maxActiveReferencePictures = 32;
+ std::strncpy(caps->stdHeaderVersion.extensionName, VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_EXTENSION_NAME,
+ sizeof(caps->stdHeaderVersion.extensionName));
+ caps->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_SPEC_VERSION;
+
+ switch (pVideoProfile->chromaSubsampling) {
+ case VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR:
+ if (profile->pictureLayout != VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR) {
+ return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR;
+ }
+ caps_decode->flags = VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR;
+ caps_decode_h264->maxLevelIdc = STD_VIDEO_H264_LEVEL_IDC_6_2;
+ caps_decode_h264->fieldOffsetGranularity = {0,0};
+ break;
+ case VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR:
+ if (profile->pictureLayout != VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR &&
+ profile->pictureLayout != VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_SEPARATE_PLANES_BIT_KHR) {
+ return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR;
+ }
+ caps_decode->flags = VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR;
+ caps_decode_h264->maxLevelIdc = STD_VIDEO_H264_LEVEL_IDC_5_0;
+ caps_decode_h264->fieldOffsetGranularity = {0,16};
+ break;
+ case VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR:
+ if (profile->pictureLayout != VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR &&
+ profile->pictureLayout != VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR) {
+ return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR;
+ }
+ caps_decode->flags = VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR
+ | VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR;
+ caps_decode_h264->maxLevelIdc = STD_VIDEO_H264_LEVEL_IDC_3_2;
+ caps_decode_h264->fieldOffsetGranularity = {0,1};
+ break;
+ default:
+ return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR;
+ }
+ break;
+ }
+ case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR: {
+ auto profile = lvl_find_in_chain<VkVideoDecodeH265ProfileInfoKHR>(pVideoProfile->pNext);
+ if (profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN) {
+ return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR;
+ }
+
+ caps->flags = VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR;
+ caps->minBitstreamBufferOffsetAlignment = 64;
+ caps->minBitstreamBufferSizeAlignment = 64;
+ caps->pictureAccessGranularity = {32,32};
+ caps->minCodedExtent = {48,48};
+ caps->maxCodedExtent = {3840,2160};
+ caps->maxDpbSlots = 16;
+ caps->maxActiveReferencePictures = 15;
+ std::strncpy(caps->stdHeaderVersion.extensionName, VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_EXTENSION_NAME,
+ sizeof(caps->stdHeaderVersion.extensionName));
+ caps->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_SPEC_VERSION;
+
+ switch (pVideoProfile->chromaSubsampling) {
+ case VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR:
+ caps_decode->flags = VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR;
+ caps_decode_h265->maxLevelIdc = STD_VIDEO_H265_LEVEL_IDC_6_0;
+ break;
+ case VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR:
+ caps_decode->flags = VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR;
+ caps_decode_h265->maxLevelIdc = STD_VIDEO_H265_LEVEL_IDC_5_2;
+ break;
+ case VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR:
+ caps_decode->flags = VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR
+ | VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR;
+ caps_decode_h265->maxLevelIdc = STD_VIDEO_H265_LEVEL_IDC_4_1;
+ break;
+ default:
+ return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR;
+ }
+ break;
+ }
+ case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR: {
+ auto profile = lvl_find_in_chain<VkVideoEncodeH264ProfileInfoKHR>(pVideoProfile->pNext);
+ if (profile->stdProfileIdc != STD_VIDEO_H264_PROFILE_IDC_BASELINE) {
+ return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR;
+ }
+
+ caps->flags = VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR;
+ caps->minBitstreamBufferOffsetAlignment = 4096;
+ caps->minBitstreamBufferSizeAlignment = 4096;
+ caps->pictureAccessGranularity = {16,16};
+ caps->minCodedExtent = {160,128};
+ caps->maxCodedExtent = {1920,1080};
+ caps->maxDpbSlots = 10;
+ caps->maxActiveReferencePictures = 4;
+ std::strncpy(caps->stdHeaderVersion.extensionName, VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_EXTENSION_NAME,
+ sizeof(caps->stdHeaderVersion.extensionName));
+ caps->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_SPEC_VERSION;
+
+ switch (pVideoProfile->chromaSubsampling) {
+ case VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR:
+ caps_encode->flags = VK_VIDEO_ENCODE_CAPABILITY_PRECEDING_EXTERNALLY_ENCODED_BYTES_BIT_KHR;
+ caps_encode->rateControlModes = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR
+ | VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR
+ | VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR;
+ caps_encode->maxRateControlLayers = 4;
+ caps_encode->maxBitrate = 800000000;
+ caps_encode->maxQualityLevels = 4;
+ caps_encode->encodeInputPictureGranularity = {16,16};
+ caps_encode->supportedEncodeFeedbackFlags = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR
+ | VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR
+ | VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_HAS_OVERRIDES_BIT_KHR;
+ caps_encode_h264->flags = VK_VIDEO_ENCODE_H264_CAPABILITY_HRD_COMPLIANCE_BIT_KHR
+ | VK_VIDEO_ENCODE_H264_CAPABILITY_PREDICTION_WEIGHT_TABLE_GENERATED_BIT_KHR
+ | VK_VIDEO_ENCODE_H264_CAPABILITY_ROW_UNALIGNED_SLICE_BIT_KHR
+ | VK_VIDEO_ENCODE_H264_CAPABILITY_B_FRAME_IN_L0_LIST_BIT_KHR
+ | VK_VIDEO_ENCODE_H264_CAPABILITY_PER_PICTURE_TYPE_MIN_MAX_QP_BIT_KHR
+ | VK_VIDEO_ENCODE_H264_CAPABILITY_GENERATE_PREFIX_NALU_BIT_KHR;
+ caps_encode_h264->maxLevelIdc = STD_VIDEO_H264_LEVEL_IDC_6_2;
+ caps_encode_h264->maxSliceCount = 8;
+ caps_encode_h264->maxPPictureL0ReferenceCount = 4;
+ caps_encode_h264->maxBPictureL0ReferenceCount = 3;
+ caps_encode_h264->maxL1ReferenceCount = 2;
+ caps_encode_h264->maxTemporalLayerCount = 4;
+ caps_encode_h264->expectDyadicTemporalLayerPattern = VK_FALSE;
+ caps_encode_h264->minQp = 0;
+ caps_encode_h264->maxQp = 51;
+ caps_encode_h264->prefersGopRemainingFrames = VK_FALSE;
+ caps_encode_h264->requiresGopRemainingFrames = VK_FALSE;
+ break;
+ case VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR:
+ caps_encode->flags = VK_VIDEO_ENCODE_CAPABILITY_PRECEDING_EXTERNALLY_ENCODED_BYTES_BIT_KHR;
+ caps_encode->rateControlModes = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR
+ | VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR;
+ caps_encode->maxRateControlLayers = 1;
+ caps_encode->maxBitrate = 480000000;
+ caps_encode->maxQualityLevels = 3;
+ caps_encode->encodeInputPictureGranularity = {32,32};
+ caps_encode->supportedEncodeFeedbackFlags = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR
+ | VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR;
+ caps_encode_h264->flags = VK_VIDEO_ENCODE_H264_CAPABILITY_DIFFERENT_SLICE_TYPE_BIT_KHR
+ | VK_VIDEO_ENCODE_H264_CAPABILITY_PER_SLICE_CONSTANT_QP_BIT_KHR
+ | VK_VIDEO_ENCODE_H264_CAPABILITY_GENERATE_PREFIX_NALU_BIT_KHR;
+ caps_encode_h264->maxLevelIdc = STD_VIDEO_H264_LEVEL_IDC_6_1;
+ caps_encode_h264->maxSliceCount = 4;
+ caps_encode_h264->maxPPictureL0ReferenceCount = 4;
+ caps_encode_h264->maxBPictureL0ReferenceCount = 0;
+ caps_encode_h264->maxL1ReferenceCount = 0;
+ caps_encode_h264->maxTemporalLayerCount = 4;
+ caps_encode_h264->expectDyadicTemporalLayerPattern = VK_TRUE;
+ caps_encode_h264->minQp = 0;
+ caps_encode_h264->maxQp = 30;
+ caps_encode_h264->prefersGopRemainingFrames = VK_TRUE;
+ caps_encode_h264->requiresGopRemainingFrames = VK_FALSE;
+ break;
+ case VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR:
+ caps_encode->flags = 0;
+ caps_encode->rateControlModes = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR;
+ caps_encode->maxRateControlLayers = 1;
+ caps_encode->maxBitrate = 240000000;
+ caps_encode->maxQualityLevels = 1;
+ caps_encode->encodeInputPictureGranularity = {1,1};
+ caps_encode->supportedEncodeFeedbackFlags = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR
+ | VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR;
+ caps_encode_h264->flags = VK_VIDEO_ENCODE_H264_CAPABILITY_ROW_UNALIGNED_SLICE_BIT_KHR
+ | VK_VIDEO_ENCODE_H264_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_KHR
+ | VK_VIDEO_ENCODE_H264_CAPABILITY_PER_PICTURE_TYPE_MIN_MAX_QP_BIT_KHR;
+ caps_encode_h264->maxLevelIdc = STD_VIDEO_H264_LEVEL_IDC_5_1;
+ caps_encode_h264->maxSliceCount = 1;
+ caps_encode_h264->maxPPictureL0ReferenceCount = 0;
+ caps_encode_h264->maxBPictureL0ReferenceCount = 2;
+ caps_encode_h264->maxL1ReferenceCount = 2;
+ caps_encode_h264->maxTemporalLayerCount = 1;
+ caps_encode_h264->expectDyadicTemporalLayerPattern = VK_FALSE;
+ caps_encode_h264->minQp = 5;
+ caps_encode_h264->maxQp = 40;
+ caps_encode_h264->prefersGopRemainingFrames = VK_TRUE;
+ caps_encode_h264->requiresGopRemainingFrames = VK_TRUE;
+ break;
+ default:
+ return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR;
+ }
+ break;
+ }
+ case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR: {
+ auto profile = lvl_find_in_chain<VkVideoEncodeH265ProfileInfoKHR>(pVideoProfile->pNext);
+ if (profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN) {
+ return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR;
+ }
+
+ caps->flags = VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR;
+ caps->minBitstreamBufferOffsetAlignment = 1;
+ caps->minBitstreamBufferSizeAlignment = 1;
+ caps->pictureAccessGranularity = {8,8};
+ caps->minCodedExtent = {64,48};
+ caps->maxCodedExtent = {4096,2560};
+ caps->maxDpbSlots = 8;
+ caps->maxActiveReferencePictures = 2;
+ std::strncpy(caps->stdHeaderVersion.extensionName, VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_EXTENSION_NAME, sizeof(caps->stdHeaderVersion.extensionName));
+ caps->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_SPEC_VERSION;
+
+ switch (pVideoProfile->chromaSubsampling) {
+ case VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR:
+ caps_encode->flags = 0;
+ caps_encode->rateControlModes = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR;
+ caps_encode->maxRateControlLayers = 1;
+ caps_encode->maxBitrate = 800000000;
+ caps_encode->maxQualityLevels = 1;
+ caps_encode->encodeInputPictureGranularity = {64,64};
+ caps_encode->supportedEncodeFeedbackFlags = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR
+ | VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR;
+ caps_encode_h265->flags = VK_VIDEO_ENCODE_H265_CAPABILITY_HRD_COMPLIANCE_BIT_KHR
+ | VK_VIDEO_ENCODE_H265_CAPABILITY_PREDICTION_WEIGHT_TABLE_GENERATED_BIT_KHR
+ | VK_VIDEO_ENCODE_H265_CAPABILITY_ROW_UNALIGNED_SLICE_SEGMENT_BIT_KHR
+ | VK_VIDEO_ENCODE_H265_CAPABILITY_B_FRAME_IN_L0_LIST_BIT_KHR
+ | VK_VIDEO_ENCODE_H265_CAPABILITY_PER_SLICE_SEGMENT_CONSTANT_QP_BIT_KHR
+ | VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_SLICE_SEGMENTS_PER_TILE_BIT_KHR;
+ caps_encode_h265->maxLevelIdc = STD_VIDEO_H265_LEVEL_IDC_6_2;
+ caps_encode_h265->maxSliceSegmentCount = 8;
+ caps_encode_h265->maxTiles = {1,1};
+ caps_encode_h265->ctbSizes = VK_VIDEO_ENCODE_H265_CTB_SIZE_32_BIT_KHR
+ | VK_VIDEO_ENCODE_H265_CTB_SIZE_64_BIT_KHR;
+ caps_encode_h265->transformBlockSizes = VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_4_BIT_KHR
+ | VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_8_BIT_KHR
+ | VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_32_BIT_KHR;
+ caps_encode_h265->maxPPictureL0ReferenceCount = 4;
+ caps_encode_h265->maxBPictureL0ReferenceCount = 3;
+ caps_encode_h265->maxL1ReferenceCount = 2;
+ caps_encode_h265->maxSubLayerCount = 1;
+ caps_encode_h265->expectDyadicTemporalSubLayerPattern = VK_FALSE;
+ caps_encode_h265->minQp = 16;
+ caps_encode_h265->maxQp = 32;
+ caps_encode_h265->prefersGopRemainingFrames = VK_FALSE;
+ caps_encode_h265->requiresGopRemainingFrames = VK_FALSE;
+ break;
+ case VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR:
+ caps_encode->flags = 0;
+ caps_encode->rateControlModes = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
+ caps_encode->maxRateControlLayers = 0;
+ caps_encode->maxBitrate = 480000000;
+ caps_encode->maxQualityLevels = 2;
+ caps_encode->encodeInputPictureGranularity = {32,32};
+ caps_encode->supportedEncodeFeedbackFlags = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR
+ | VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR;
+ caps_encode_h265->flags = VK_VIDEO_ENCODE_H265_CAPABILITY_DIFFERENT_SLICE_SEGMENT_TYPE_BIT_KHR;
+ caps_encode_h265->maxLevelIdc = STD_VIDEO_H265_LEVEL_IDC_6_1;
+ caps_encode_h265->maxSliceSegmentCount = 4;
+ caps_encode_h265->maxTiles = {2,2};
+ caps_encode_h265->ctbSizes = VK_VIDEO_ENCODE_H265_CTB_SIZE_16_BIT_KHR
+ | VK_VIDEO_ENCODE_H265_CTB_SIZE_64_BIT_KHR;
+ caps_encode_h265->transformBlockSizes = VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_8_BIT_KHR
+ | VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_16_BIT_KHR
+ | VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_32_BIT_KHR;
+ caps_encode_h265->maxPPictureL0ReferenceCount = 4;
+ caps_encode_h265->maxBPictureL0ReferenceCount = 0;
+ caps_encode_h265->maxL1ReferenceCount = 0;
+ caps_encode_h265->maxSubLayerCount = 1;
+ caps_encode_h265->expectDyadicTemporalSubLayerPattern = VK_FALSE;
+ caps_encode_h265->minQp = 0;
+ caps_encode_h265->maxQp = 51;
+ caps_encode_h265->prefersGopRemainingFrames = VK_TRUE;
+ caps_encode_h265->requiresGopRemainingFrames = VK_FALSE;
+ break;
+ case VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR:
+ caps_encode->flags = VK_VIDEO_ENCODE_CAPABILITY_PRECEDING_EXTERNALLY_ENCODED_BYTES_BIT_KHR;
+ caps_encode->rateControlModes = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR
+ | VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR
+ | VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR;
+ caps_encode->maxRateControlLayers = 2;
+ caps_encode->maxBitrate = 240000000;
+ caps_encode->maxQualityLevels = 3;
+ caps_encode->encodeInputPictureGranularity = {16,16};
+ caps_encode->supportedEncodeFeedbackFlags = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR
+ | VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR
+ | VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_HAS_OVERRIDES_BIT_KHR;
+ caps_encode_h265->flags = VK_VIDEO_ENCODE_H265_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_KHR
+ | VK_VIDEO_ENCODE_H265_CAPABILITY_PER_PICTURE_TYPE_MIN_MAX_QP_BIT_KHR
+ | VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_TILES_PER_SLICE_SEGMENT_BIT_KHR;
+ caps_encode_h265->maxLevelIdc = STD_VIDEO_H265_LEVEL_IDC_5_1;
+ caps_encode_h265->maxSliceSegmentCount = 1;
+ caps_encode_h265->maxTiles = {2,2};
+ caps_encode_h265->ctbSizes = VK_VIDEO_ENCODE_H265_CTB_SIZE_32_BIT_KHR;
+ caps_encode_h265->transformBlockSizes = VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_32_BIT_KHR;
+ caps_encode_h265->maxPPictureL0ReferenceCount = 0;
+ caps_encode_h265->maxBPictureL0ReferenceCount = 2;
+ caps_encode_h265->maxL1ReferenceCount = 2;
+ caps_encode_h265->maxSubLayerCount = 4;
+ caps_encode_h265->expectDyadicTemporalSubLayerPattern = VK_TRUE;
+ caps_encode_h265->minQp = 16;
+ caps_encode_h265->maxQp = 51;
+ caps_encode_h265->prefersGopRemainingFrames = VK_TRUE;
+ caps_encode_h265->requiresGopRemainingFrames = VK_TRUE;
+ break;
+ default:
+ return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR;
+ }
+ break;
+ }
+
+ default:
+ break;
}
- pCapabilities->flags = 0;
- pCapabilities->minBitstreamBufferOffsetAlignment = 4;
- pCapabilities->minBitstreamBufferSizeAlignment = 4;
- pCapabilities->pictureAccessGranularity = {1, 1};
- pCapabilities->minCodedExtent = {4, 4};
- pCapabilities->maxCodedExtent = {16, 16};
- pCapabilities->maxDpbSlots = 4;
- pCapabilities->maxActiveReferencePictures = 4;
return VK_SUCCESS;
}
@@ -2751,22 +3066,147 @@ static VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceVideoFormatPropertiesKHR(
uint32_t* pVideoFormatPropertyCount,
VkVideoFormatPropertiesKHR* pVideoFormatProperties)
{
- if (!pVideoFormatProperties) {
- *pVideoFormatPropertyCount = 2;
- } else {
- // arbitrary
- pVideoFormatProperties[0].format = VK_FORMAT_R8G8B8A8_UNORM;
- pVideoFormatProperties[0].imageCreateFlags = VK_IMAGE_TYPE_2D;
- pVideoFormatProperties[0].imageType = VK_IMAGE_TYPE_2D;
- pVideoFormatProperties[0].imageTiling = VK_IMAGE_TILING_OPTIMAL;
- pVideoFormatProperties[0].imageUsageFlags = VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR | VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR | VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
- pVideoFormatProperties[1].format = VK_FORMAT_R8G8B8A8_SNORM;
- pVideoFormatProperties[1].imageCreateFlags = VK_IMAGE_TYPE_2D;
- pVideoFormatProperties[1].imageType = VK_IMAGE_TYPE_2D;
- pVideoFormatProperties[1].imageTiling = VK_IMAGE_TILING_OPTIMAL;
- pVideoFormatProperties[1].imageUsageFlags = VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR | VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR | VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
+ // We include some reasonable set of format combinations to cover a wide range of use cases
+ auto profile_list = lvl_find_in_chain<VkVideoProfileListInfoKHR>(pVideoFormatInfo->pNext);
+ if (profile_list->profileCount != 1) {
+ return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR;
+ }
+
+ std::vector<VkVideoFormatPropertiesKHR> format_props{};
+
+ VkVideoFormatPropertiesKHR props = {};
+ props.sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR;
+ props.imageCreateFlags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
+ | VK_IMAGE_CREATE_ALIAS_BIT
+ | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT
+ | VK_IMAGE_CREATE_PROTECTED_BIT
+ | VK_IMAGE_CREATE_DISJOINT_BIT;
+ props.imageType = VK_IMAGE_TYPE_2D;
+ props.imageTiling = VK_IMAGE_TILING_OPTIMAL;
+
+ switch (profile_list->pProfiles[0].videoCodecOperation) {
+ case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR:
+ case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR:
+ switch (profile_list->pProfiles[0].chromaSubsampling) {
+ case VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR:
+ props.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
+ props.imageUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
+ | VK_IMAGE_USAGE_TRANSFER_DST_BIT
+ | VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
+ format_props.push_back(props);
+ props.imageUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
+ | VK_IMAGE_USAGE_TRANSFER_DST_BIT
+ | VK_IMAGE_USAGE_SAMPLED_BIT
+ | VK_IMAGE_USAGE_STORAGE_BIT
+ | VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR
+ | VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR
+ | VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
+ format_props.push_back(props);
+ props.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
+ format_props.push_back(props);
+ break;
+ case VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR:
+ props.imageUsageFlags = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
+ props.format = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM;
+ format_props.push_back(props);
+ props.imageUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
+ | VK_IMAGE_USAGE_TRANSFER_DST_BIT
+ | VK_IMAGE_USAGE_SAMPLED_BIT
+ | VK_IMAGE_USAGE_STORAGE_BIT
+ | VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR
+ | VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
+ format_props.push_back(props);
+ props.format = VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16;
+ format_props.push_back(props);
+ break;
+ case VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR:
+ props.format = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM;
+ props.imageUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
+ | VK_IMAGE_USAGE_TRANSFER_DST_BIT
+ | VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
+ format_props.push_back(props);
+ props.imageUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
+ | VK_IMAGE_USAGE_TRANSFER_DST_BIT
+ | VK_IMAGE_USAGE_SAMPLED_BIT
+ | VK_IMAGE_USAGE_STORAGE_BIT
+ | VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR
+ | VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR
+ | VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
+ format_props.push_back(props);
+ break;
+ default:
+ return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR;
+ }
+ break;
+ case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR:
+ case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR:
+ switch (profile_list->pProfiles[0].chromaSubsampling) {
+ case VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR:
+ props.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
+ props.imageUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
+ | VK_IMAGE_USAGE_TRANSFER_DST_BIT
+ | VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR;
+ format_props.push_back(props);
+ props.imageUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
+ | VK_IMAGE_USAGE_TRANSFER_DST_BIT
+ | VK_IMAGE_USAGE_SAMPLED_BIT
+ | VK_IMAGE_USAGE_STORAGE_BIT
+ | VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR
+ | VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
+ format_props.push_back(props);
+ props.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
+ format_props.push_back(props);
+ break;
+ case VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR:
+ props.format = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM;
+ props.imageUsageFlags = VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR;
+ format_props.push_back(props);
+ props.imageUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
+ | VK_IMAGE_USAGE_TRANSFER_DST_BIT
+ | VK_IMAGE_USAGE_SAMPLED_BIT
+ | VK_IMAGE_USAGE_STORAGE_BIT
+ | VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR
+ | VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
+ format_props.push_back(props);
+ props.format = VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16;
+ format_props.push_back(props);
+ break;
+ case VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR:
+ props.format = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM;
+ props.imageUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
+ | VK_IMAGE_USAGE_TRANSFER_DST_BIT
+ | VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR;
+ format_props.push_back(props);
+ props.imageUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
+ | VK_IMAGE_USAGE_TRANSFER_DST_BIT
+ | VK_IMAGE_USAGE_SAMPLED_BIT
+ | VK_IMAGE_USAGE_STORAGE_BIT
+ | VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR
+ | VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
+ format_props.push_back(props);
+ break;
+ default:
+ return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ std::vector<VkVideoFormatPropertiesKHR> filtered_props;
+ for (const auto& fmt_props : format_props) {
+ if ((pVideoFormatInfo->imageUsage & fmt_props.imageUsageFlags) == pVideoFormatInfo->imageUsage) {
+ filtered_props.push_back(fmt_props);
+ }
+ }
+ if (pVideoFormatProperties != nullptr) {
+ for (uint32_t i = 0; i < (std::min)(*pVideoFormatPropertyCount, (uint32_t)filtered_props.size()); ++i) {
+ pVideoFormatProperties[i] = filtered_props[i];
+ }
}
+ *pVideoFormatPropertyCount = (uint32_t)filtered_props.size();
return VK_SUCCESS;
}
@@ -2900,6 +3340,26 @@ static VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures2KHR(
GetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
uint32_t num_bools = 0; // Count number of VkBool32s in extension structs
VkBool32* feat_bools = nullptr;
+ auto vk_1_1_features = lvl_find_mod_in_chain<VkPhysicalDeviceVulkan11Features>(pFeatures->pNext);
+ if (vk_1_1_features) {
+ vk_1_1_features->protectedMemory = VK_TRUE;
+ }
+ auto vk_1_3_features = lvl_find_mod_in_chain<VkPhysicalDeviceVulkan13Features>(pFeatures->pNext);
+ if (vk_1_3_features) {
+ vk_1_3_features->synchronization2 = VK_TRUE;
+ }
+ auto prot_features = lvl_find_mod_in_chain<VkPhysicalDeviceProtectedMemoryFeatures>(pFeatures->pNext);
+ if (prot_features) {
+ prot_features->protectedMemory = VK_TRUE;
+ }
+ auto sync2_features = lvl_find_mod_in_chain<VkPhysicalDeviceSynchronization2FeaturesKHR>(pFeatures->pNext);
+ if (sync2_features) {
+ sync2_features->synchronization2 = VK_TRUE;
+ }
+ auto video_maintenance1_features = lvl_find_mod_in_chain<VkPhysicalDeviceVideoMaintenance1FeaturesKHR>(pFeatures->pNext);
+ if (video_maintenance1_features) {
+ video_maintenance1_features->videoMaintenance1 = VK_TRUE;
+ }
const auto *desc_idx_features = lvl_find_in_chain<VkPhysicalDeviceDescriptorIndexingFeaturesEXT>(pFeatures->pNext);
if (desc_idx_features) {
const auto bool_size = sizeof(VkPhysicalDeviceDescriptorIndexingFeaturesEXT) - offsetof(VkPhysicalDeviceDescriptorIndexingFeaturesEXT, shaderInputAttachmentArrayDynamicIndexing);
@@ -3090,10 +3550,54 @@ static VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties2KHR(
uint32_t* pQueueFamilyPropertyCount,
VkQueueFamilyProperties2* pQueueFamilyProperties)
{
- if (pQueueFamilyPropertyCount && pQueueFamilyProperties) {
- GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, &pQueueFamilyProperties->queueFamilyProperties);
+ if (pQueueFamilyProperties) {
+ if (*pQueueFamilyPropertyCount >= 1) {
+ auto props = &pQueueFamilyProperties[0].queueFamilyProperties;
+ props->queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT
+ | VK_QUEUE_SPARSE_BINDING_BIT | VK_QUEUE_PROTECTED_BIT;
+ props->queueCount = 1;
+ props->timestampValidBits = 16;
+ props->minImageTransferGranularity = {1,1,1};
+ }
+ if (*pQueueFamilyPropertyCount >= 2) {
+ auto props = &pQueueFamilyProperties[1].queueFamilyProperties;
+ props->queueFlags = VK_QUEUE_TRANSFER_BIT | VK_QUEUE_PROTECTED_BIT | VK_QUEUE_VIDEO_DECODE_BIT_KHR;
+ props->queueCount = 1;
+ props->timestampValidBits = 16;
+ props->minImageTransferGranularity = {1,1,1};
+
+ auto status_query_props = lvl_find_mod_in_chain<VkQueueFamilyQueryResultStatusPropertiesKHR>(pQueueFamilyProperties[1].pNext);
+ if (status_query_props) {
+ status_query_props->queryResultStatusSupport = VK_TRUE;
+ }
+ auto video_props = lvl_find_mod_in_chain<VkQueueFamilyVideoPropertiesKHR>(pQueueFamilyProperties[1].pNext);
+ if (video_props) {
+ video_props->videoCodecOperations = VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR
+ | VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR;
+ }
+ }
+ if (*pQueueFamilyPropertyCount >= 3) {
+ auto props = &pQueueFamilyProperties[2].queueFamilyProperties;
+ props->queueFlags = VK_QUEUE_TRANSFER_BIT | VK_QUEUE_PROTECTED_BIT | VK_QUEUE_VIDEO_ENCODE_BIT_KHR;
+ props->queueCount = 1;
+ props->timestampValidBits = 16;
+ props->minImageTransferGranularity = {1,1,1};
+
+ auto status_query_props = lvl_find_mod_in_chain<VkQueueFamilyQueryResultStatusPropertiesKHR>(pQueueFamilyProperties[2].pNext);
+ if (status_query_props) {
+ status_query_props->queryResultStatusSupport = VK_TRUE;
+ }
+ auto video_props = lvl_find_mod_in_chain<VkQueueFamilyVideoPropertiesKHR>(pQueueFamilyProperties[2].pNext);
+ if (video_props) {
+ video_props->videoCodecOperations = VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR
+ | VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR;
+ }
+ }
+ if (*pQueueFamilyPropertyCount > 3) {
+ *pQueueFamilyPropertyCount = 3;
+ }
} else {
- GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, nullptr);
+ *pQueueFamilyPropertyCount = 3;
}
}