diff options
| author | Daniel Rakos <daniel.rakos@rastergrid.com> | 2023-12-20 13:48:52 +0100 |
|---|---|---|
| committer | Spencer Fricke <115671160+spencer-lunarg@users.noreply.github.com> | 2023-12-21 00:40:41 +0900 |
| commit | 87130b22e74cb208bf8ecd755dcf40dabd365dad (patch) | |
| tree | 6e164d21772a4af8f364db655129d5153e35a2cf /icd/generated/function_definitions.h | |
| parent | 64d9218726083ece79099341249890c75a5c4491 (diff) | |
| download | usermoji-87130b22e74cb208bf8ecd755dcf40dabd365dad.tar.xz | |
icd: Add video support
Diffstat (limited to 'icd/generated/function_definitions.h')
| -rw-r--r-- | icd/generated/function_definitions.h | 578 |
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; } } |
