1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------ 2e5c31af7Sopenharmony_ci* Vulkan Conformance Tests 3e5c31af7Sopenharmony_ci* ------------------------ 4e5c31af7Sopenharmony_ci* 5e5c31af7Sopenharmony_ci* Copyright (c) 2023 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci* 7e5c31af7Sopenharmony_ci* Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci* you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci* You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci* 11e5c31af7Sopenharmony_ci* http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci* 13e5c31af7Sopenharmony_ci* Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci* distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci* See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci* limitations under the License. 18e5c31af7Sopenharmony_ci* 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci* \file 21e5c31af7Sopenharmony_ci* \brief Video framebuffer 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci/* 24e5c31af7Sopenharmony_ci* Copyright 2020 NVIDIA Corporation. 25e5c31af7Sopenharmony_ci* 26e5c31af7Sopenharmony_ci* Licensed under the Apache License, Version 2.0 (the "License"); 27e5c31af7Sopenharmony_ci* you may not use this file except in compliance with the License. 28e5c31af7Sopenharmony_ci* You may obtain a copy of the License at 29e5c31af7Sopenharmony_ci* 30e5c31af7Sopenharmony_ci* http://www.apache.org/licenses/LICENSE-2.0 31e5c31af7Sopenharmony_ci* 32e5c31af7Sopenharmony_ci* Unless required by applicable law or agreed to in writing, software 33e5c31af7Sopenharmony_ci* distributed under the License is distributed on an "AS IS" BASIS, 34e5c31af7Sopenharmony_ci* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 35e5c31af7Sopenharmony_ci* See the License for the specific language governing permissions and 36e5c31af7Sopenharmony_ci* limitations under the License. 37e5c31af7Sopenharmony_ci */ 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_ci#include "vktVideoFrameBuffer.hpp" 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_ci#include <queue> 42e5c31af7Sopenharmony_ci 43e5c31af7Sopenharmony_cinamespace vkt 44e5c31af7Sopenharmony_ci{ 45e5c31af7Sopenharmony_cinamespace video 46e5c31af7Sopenharmony_ci{ 47e5c31af7Sopenharmony_cistatic VkSharedBaseObj<VkImageResourceView> emptyImageView; 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_ciclass NvPerFrameDecodeResources : public vkPicBuffBase { 50e5c31af7Sopenharmony_cipublic: 51e5c31af7Sopenharmony_ci NvPerFrameDecodeResources() 52e5c31af7Sopenharmony_ci : m_picDispInfo() 53e5c31af7Sopenharmony_ci , m_frameCompleteFence(VK_NULL_HANDLE) 54e5c31af7Sopenharmony_ci , m_frameCompleteSemaphore(VK_NULL_HANDLE) 55e5c31af7Sopenharmony_ci , m_frameConsumerDoneFence(VK_NULL_HANDLE) 56e5c31af7Sopenharmony_ci , m_frameConsumerDoneSemaphore(VK_NULL_HANDLE) 57e5c31af7Sopenharmony_ci , m_hasFrameCompleteSignalFence(false) 58e5c31af7Sopenharmony_ci , m_hasFrameCompleteSignalSemaphore(false) 59e5c31af7Sopenharmony_ci , m_hasConsummerSignalFence(false) 60e5c31af7Sopenharmony_ci , m_hasConsummerSignalSemaphore(false) 61e5c31af7Sopenharmony_ci , m_recreateImage(false) 62e5c31af7Sopenharmony_ci , m_currentDpbImageLayerLayout(VK_IMAGE_LAYOUT_UNDEFINED) 63e5c31af7Sopenharmony_ci , m_currentOutputImageLayout(VK_IMAGE_LAYOUT_UNDEFINED) 64e5c31af7Sopenharmony_ci , m_vkDevCtx(nullptr) 65e5c31af7Sopenharmony_ci , m_frameDpbImageView(VK_NULL_HANDLE) 66e5c31af7Sopenharmony_ci , m_outImageView(VK_NULL_HANDLE) 67e5c31af7Sopenharmony_ci { 68e5c31af7Sopenharmony_ci } 69e5c31af7Sopenharmony_ci 70e5c31af7Sopenharmony_ci VkResult CreateImage( DeviceContext& vkDevCtx, 71e5c31af7Sopenharmony_ci const VkImageCreateInfo* pDpbImageCreateInfo, 72e5c31af7Sopenharmony_ci const VkImageCreateInfo* pOutImageCreateInfo, 73e5c31af7Sopenharmony_ci deUint32 imageIndex, 74e5c31af7Sopenharmony_ci VkSharedBaseObj<VkImageResource>& imageArrayParent, 75e5c31af7Sopenharmony_ci VkSharedBaseObj<VkImageResourceView>& imageViewArrayParent, 76e5c31af7Sopenharmony_ci bool useSeparateOutputImage = false, 77e5c31af7Sopenharmony_ci bool useLinearOutput = false); 78e5c31af7Sopenharmony_ci 79e5c31af7Sopenharmony_ci VkResult init(DeviceContext& vkDevCtx); 80e5c31af7Sopenharmony_ci 81e5c31af7Sopenharmony_ci void Deinit(); 82e5c31af7Sopenharmony_ci 83e5c31af7Sopenharmony_ci NvPerFrameDecodeResources (const NvPerFrameDecodeResources &srcObj) = delete; 84e5c31af7Sopenharmony_ci NvPerFrameDecodeResources (NvPerFrameDecodeResources &&srcObj) = delete; 85e5c31af7Sopenharmony_ci 86e5c31af7Sopenharmony_ci ~NvPerFrameDecodeResources() override 87e5c31af7Sopenharmony_ci { 88e5c31af7Sopenharmony_ci Deinit(); 89e5c31af7Sopenharmony_ci } 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_ci VkSharedBaseObj<VkImageResourceView>& GetFrameImageView() { 92e5c31af7Sopenharmony_ci if (ImageExist()) { 93e5c31af7Sopenharmony_ci return m_frameDpbImageView; 94e5c31af7Sopenharmony_ci } else { 95e5c31af7Sopenharmony_ci return emptyImageView; 96e5c31af7Sopenharmony_ci } 97e5c31af7Sopenharmony_ci } 98e5c31af7Sopenharmony_ci 99e5c31af7Sopenharmony_ci VkSharedBaseObj<VkImageResourceView>& GetDisplayImageView() { 100e5c31af7Sopenharmony_ci if (ImageExist()) { 101e5c31af7Sopenharmony_ci return m_outImageView; 102e5c31af7Sopenharmony_ci } else { 103e5c31af7Sopenharmony_ci return emptyImageView; 104e5c31af7Sopenharmony_ci } 105e5c31af7Sopenharmony_ci } 106e5c31af7Sopenharmony_ci 107e5c31af7Sopenharmony_ci bool ImageExist() { 108e5c31af7Sopenharmony_ci 109e5c31af7Sopenharmony_ci return (!!m_frameDpbImageView && (m_frameDpbImageView->GetImageView() != VK_NULL_HANDLE)); 110e5c31af7Sopenharmony_ci } 111e5c31af7Sopenharmony_ci 112e5c31af7Sopenharmony_ci bool GetImageSetNewLayout(VkImageLayout newDpbImageLayout, 113e5c31af7Sopenharmony_ci VkVideoPictureResourceInfoKHR* pDpbPictureResource, 114e5c31af7Sopenharmony_ci VulkanVideoFrameBuffer::PictureResourceInfo* pDpbPictureResourceInfo, 115e5c31af7Sopenharmony_ci VkImageLayout newOutputImageLayout = VK_IMAGE_LAYOUT_MAX_ENUM, 116e5c31af7Sopenharmony_ci VkVideoPictureResourceInfoKHR* pOutputPictureResource = nullptr, 117e5c31af7Sopenharmony_ci VulkanVideoFrameBuffer::PictureResourceInfo* pOutputPictureResourceInfo = nullptr) { 118e5c31af7Sopenharmony_ci 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ci if (m_recreateImage || !ImageExist()) { 121e5c31af7Sopenharmony_ci return false; 122e5c31af7Sopenharmony_ci } 123e5c31af7Sopenharmony_ci 124e5c31af7Sopenharmony_ci if (pDpbPictureResourceInfo) { 125e5c31af7Sopenharmony_ci pDpbPictureResourceInfo->image = m_frameDpbImageView->GetImageResource()->GetImage(); 126e5c31af7Sopenharmony_ci pDpbPictureResourceInfo->imageFormat = m_frameDpbImageView->GetImageResource()->GetImageCreateInfo().format; 127e5c31af7Sopenharmony_ci pDpbPictureResourceInfo->currentImageLayout = m_currentDpbImageLayerLayout; 128e5c31af7Sopenharmony_ci } 129e5c31af7Sopenharmony_ci 130e5c31af7Sopenharmony_ci if (VK_IMAGE_LAYOUT_MAX_ENUM != newDpbImageLayout) { 131e5c31af7Sopenharmony_ci m_currentDpbImageLayerLayout = newDpbImageLayout; 132e5c31af7Sopenharmony_ci } 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_ci if (pDpbPictureResource) { 135e5c31af7Sopenharmony_ci pDpbPictureResource->imageViewBinding = m_frameDpbImageView->GetImageView(); 136e5c31af7Sopenharmony_ci } 137e5c31af7Sopenharmony_ci 138e5c31af7Sopenharmony_ci if (pOutputPictureResourceInfo) { 139e5c31af7Sopenharmony_ci pOutputPictureResourceInfo->image = m_outImageView->GetImageResource()->GetImage(); 140e5c31af7Sopenharmony_ci pOutputPictureResourceInfo->imageFormat = m_outImageView->GetImageResource()->GetImageCreateInfo().format; 141e5c31af7Sopenharmony_ci pOutputPictureResourceInfo->currentImageLayout = m_currentOutputImageLayout; 142e5c31af7Sopenharmony_ci } 143e5c31af7Sopenharmony_ci 144e5c31af7Sopenharmony_ci if (VK_IMAGE_LAYOUT_MAX_ENUM != newOutputImageLayout) { 145e5c31af7Sopenharmony_ci m_currentOutputImageLayout = newOutputImageLayout; 146e5c31af7Sopenharmony_ci } 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_ci if (pOutputPictureResource) { 149e5c31af7Sopenharmony_ci pOutputPictureResource->imageViewBinding = m_outImageView->GetImageView(); 150e5c31af7Sopenharmony_ci } 151e5c31af7Sopenharmony_ci 152e5c31af7Sopenharmony_ci return true; 153e5c31af7Sopenharmony_ci } 154e5c31af7Sopenharmony_ci 155e5c31af7Sopenharmony_ci VkParserDecodePictureInfo m_picDispInfo; 156e5c31af7Sopenharmony_ci VkFence m_frameCompleteFence; 157e5c31af7Sopenharmony_ci VkSemaphore m_frameCompleteSemaphore; 158e5c31af7Sopenharmony_ci VkFence m_frameConsumerDoneFence; 159e5c31af7Sopenharmony_ci VkSemaphore m_frameConsumerDoneSemaphore; 160e5c31af7Sopenharmony_ci deUint32 m_hasFrameCompleteSignalFence : 1; 161e5c31af7Sopenharmony_ci deUint32 m_hasFrameCompleteSignalSemaphore : 1; 162e5c31af7Sopenharmony_ci deUint32 m_hasConsummerSignalFence : 1; 163e5c31af7Sopenharmony_ci deUint32 m_hasConsummerSignalSemaphore : 1; 164e5c31af7Sopenharmony_ci deUint32 m_recreateImage : 1; 165e5c31af7Sopenharmony_ci // VPS 166e5c31af7Sopenharmony_ci VkSharedBaseObj<VkVideoRefCountBase> stdVps; 167e5c31af7Sopenharmony_ci // SPS 168e5c31af7Sopenharmony_ci VkSharedBaseObj<VkVideoRefCountBase> stdSps; 169e5c31af7Sopenharmony_ci // PPS 170e5c31af7Sopenharmony_ci VkSharedBaseObj<VkVideoRefCountBase> stdPps; 171e5c31af7Sopenharmony_ci // The bitstream Buffer 172e5c31af7Sopenharmony_ci VkSharedBaseObj<VkVideoRefCountBase> bitstreamData; 173e5c31af7Sopenharmony_ci 174e5c31af7Sopenharmony_ciprivate: 175e5c31af7Sopenharmony_ci VkImageLayout m_currentDpbImageLayerLayout; 176e5c31af7Sopenharmony_ci VkImageLayout m_currentOutputImageLayout; 177e5c31af7Sopenharmony_ci DeviceContext* m_vkDevCtx; 178e5c31af7Sopenharmony_ci VkSharedBaseObj<VkImageResourceView> m_frameDpbImageView; 179e5c31af7Sopenharmony_ci VkSharedBaseObj<VkImageResourceView> m_outImageView; 180e5c31af7Sopenharmony_ci}; 181e5c31af7Sopenharmony_ci 182e5c31af7Sopenharmony_ciclass NvPerFrameDecodeImageSet { 183e5c31af7Sopenharmony_cipublic: 184e5c31af7Sopenharmony_ci 185e5c31af7Sopenharmony_ci static constexpr size_t maxImages = 32; 186e5c31af7Sopenharmony_ci 187e5c31af7Sopenharmony_ci NvPerFrameDecodeImageSet() 188e5c31af7Sopenharmony_ci : m_queueFamilyIndex((deUint32)-1) 189e5c31af7Sopenharmony_ci , m_dpbImageCreateInfo() 190e5c31af7Sopenharmony_ci , m_outImageCreateInfo() 191e5c31af7Sopenharmony_ci , m_numImages(0) 192e5c31af7Sopenharmony_ci , m_usesImageArray(false) 193e5c31af7Sopenharmony_ci , m_usesImageViewArray(false) 194e5c31af7Sopenharmony_ci , m_usesSeparateOutputImage(false) 195e5c31af7Sopenharmony_ci , m_usesLinearOutput(false) 196e5c31af7Sopenharmony_ci , m_perFrameDecodeResources(maxImages) 197e5c31af7Sopenharmony_ci , m_imageArray() 198e5c31af7Sopenharmony_ci , m_imageViewArray() 199e5c31af7Sopenharmony_ci { 200e5c31af7Sopenharmony_ci } 201e5c31af7Sopenharmony_ci 202e5c31af7Sopenharmony_ci int32_t init(DeviceContext& vkDevCtx, 203e5c31af7Sopenharmony_ci const VkVideoProfileInfoKHR* pDecodeProfile, 204e5c31af7Sopenharmony_ci deUint32 numImages, 205e5c31af7Sopenharmony_ci VkFormat dpbImageFormat, 206e5c31af7Sopenharmony_ci VkFormat outImageFormat, 207e5c31af7Sopenharmony_ci const VkExtent2D& maxImageExtent, 208e5c31af7Sopenharmony_ci VkImageUsageFlags dpbImageUsage, 209e5c31af7Sopenharmony_ci VkImageUsageFlags outImageUsage, 210e5c31af7Sopenharmony_ci deUint32 queueFamilyIndex, 211e5c31af7Sopenharmony_ci bool useImageArray = false, 212e5c31af7Sopenharmony_ci bool useImageViewArray = false, 213e5c31af7Sopenharmony_ci bool useSeparateOutputImages = false, 214e5c31af7Sopenharmony_ci bool useLinearOutput = false); 215e5c31af7Sopenharmony_ci 216e5c31af7Sopenharmony_ci ~NvPerFrameDecodeImageSet() 217e5c31af7Sopenharmony_ci { 218e5c31af7Sopenharmony_ci m_numImages = 0; 219e5c31af7Sopenharmony_ci } 220e5c31af7Sopenharmony_ci 221e5c31af7Sopenharmony_ci NvPerFrameDecodeResources& operator[](unsigned int index) 222e5c31af7Sopenharmony_ci { 223e5c31af7Sopenharmony_ci DE_ASSERT(index < m_perFrameDecodeResources.size()); 224e5c31af7Sopenharmony_ci return m_perFrameDecodeResources[index]; 225e5c31af7Sopenharmony_ci } 226e5c31af7Sopenharmony_ci 227e5c31af7Sopenharmony_ci size_t size() const 228e5c31af7Sopenharmony_ci { 229e5c31af7Sopenharmony_ci return m_numImages; 230e5c31af7Sopenharmony_ci } 231e5c31af7Sopenharmony_ci 232e5c31af7Sopenharmony_ci VkResult GetImageSetNewLayout(DeviceContext& vkDevCtx, 233e5c31af7Sopenharmony_ci deUint32 imageIndex, 234e5c31af7Sopenharmony_ci VkImageLayout newDpbImageLayout, 235e5c31af7Sopenharmony_ci VkVideoPictureResourceInfoKHR* pDpbPictureResource = nullptr, 236e5c31af7Sopenharmony_ci VulkanVideoFrameBuffer::PictureResourceInfo* pDpbPictureResourceInfo = nullptr, 237e5c31af7Sopenharmony_ci VkImageLayout newOutputImageLayout = VK_IMAGE_LAYOUT_MAX_ENUM, 238e5c31af7Sopenharmony_ci VkVideoPictureResourceInfoKHR* pOutputPictureResource = nullptr, 239e5c31af7Sopenharmony_ci VulkanVideoFrameBuffer::PictureResourceInfo* pOutputPictureResourceInfo = nullptr) { 240e5c31af7Sopenharmony_ci 241e5c31af7Sopenharmony_ci VkResult result = VK_SUCCESS; 242e5c31af7Sopenharmony_ci if (pDpbPictureResource) { 243e5c31af7Sopenharmony_ci if (m_imageViewArray) { 244e5c31af7Sopenharmony_ci // We have an image view that has the same number of layers as the image. 245e5c31af7Sopenharmony_ci // In that scenario, while specifying the resource, the API must specifically choose the image layer. 246e5c31af7Sopenharmony_ci pDpbPictureResource->baseArrayLayer = imageIndex; 247e5c31af7Sopenharmony_ci } else { 248e5c31af7Sopenharmony_ci // Let the image view sub-resource specify the image layer. 249e5c31af7Sopenharmony_ci pDpbPictureResource->baseArrayLayer = 0; 250e5c31af7Sopenharmony_ci } 251e5c31af7Sopenharmony_ci } 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_ci if(pOutputPictureResource) { 254e5c31af7Sopenharmony_ci // Output pictures currently are only allocated as discrete 255e5c31af7Sopenharmony_ci // Let the image view sub-resource specify the image layer. 256e5c31af7Sopenharmony_ci pOutputPictureResource->baseArrayLayer = 0; 257e5c31af7Sopenharmony_ci } 258e5c31af7Sopenharmony_ci 259e5c31af7Sopenharmony_ci bool validImage = m_perFrameDecodeResources[imageIndex].GetImageSetNewLayout( 260e5c31af7Sopenharmony_ci newDpbImageLayout, 261e5c31af7Sopenharmony_ci pDpbPictureResource, 262e5c31af7Sopenharmony_ci pDpbPictureResourceInfo, 263e5c31af7Sopenharmony_ci newOutputImageLayout, 264e5c31af7Sopenharmony_ci pOutputPictureResource, 265e5c31af7Sopenharmony_ci pOutputPictureResourceInfo); 266e5c31af7Sopenharmony_ci 267e5c31af7Sopenharmony_ci if (!validImage) { 268e5c31af7Sopenharmony_ci result = m_perFrameDecodeResources[imageIndex].CreateImage( 269e5c31af7Sopenharmony_ci vkDevCtx, 270e5c31af7Sopenharmony_ci &m_dpbImageCreateInfo, 271e5c31af7Sopenharmony_ci &m_outImageCreateInfo, 272e5c31af7Sopenharmony_ci imageIndex, 273e5c31af7Sopenharmony_ci m_imageArray, 274e5c31af7Sopenharmony_ci m_imageViewArray, 275e5c31af7Sopenharmony_ci m_usesSeparateOutputImage, 276e5c31af7Sopenharmony_ci m_usesLinearOutput); 277e5c31af7Sopenharmony_ci 278e5c31af7Sopenharmony_ci if (result == VK_SUCCESS) { 279e5c31af7Sopenharmony_ci validImage = m_perFrameDecodeResources[imageIndex].GetImageSetNewLayout( 280e5c31af7Sopenharmony_ci newDpbImageLayout, 281e5c31af7Sopenharmony_ci pDpbPictureResource, 282e5c31af7Sopenharmony_ci pDpbPictureResourceInfo, 283e5c31af7Sopenharmony_ci newOutputImageLayout, 284e5c31af7Sopenharmony_ci pOutputPictureResource, 285e5c31af7Sopenharmony_ci pOutputPictureResourceInfo); 286e5c31af7Sopenharmony_ci 287e5c31af7Sopenharmony_ci DE_ASSERT(validImage); 288e5c31af7Sopenharmony_ci } 289e5c31af7Sopenharmony_ci } 290e5c31af7Sopenharmony_ci 291e5c31af7Sopenharmony_ci return result; 292e5c31af7Sopenharmony_ci } 293e5c31af7Sopenharmony_ci 294e5c31af7Sopenharmony_ciprivate: 295e5c31af7Sopenharmony_ci deUint32 m_queueFamilyIndex; 296e5c31af7Sopenharmony_ci VkVideoCoreProfile m_videoProfile; 297e5c31af7Sopenharmony_ci VkImageCreateInfo m_dpbImageCreateInfo; 298e5c31af7Sopenharmony_ci VkImageCreateInfo m_outImageCreateInfo; 299e5c31af7Sopenharmony_ci deUint32 m_numImages; 300e5c31af7Sopenharmony_ci // TODO: This code copied from the NVIDIA sample app has never been tested. Need to make sure the IHVs have a Radeon 5000 series GPU that uses this feature. 301e5c31af7Sopenharmony_ci deUint32 m_usesImageArray : 1; 302e5c31af7Sopenharmony_ci deUint32 m_usesImageViewArray : 1; 303e5c31af7Sopenharmony_ci deUint32 m_usesSeparateOutputImage : 1; 304e5c31af7Sopenharmony_ci deUint32 m_usesLinearOutput : 1; 305e5c31af7Sopenharmony_ci std::vector<NvPerFrameDecodeResources> m_perFrameDecodeResources; 306e5c31af7Sopenharmony_ci VkSharedBaseObj<VkImageResource> m_imageArray; // must be valid if m_usesImageArray is true 307e5c31af7Sopenharmony_ci VkSharedBaseObj<VkImageResourceView> m_imageViewArray; // must be valid if m_usesImageViewArray is true 308e5c31af7Sopenharmony_ci}; 309e5c31af7Sopenharmony_ci 310e5c31af7Sopenharmony_ciclass VkVideoFrameBuffer : public VulkanVideoFrameBuffer { 311e5c31af7Sopenharmony_cipublic: 312e5c31af7Sopenharmony_ci static constexpr size_t maxFramebufferImages = 32; 313e5c31af7Sopenharmony_ci 314e5c31af7Sopenharmony_ci VkVideoFrameBuffer(DeviceContext& vkDevCtx, bool supportsQueries) 315e5c31af7Sopenharmony_ci : m_vkDevCtx(vkDevCtx), 316e5c31af7Sopenharmony_ci m_refCount(0), 317e5c31af7Sopenharmony_ci m_displayQueueMutex(), 318e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet(), 319e5c31af7Sopenharmony_ci m_displayFrames(), 320e5c31af7Sopenharmony_ci m_supportsQueries(supportsQueries), 321e5c31af7Sopenharmony_ci m_queryPool(VK_NULL_HANDLE), 322e5c31af7Sopenharmony_ci m_ownedByDisplayMask(0), 323e5c31af7Sopenharmony_ci m_frameNumInDecodeOrder(0), 324e5c31af7Sopenharmony_ci m_frameNumInDisplayOrder(0), 325e5c31af7Sopenharmony_ci m_codedExtent{0, 0}, 326e5c31af7Sopenharmony_ci m_numberParameterUpdates(0) 327e5c31af7Sopenharmony_ci { } 328e5c31af7Sopenharmony_ci 329e5c31af7Sopenharmony_ci int32_t AddRef() override; 330e5c31af7Sopenharmony_ci int32_t Release() override; 331e5c31af7Sopenharmony_ci 332e5c31af7Sopenharmony_ci VkResult CreateVideoQueries(deUint32 numSlots, DeviceContext& vkDevCtx, 333e5c31af7Sopenharmony_ci const VkVideoProfileInfoKHR* pDecodeProfile) { 334e5c31af7Sopenharmony_ci DE_ASSERT(numSlots <= maxFramebufferImages); 335e5c31af7Sopenharmony_ci 336e5c31af7Sopenharmony_ci auto& vk = vkDevCtx.context->getDeviceInterface(); 337e5c31af7Sopenharmony_ci 338e5c31af7Sopenharmony_ci if (m_queryPool == VK_NULL_HANDLE) { 339e5c31af7Sopenharmony_ci // It would be difficult to resize a query pool, so allocate the maximum possible slot. 340e5c31af7Sopenharmony_ci numSlots = maxFramebufferImages; 341e5c31af7Sopenharmony_ci VkQueryPoolCreateInfo queryPoolCreateInfo{}; 342e5c31af7Sopenharmony_ci queryPoolCreateInfo.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; 343e5c31af7Sopenharmony_ci queryPoolCreateInfo.pNext = pDecodeProfile; 344e5c31af7Sopenharmony_ci queryPoolCreateInfo.queryType = VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR; 345e5c31af7Sopenharmony_ci queryPoolCreateInfo.queryCount = numSlots; // m_numDecodeSurfaces frames worth 346e5c31af7Sopenharmony_ci 347e5c31af7Sopenharmony_ci return vk.createQueryPool(vkDevCtx.device, &queryPoolCreateInfo, nullptr, &m_queryPool); 348e5c31af7Sopenharmony_ci } 349e5c31af7Sopenharmony_ci 350e5c31af7Sopenharmony_ci return VK_SUCCESS; 351e5c31af7Sopenharmony_ci } 352e5c31af7Sopenharmony_ci 353e5c31af7Sopenharmony_ci void DestroyVideoQueries() { 354e5c31af7Sopenharmony_ci if (m_queryPool != VK_NULL_HANDLE) { 355e5c31af7Sopenharmony_ci m_vkDevCtx.getDeviceDriver().destroyQueryPool(m_vkDevCtx.device, m_queryPool, nullptr); 356e5c31af7Sopenharmony_ci m_queryPool = VK_NULL_HANDLE; 357e5c31af7Sopenharmony_ci } 358e5c31af7Sopenharmony_ci } 359e5c31af7Sopenharmony_ci 360e5c31af7Sopenharmony_ci deUint32 FlushDisplayQueue() { 361e5c31af7Sopenharmony_ci std::lock_guard<std::mutex> lock(m_displayQueueMutex); 362e5c31af7Sopenharmony_ci 363e5c31af7Sopenharmony_ci deUint32 flushedImages = 0; 364e5c31af7Sopenharmony_ci while (!m_displayFrames.empty()) { 365e5c31af7Sopenharmony_ci deUint8 pictureIndex = m_displayFrames.front(); 366e5c31af7Sopenharmony_ci DE_ASSERT(pictureIndex < m_perFrameDecodeImageSet.size()); 367e5c31af7Sopenharmony_ci m_displayFrames.pop(); 368e5c31af7Sopenharmony_ci if (m_perFrameDecodeImageSet[(deUint32)pictureIndex].IsAvailable()) { 369e5c31af7Sopenharmony_ci // The frame is not released yet - force release it. 370e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[(deUint32)pictureIndex].Release(); 371e5c31af7Sopenharmony_ci } 372e5c31af7Sopenharmony_ci flushedImages++; 373e5c31af7Sopenharmony_ci } 374e5c31af7Sopenharmony_ci 375e5c31af7Sopenharmony_ci return flushedImages; 376e5c31af7Sopenharmony_ci } 377e5c31af7Sopenharmony_ci 378e5c31af7Sopenharmony_ci int32_t InitImagePool(const VkVideoProfileInfoKHR* pDecodeProfile, deUint32 numImages, VkFormat dpbImageFormat, 379e5c31af7Sopenharmony_ci VkFormat outImageFormat, const VkExtent2D& codedExtent, const VkExtent2D& maxImageExtent, 380e5c31af7Sopenharmony_ci VkImageUsageFlags dpbImageUsage, VkImageUsageFlags outImageUsage, deUint32 queueFamilyIndex, 381e5c31af7Sopenharmony_ci bool useImageArray, bool useImageViewArray, 382e5c31af7Sopenharmony_ci bool useSeparateOutputImage, bool useLinearOutput) override; 383e5c31af7Sopenharmony_ci 384e5c31af7Sopenharmony_ci void Deinitialize() { 385e5c31af7Sopenharmony_ci FlushDisplayQueue(); 386e5c31af7Sopenharmony_ci 387e5c31af7Sopenharmony_ci if (m_supportsQueries) 388e5c31af7Sopenharmony_ci DestroyVideoQueries(); 389e5c31af7Sopenharmony_ci 390e5c31af7Sopenharmony_ci m_ownedByDisplayMask = 0; 391e5c31af7Sopenharmony_ci m_frameNumInDecodeOrder = 0; 392e5c31af7Sopenharmony_ci m_frameNumInDisplayOrder = 0; 393e5c31af7Sopenharmony_ci 394e5c31af7Sopenharmony_ci if (m_queryPool != VK_NULL_HANDLE) { 395e5c31af7Sopenharmony_ci m_vkDevCtx.getDeviceDriver().destroyQueryPool(m_vkDevCtx.device, m_queryPool, nullptr); 396e5c31af7Sopenharmony_ci m_queryPool = VK_NULL_HANDLE; 397e5c31af7Sopenharmony_ci } 398e5c31af7Sopenharmony_ci }; 399e5c31af7Sopenharmony_ci 400e5c31af7Sopenharmony_ci int32_t QueueDecodedPictureForDisplay(int8_t picId, VulkanVideoDisplayPictureInfo* pDispInfo) override { 401e5c31af7Sopenharmony_ci DE_ASSERT((deUint32)picId < m_perFrameDecodeImageSet.size()); 402e5c31af7Sopenharmony_ci 403e5c31af7Sopenharmony_ci std::lock_guard<std::mutex> lock(m_displayQueueMutex); 404e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].m_displayOrder = m_frameNumInDisplayOrder++; 405e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].m_timestamp = pDispInfo->timestamp; 406e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].AddRef(); 407e5c31af7Sopenharmony_ci 408e5c31af7Sopenharmony_ci m_displayFrames.push((deUint8)picId); 409e5c31af7Sopenharmony_ci 410e5c31af7Sopenharmony_ci if (videoLoggingEnabled()) { 411e5c31af7Sopenharmony_ci std::cout << "==> Queue Display Picture picIdx: " << (deUint32)picId 412e5c31af7Sopenharmony_ci << "\t\tdisplayOrder: " << m_perFrameDecodeImageSet[picId].m_displayOrder 413e5c31af7Sopenharmony_ci << "\tdecodeOrder: " << m_perFrameDecodeImageSet[picId].m_decodeOrder << "\ttimestamp " 414e5c31af7Sopenharmony_ci << m_perFrameDecodeImageSet[picId].m_timestamp << std::endl; 415e5c31af7Sopenharmony_ci } 416e5c31af7Sopenharmony_ci return picId; 417e5c31af7Sopenharmony_ci } 418e5c31af7Sopenharmony_ci 419e5c31af7Sopenharmony_ci int32_t QueuePictureForDecode(int8_t picId, VkParserDecodePictureInfo* pDecodePictureInfo, 420e5c31af7Sopenharmony_ci ReferencedObjectsInfo* pReferencedObjectsInfo, 421e5c31af7Sopenharmony_ci FrameSynchronizationInfo* pFrameSynchronizationInfo) override; 422e5c31af7Sopenharmony_ci 423e5c31af7Sopenharmony_ci size_t GetDisplayedFrameCount() const override { return m_displayFrames.size(); } 424e5c31af7Sopenharmony_ci 425e5c31af7Sopenharmony_ci // dequeue 426e5c31af7Sopenharmony_ci int32_t DequeueDecodedPicture(DecodedFrame* pDecodedFrame) override; 427e5c31af7Sopenharmony_ci 428e5c31af7Sopenharmony_ci int32_t ReleaseDisplayedPicture(DecodedFrameRelease** pDecodedFramesRelease, deUint32 numFramesToRelease) override; 429e5c31af7Sopenharmony_ci 430e5c31af7Sopenharmony_ci int32_t GetDpbImageResourcesByIndex(deUint32 numResources, const int8_t* referenceSlotIndexes, 431e5c31af7Sopenharmony_ci VkVideoPictureResourceInfoKHR* dpbPictureResources, 432e5c31af7Sopenharmony_ci PictureResourceInfo* dpbPictureResourcesInfo, 433e5c31af7Sopenharmony_ci VkImageLayout newDpbImageLayerLayout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR) override; 434e5c31af7Sopenharmony_ci 435e5c31af7Sopenharmony_ci int32_t GetCurrentImageResourceByIndex(int8_t referenceSlotIndex, VkVideoPictureResourceInfoKHR* dpbPictureResource, 436e5c31af7Sopenharmony_ci PictureResourceInfo* dpbPictureResourceInfo, 437e5c31af7Sopenharmony_ci VkImageLayout newDpbImageLayerLayout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR, 438e5c31af7Sopenharmony_ci VkVideoPictureResourceInfoKHR* outputPictureResource = nullptr, 439e5c31af7Sopenharmony_ci PictureResourceInfo* outputPictureResourceInfo = nullptr, 440e5c31af7Sopenharmony_ci VkImageLayout newOutputImageLayerLayout = VK_IMAGE_LAYOUT_MAX_ENUM) override; 441e5c31af7Sopenharmony_ci 442e5c31af7Sopenharmony_ci int32_t ReleaseImageResources(deUint32 numResources, const deUint32* indexes) override { 443e5c31af7Sopenharmony_ci std::lock_guard<std::mutex> lock(m_displayQueueMutex); 444e5c31af7Sopenharmony_ci for (unsigned int resId = 0; resId < numResources; resId++) { 445e5c31af7Sopenharmony_ci if ((deUint32)indexes[resId] < m_perFrameDecodeImageSet.size()) { 446e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[indexes[resId]].Deinit(); 447e5c31af7Sopenharmony_ci } 448e5c31af7Sopenharmony_ci } 449e5c31af7Sopenharmony_ci return (int32_t)m_perFrameDecodeImageSet.size(); 450e5c31af7Sopenharmony_ci } 451e5c31af7Sopenharmony_ci 452e5c31af7Sopenharmony_ci int32_t SetPicNumInDecodeOrder(int32_t picId, int32_t picNumInDecodeOrder) override { 453e5c31af7Sopenharmony_ci std::lock_guard<std::mutex> lock(m_displayQueueMutex); 454e5c31af7Sopenharmony_ci if ((deUint32)picId < m_perFrameDecodeImageSet.size()) { 455e5c31af7Sopenharmony_ci int32_t oldPicNumInDecodeOrder = m_perFrameDecodeImageSet[picId].m_decodeOrder; 456e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].m_decodeOrder = picNumInDecodeOrder; 457e5c31af7Sopenharmony_ci return oldPicNumInDecodeOrder; 458e5c31af7Sopenharmony_ci } 459e5c31af7Sopenharmony_ci DE_ASSERT(false); 460e5c31af7Sopenharmony_ci return -1; 461e5c31af7Sopenharmony_ci } 462e5c31af7Sopenharmony_ci 463e5c31af7Sopenharmony_ci int32_t SetPicNumInDisplayOrder(int32_t picId, int32_t picNumInDisplayOrder) override { 464e5c31af7Sopenharmony_ci std::lock_guard<std::mutex> lock(m_displayQueueMutex); 465e5c31af7Sopenharmony_ci if ((deUint32)picId < m_perFrameDecodeImageSet.size()) { 466e5c31af7Sopenharmony_ci int32_t oldPicNumInDisplayOrder = m_perFrameDecodeImageSet[picId].m_displayOrder; 467e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].m_displayOrder = picNumInDisplayOrder; 468e5c31af7Sopenharmony_ci return oldPicNumInDisplayOrder; 469e5c31af7Sopenharmony_ci } 470e5c31af7Sopenharmony_ci DE_ASSERT(false); 471e5c31af7Sopenharmony_ci return -1; 472e5c31af7Sopenharmony_ci } 473e5c31af7Sopenharmony_ci 474e5c31af7Sopenharmony_ci virtual const VkSharedBaseObj<VkImageResourceView>& GetImageResourceByIndex(int8_t picId) { 475e5c31af7Sopenharmony_ci std::lock_guard<std::mutex> lock(m_displayQueueMutex); 476e5c31af7Sopenharmony_ci if ((deUint32)picId < m_perFrameDecodeImageSet.size()) { 477e5c31af7Sopenharmony_ci return m_perFrameDecodeImageSet[picId].GetFrameImageView(); 478e5c31af7Sopenharmony_ci } 479e5c31af7Sopenharmony_ci DE_ASSERT(false); 480e5c31af7Sopenharmony_ci return emptyImageView; 481e5c31af7Sopenharmony_ci } 482e5c31af7Sopenharmony_ci 483e5c31af7Sopenharmony_ci vkPicBuffBase* ReservePictureBuffer() override { 484e5c31af7Sopenharmony_ci std::lock_guard<std::mutex> lock(m_displayQueueMutex); 485e5c31af7Sopenharmony_ci int foundPicId = -1; 486e5c31af7Sopenharmony_ci for (int picId = 0; picId < m_perFrameDecodeImageSet.size(); picId++) { 487e5c31af7Sopenharmony_ci if (m_perFrameDecodeImageSet[picId].IsAvailable()) { 488e5c31af7Sopenharmony_ci foundPicId = picId; 489e5c31af7Sopenharmony_ci break; 490e5c31af7Sopenharmony_ci } 491e5c31af7Sopenharmony_ci } 492e5c31af7Sopenharmony_ci 493e5c31af7Sopenharmony_ci if (foundPicId >= 0) { 494e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[foundPicId].Reset(); 495e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[foundPicId].AddRef(); 496e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[foundPicId].m_picIdx = foundPicId; 497e5c31af7Sopenharmony_ci return &m_perFrameDecodeImageSet[foundPicId]; 498e5c31af7Sopenharmony_ci } 499e5c31af7Sopenharmony_ci 500e5c31af7Sopenharmony_ci DE_ASSERT(foundPicId >= 0); 501e5c31af7Sopenharmony_ci return nullptr; 502e5c31af7Sopenharmony_ci } 503e5c31af7Sopenharmony_ci 504e5c31af7Sopenharmony_ci size_t GetSize() override { 505e5c31af7Sopenharmony_ci std::lock_guard<std::mutex> lock(m_displayQueueMutex); 506e5c31af7Sopenharmony_ci return m_perFrameDecodeImageSet.size(); 507e5c31af7Sopenharmony_ci } 508e5c31af7Sopenharmony_ci 509e5c31af7Sopenharmony_ci virtual ~VkVideoFrameBuffer() { Deinitialize(); } 510e5c31af7Sopenharmony_ci 511e5c31af7Sopenharmony_ciprivate: 512e5c31af7Sopenharmony_ci DeviceContext& m_vkDevCtx; 513e5c31af7Sopenharmony_ci std::atomic<int32_t> m_refCount; 514e5c31af7Sopenharmony_ci std::mutex m_displayQueueMutex; 515e5c31af7Sopenharmony_ci NvPerFrameDecodeImageSet m_perFrameDecodeImageSet; 516e5c31af7Sopenharmony_ci std::queue<deUint8> m_displayFrames; 517e5c31af7Sopenharmony_ci bool m_supportsQueries; 518e5c31af7Sopenharmony_ci VkQueryPool m_queryPool; 519e5c31af7Sopenharmony_ci deUint32 m_ownedByDisplayMask; 520e5c31af7Sopenharmony_ci int32_t m_frameNumInDecodeOrder; 521e5c31af7Sopenharmony_ci int32_t m_frameNumInDisplayOrder; 522e5c31af7Sopenharmony_ci VkExtent2D m_codedExtent; // for the codedExtent, not the max image resolution 523e5c31af7Sopenharmony_ci deUint32 m_numberParameterUpdates; 524e5c31af7Sopenharmony_ci}; 525e5c31af7Sopenharmony_ci 526e5c31af7Sopenharmony_ciVkResult VulkanVideoFrameBuffer::Create(DeviceContext* vkDevCtx, 527e5c31af7Sopenharmony_ci bool supportsQueries, 528e5c31af7Sopenharmony_ci VkSharedBaseObj<VulkanVideoFrameBuffer>& vkVideoFrameBuffer) 529e5c31af7Sopenharmony_ci{ 530e5c31af7Sopenharmony_ci VkSharedBaseObj<VkVideoFrameBuffer> videoFrameBuffer(new VkVideoFrameBuffer(*vkDevCtx, supportsQueries)); 531e5c31af7Sopenharmony_ci if (videoFrameBuffer) { 532e5c31af7Sopenharmony_ci vkVideoFrameBuffer = videoFrameBuffer; 533e5c31af7Sopenharmony_ci return VK_SUCCESS; 534e5c31af7Sopenharmony_ci } 535e5c31af7Sopenharmony_ci return VK_ERROR_OUT_OF_HOST_MEMORY; 536e5c31af7Sopenharmony_ci} 537e5c31af7Sopenharmony_ci 538e5c31af7Sopenharmony_ciint32_t VkVideoFrameBuffer::AddRef() 539e5c31af7Sopenharmony_ci{ 540e5c31af7Sopenharmony_ci return ++m_refCount; 541e5c31af7Sopenharmony_ci} 542e5c31af7Sopenharmony_ci 543e5c31af7Sopenharmony_ciint32_t VkVideoFrameBuffer::Release() 544e5c31af7Sopenharmony_ci{ 545e5c31af7Sopenharmony_ci deUint32 ret; 546e5c31af7Sopenharmony_ci ret = --m_refCount; 547e5c31af7Sopenharmony_ci // Destroy the device if refcount reaches zero 548e5c31af7Sopenharmony_ci if (ret == 0) { 549e5c31af7Sopenharmony_ci delete this; 550e5c31af7Sopenharmony_ci } 551e5c31af7Sopenharmony_ci return ret; 552e5c31af7Sopenharmony_ci} 553e5c31af7Sopenharmony_ci 554e5c31af7Sopenharmony_ciint32_t VkVideoFrameBuffer::QueuePictureForDecode(int8_t picId, VkParserDecodePictureInfo* pDecodePictureInfo, VulkanVideoFrameBuffer::ReferencedObjectsInfo* pReferencedObjectsInfo, VulkanVideoFrameBuffer::FrameSynchronizationInfo* pFrameSynchronizationInfo) 555e5c31af7Sopenharmony_ci{ 556e5c31af7Sopenharmony_ci DE_ASSERT((deUint32)picId < m_perFrameDecodeImageSet.size()); 557e5c31af7Sopenharmony_ci 558e5c31af7Sopenharmony_ci std::lock_guard<std::mutex> lock(m_displayQueueMutex); 559e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].m_picDispInfo = *pDecodePictureInfo; 560e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].m_decodeOrder = m_frameNumInDecodeOrder++; 561e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].stdPps = const_cast<VkVideoRefCountBase*>(pReferencedObjectsInfo->pStdPps); 562e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].stdSps = const_cast<VkVideoRefCountBase*>(pReferencedObjectsInfo->pStdSps); 563e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].stdVps = const_cast<VkVideoRefCountBase*>(pReferencedObjectsInfo->pStdVps); 564e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].bitstreamData = const_cast<VkVideoRefCountBase*>(pReferencedObjectsInfo->pBitstreamData); 565e5c31af7Sopenharmony_ci 566e5c31af7Sopenharmony_ci if (videoLoggingEnabled()) { 567e5c31af7Sopenharmony_ci std::cout << std::dec << "==> Queue Decode Picture picIdx: " << (deUint32)picId 568e5c31af7Sopenharmony_ci << "\t\tdisplayOrder: " << m_perFrameDecodeImageSet[picId].m_displayOrder 569e5c31af7Sopenharmony_ci << "\tdecodeOrder: " << m_perFrameDecodeImageSet[picId].m_decodeOrder << "\tFrameType " 570e5c31af7Sopenharmony_ci << m_perFrameDecodeImageSet[picId].m_picDispInfo.videoFrameType << std::endl; 571e5c31af7Sopenharmony_ci } 572e5c31af7Sopenharmony_ci 573e5c31af7Sopenharmony_ci if (pFrameSynchronizationInfo->hasFrameCompleteSignalFence) { 574e5c31af7Sopenharmony_ci pFrameSynchronizationInfo->frameCompleteFence = m_perFrameDecodeImageSet[picId].m_frameCompleteFence; 575e5c31af7Sopenharmony_ci if (!!pFrameSynchronizationInfo->frameCompleteFence) { 576e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].m_hasFrameCompleteSignalFence = true; 577e5c31af7Sopenharmony_ci } 578e5c31af7Sopenharmony_ci } 579e5c31af7Sopenharmony_ci 580e5c31af7Sopenharmony_ci if (m_perFrameDecodeImageSet[picId].m_hasConsummerSignalFence) { 581e5c31af7Sopenharmony_ci pFrameSynchronizationInfo->frameConsumerDoneFence = m_perFrameDecodeImageSet[picId].m_frameConsumerDoneFence; 582e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].m_hasConsummerSignalFence = false; 583e5c31af7Sopenharmony_ci } 584e5c31af7Sopenharmony_ci 585e5c31af7Sopenharmony_ci if (pFrameSynchronizationInfo->hasFrameCompleteSignalSemaphore) { 586e5c31af7Sopenharmony_ci pFrameSynchronizationInfo->frameCompleteSemaphore = m_perFrameDecodeImageSet[picId].m_frameCompleteSemaphore; 587e5c31af7Sopenharmony_ci if (!!pFrameSynchronizationInfo->frameCompleteSemaphore) { 588e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].m_hasFrameCompleteSignalSemaphore = true; 589e5c31af7Sopenharmony_ci } 590e5c31af7Sopenharmony_ci } 591e5c31af7Sopenharmony_ci 592e5c31af7Sopenharmony_ci if (m_perFrameDecodeImageSet[picId].m_hasConsummerSignalSemaphore) { 593e5c31af7Sopenharmony_ci pFrameSynchronizationInfo->frameConsumerDoneSemaphore = m_perFrameDecodeImageSet[picId].m_frameConsumerDoneSemaphore; 594e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].m_hasConsummerSignalSemaphore = false; 595e5c31af7Sopenharmony_ci } 596e5c31af7Sopenharmony_ci 597e5c31af7Sopenharmony_ci pFrameSynchronizationInfo->queryPool = m_queryPool; 598e5c31af7Sopenharmony_ci pFrameSynchronizationInfo->startQueryId = picId; 599e5c31af7Sopenharmony_ci pFrameSynchronizationInfo->numQueries = 1; 600e5c31af7Sopenharmony_ci 601e5c31af7Sopenharmony_ci return picId; 602e5c31af7Sopenharmony_ci} 603e5c31af7Sopenharmony_ci 604e5c31af7Sopenharmony_ciint32_t VkVideoFrameBuffer::DequeueDecodedPicture(DecodedFrame* pDecodedFrame) 605e5c31af7Sopenharmony_ci{ 606e5c31af7Sopenharmony_ci int numberofPendingFrames = 0; 607e5c31af7Sopenharmony_ci int pictureIndex = -1; 608e5c31af7Sopenharmony_ci std::lock_guard<std::mutex> lock(m_displayQueueMutex); 609e5c31af7Sopenharmony_ci if (!m_displayFrames.empty()) { 610e5c31af7Sopenharmony_ci numberofPendingFrames = (int)m_displayFrames.size(); 611e5c31af7Sopenharmony_ci pictureIndex = m_displayFrames.front(); 612e5c31af7Sopenharmony_ci DE_ASSERT((pictureIndex >= 0) && ((deUint32)pictureIndex < m_perFrameDecodeImageSet.size())); 613e5c31af7Sopenharmony_ci DE_ASSERT(!(m_ownedByDisplayMask & (1 << pictureIndex))); 614e5c31af7Sopenharmony_ci m_ownedByDisplayMask |= (1 << pictureIndex); 615e5c31af7Sopenharmony_ci m_displayFrames.pop(); 616e5c31af7Sopenharmony_ci } 617e5c31af7Sopenharmony_ci 618e5c31af7Sopenharmony_ci if ((deUint32)pictureIndex < m_perFrameDecodeImageSet.size()) { 619e5c31af7Sopenharmony_ci pDecodedFrame->pictureIndex = pictureIndex; 620e5c31af7Sopenharmony_ci 621e5c31af7Sopenharmony_ci pDecodedFrame->imageLayerIndex = m_perFrameDecodeImageSet[pictureIndex].m_picDispInfo.imageLayerIndex; 622e5c31af7Sopenharmony_ci 623e5c31af7Sopenharmony_ci pDecodedFrame->decodedImageView = m_perFrameDecodeImageSet[pictureIndex].GetFrameImageView(); 624e5c31af7Sopenharmony_ci pDecodedFrame->outputImageView = m_perFrameDecodeImageSet[pictureIndex].GetDisplayImageView(); 625e5c31af7Sopenharmony_ci 626e5c31af7Sopenharmony_ci pDecodedFrame->displayWidth = m_perFrameDecodeImageSet[pictureIndex].m_picDispInfo.displayWidth; 627e5c31af7Sopenharmony_ci pDecodedFrame->displayHeight = m_perFrameDecodeImageSet[pictureIndex].m_picDispInfo.displayHeight; 628e5c31af7Sopenharmony_ci 629e5c31af7Sopenharmony_ci if (m_perFrameDecodeImageSet[pictureIndex].m_hasFrameCompleteSignalFence) { 630e5c31af7Sopenharmony_ci pDecodedFrame->frameCompleteFence = m_perFrameDecodeImageSet[pictureIndex].m_frameCompleteFence; 631e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[pictureIndex].m_hasFrameCompleteSignalFence = false; 632e5c31af7Sopenharmony_ci } else { 633e5c31af7Sopenharmony_ci pDecodedFrame->frameCompleteFence = VK_NULL_HANDLE; 634e5c31af7Sopenharmony_ci } 635e5c31af7Sopenharmony_ci 636e5c31af7Sopenharmony_ci if (m_perFrameDecodeImageSet[pictureIndex].m_hasFrameCompleteSignalSemaphore) { 637e5c31af7Sopenharmony_ci pDecodedFrame->frameCompleteSemaphore = m_perFrameDecodeImageSet[pictureIndex].m_frameCompleteSemaphore; 638e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[pictureIndex].m_hasFrameCompleteSignalSemaphore = false; 639e5c31af7Sopenharmony_ci } else { 640e5c31af7Sopenharmony_ci pDecodedFrame->frameCompleteSemaphore = VK_NULL_HANDLE; 641e5c31af7Sopenharmony_ci } 642e5c31af7Sopenharmony_ci 643e5c31af7Sopenharmony_ci pDecodedFrame->frameConsumerDoneFence = m_perFrameDecodeImageSet[pictureIndex].m_frameConsumerDoneFence; 644e5c31af7Sopenharmony_ci pDecodedFrame->frameConsumerDoneSemaphore = m_perFrameDecodeImageSet[pictureIndex].m_frameConsumerDoneSemaphore; 645e5c31af7Sopenharmony_ci 646e5c31af7Sopenharmony_ci pDecodedFrame->timestamp = m_perFrameDecodeImageSet[pictureIndex].m_timestamp; 647e5c31af7Sopenharmony_ci pDecodedFrame->decodeOrder = m_perFrameDecodeImageSet[pictureIndex].m_decodeOrder; 648e5c31af7Sopenharmony_ci pDecodedFrame->displayOrder = m_perFrameDecodeImageSet[pictureIndex].m_displayOrder; 649e5c31af7Sopenharmony_ci 650e5c31af7Sopenharmony_ci pDecodedFrame->queryPool = m_queryPool; 651e5c31af7Sopenharmony_ci pDecodedFrame->startQueryId = pictureIndex; 652e5c31af7Sopenharmony_ci pDecodedFrame->numQueries = 1; 653e5c31af7Sopenharmony_ci } 654e5c31af7Sopenharmony_ci 655e5c31af7Sopenharmony_ci if (videoLoggingEnabled()) { 656e5c31af7Sopenharmony_ci std::cout << "<<<<<<<<<<< Dequeue from Display: " << pictureIndex << " out of " << numberofPendingFrames 657e5c31af7Sopenharmony_ci << " ===========" << std::endl; 658e5c31af7Sopenharmony_ci } 659e5c31af7Sopenharmony_ci return numberofPendingFrames; 660e5c31af7Sopenharmony_ci} 661e5c31af7Sopenharmony_ci 662e5c31af7Sopenharmony_ciint32_t VkVideoFrameBuffer::ReleaseDisplayedPicture(DecodedFrameRelease** pDecodedFramesRelease, deUint32 numFramesToRelease) 663e5c31af7Sopenharmony_ci{ 664e5c31af7Sopenharmony_ci std::lock_guard<std::mutex> lock(m_displayQueueMutex); 665e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < numFramesToRelease; i++) { 666e5c31af7Sopenharmony_ci const DecodedFrameRelease* pDecodedFrameRelease = pDecodedFramesRelease[i]; 667e5c31af7Sopenharmony_ci int picId = pDecodedFrameRelease->pictureIndex; 668e5c31af7Sopenharmony_ci DE_ASSERT((picId >= 0) && ((deUint32)picId < m_perFrameDecodeImageSet.size())); 669e5c31af7Sopenharmony_ci 670e5c31af7Sopenharmony_ci DE_ASSERT(m_perFrameDecodeImageSet[picId].m_decodeOrder == pDecodedFrameRelease->decodeOrder); 671e5c31af7Sopenharmony_ci DE_ASSERT(m_perFrameDecodeImageSet[picId].m_displayOrder == pDecodedFrameRelease->displayOrder); 672e5c31af7Sopenharmony_ci 673e5c31af7Sopenharmony_ci DE_ASSERT(m_ownedByDisplayMask & (1 << picId)); 674e5c31af7Sopenharmony_ci m_ownedByDisplayMask &= ~(1 << picId); 675e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].bitstreamData = nullptr; 676e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].stdPps = nullptr; 677e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].stdSps = nullptr; 678e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].stdVps = nullptr; 679e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].Release(); 680e5c31af7Sopenharmony_ci 681e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].m_hasConsummerSignalFence = pDecodedFrameRelease->hasConsummerSignalFence; 682e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet[picId].m_hasConsummerSignalSemaphore = pDecodedFrameRelease->hasConsummerSignalSemaphore; 683e5c31af7Sopenharmony_ci } 684e5c31af7Sopenharmony_ci return 0; 685e5c31af7Sopenharmony_ci} 686e5c31af7Sopenharmony_ci 687e5c31af7Sopenharmony_ciint32_t VkVideoFrameBuffer::GetDpbImageResourcesByIndex(deUint32 numResources, const int8_t* referenceSlotIndexes, VkVideoPictureResourceInfoKHR* dpbPictureResources, VulkanVideoFrameBuffer::PictureResourceInfo* dpbPictureResourcesInfo, VkImageLayout newDpbImageLayerLayout) 688e5c31af7Sopenharmony_ci{ 689e5c31af7Sopenharmony_ci DE_ASSERT(dpbPictureResources); 690e5c31af7Sopenharmony_ci std::lock_guard<std::mutex> lock(m_displayQueueMutex); 691e5c31af7Sopenharmony_ci for (unsigned int resId = 0; resId < numResources; resId++) { 692e5c31af7Sopenharmony_ci if ((deUint32)referenceSlotIndexes[resId] < m_perFrameDecodeImageSet.size()) { 693e5c31af7Sopenharmony_ci VkResult result = 694e5c31af7Sopenharmony_ci m_perFrameDecodeImageSet.GetImageSetNewLayout(m_vkDevCtx, referenceSlotIndexes[resId], newDpbImageLayerLayout, 695e5c31af7Sopenharmony_ci &dpbPictureResources[resId], &dpbPictureResourcesInfo[resId]); 696e5c31af7Sopenharmony_ci 697e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_SUCCESS); 698e5c31af7Sopenharmony_ci if (result != VK_SUCCESS) { 699e5c31af7Sopenharmony_ci return -1; 700e5c31af7Sopenharmony_ci } 701e5c31af7Sopenharmony_ci 702e5c31af7Sopenharmony_ci DE_ASSERT(dpbPictureResources[resId].sType == VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR); 703e5c31af7Sopenharmony_ci dpbPictureResources[resId].codedOffset = { 704e5c31af7Sopenharmony_ci 0, 0}; // FIXME: This parameter must to be adjusted based on the interlaced mode. 705e5c31af7Sopenharmony_ci dpbPictureResources[resId].codedExtent = m_codedExtent; 706e5c31af7Sopenharmony_ci } 707e5c31af7Sopenharmony_ci } 708e5c31af7Sopenharmony_ci return numResources; 709e5c31af7Sopenharmony_ci} 710e5c31af7Sopenharmony_ci 711e5c31af7Sopenharmony_ciint32_t VkVideoFrameBuffer::GetCurrentImageResourceByIndex(int8_t referenceSlotIndex, VkVideoPictureResourceInfoKHR* dpbPictureResource, VulkanVideoFrameBuffer::PictureResourceInfo* dpbPictureResourceInfo, VkImageLayout newDpbImageLayerLayout, VkVideoPictureResourceInfoKHR* outputPictureResource, VulkanVideoFrameBuffer::PictureResourceInfo* outputPictureResourceInfo, VkImageLayout newOutputImageLayerLayout) 712e5c31af7Sopenharmony_ci{ 713e5c31af7Sopenharmony_ci DE_ASSERT(dpbPictureResource); 714e5c31af7Sopenharmony_ci std::lock_guard<std::mutex> lock(m_displayQueueMutex); 715e5c31af7Sopenharmony_ci if ((deUint32)referenceSlotIndex < m_perFrameDecodeImageSet.size()) { 716e5c31af7Sopenharmony_ci VkResult result = m_perFrameDecodeImageSet.GetImageSetNewLayout( 717e5c31af7Sopenharmony_ci m_vkDevCtx, referenceSlotIndex, newDpbImageLayerLayout, dpbPictureResource, dpbPictureResourceInfo, 718e5c31af7Sopenharmony_ci newOutputImageLayerLayout, outputPictureResource, outputPictureResourceInfo); 719e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_SUCCESS); 720e5c31af7Sopenharmony_ci if (result != VK_SUCCESS) { 721e5c31af7Sopenharmony_ci return -1; 722e5c31af7Sopenharmony_ci } 723e5c31af7Sopenharmony_ci 724e5c31af7Sopenharmony_ci DE_ASSERT(dpbPictureResource->sType == VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR); 725e5c31af7Sopenharmony_ci dpbPictureResource->codedOffset = {0, 0}; // FIXME: This parameter must to be adjusted based on the interlaced mode. 726e5c31af7Sopenharmony_ci dpbPictureResource->codedExtent = m_codedExtent; 727e5c31af7Sopenharmony_ci 728e5c31af7Sopenharmony_ci if (outputPictureResource) { 729e5c31af7Sopenharmony_ci DE_ASSERT(outputPictureResource->sType == VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR); 730e5c31af7Sopenharmony_ci outputPictureResource->codedOffset = { 731e5c31af7Sopenharmony_ci 0, 0}; // FIXME: This parameter must to be adjusted based on the interlaced mode. 732e5c31af7Sopenharmony_ci outputPictureResource->codedExtent = m_codedExtent; 733e5c31af7Sopenharmony_ci } 734e5c31af7Sopenharmony_ci } 735e5c31af7Sopenharmony_ci return referenceSlotIndex; 736e5c31af7Sopenharmony_ci} 737e5c31af7Sopenharmony_ci 738e5c31af7Sopenharmony_ciint32_t VkVideoFrameBuffer::InitImagePool(const VkVideoProfileInfoKHR* pDecodeProfile, deUint32 numImages, VkFormat dpbImageFormat, VkFormat outImageFormat, const VkExtent2D& codedExtent, const VkExtent2D& maxImageExtent, VkImageUsageFlags dpbImageUsage, VkImageUsageFlags outImageUsage, deUint32 queueFamilyIndex, bool useImageArray, bool useImageViewArray, bool useSeparateOutputImage, bool useLinearOutput) 739e5c31af7Sopenharmony_ci{ 740e5c31af7Sopenharmony_ci std::lock_guard<std::mutex> lock(m_displayQueueMutex); 741e5c31af7Sopenharmony_ci 742e5c31af7Sopenharmony_ci DE_ASSERT(numImages && (numImages <= maxFramebufferImages) && pDecodeProfile); 743e5c31af7Sopenharmony_ci 744e5c31af7Sopenharmony_ci if (m_supportsQueries) 745e5c31af7Sopenharmony_ci VK_CHECK(CreateVideoQueries(numImages, m_vkDevCtx, pDecodeProfile)); 746e5c31af7Sopenharmony_ci 747e5c31af7Sopenharmony_ci // m_extent is for the codedExtent, not the max image resolution 748e5c31af7Sopenharmony_ci m_codedExtent = codedExtent; 749e5c31af7Sopenharmony_ci 750e5c31af7Sopenharmony_ci int32_t imageSetCreateResult = m_perFrameDecodeImageSet.init( 751e5c31af7Sopenharmony_ci m_vkDevCtx, pDecodeProfile, numImages, dpbImageFormat, outImageFormat, maxImageExtent, dpbImageUsage, outImageUsage, 752e5c31af7Sopenharmony_ci queueFamilyIndex, 753e5c31af7Sopenharmony_ci useImageArray, useImageViewArray, useSeparateOutputImage, useLinearOutput); 754e5c31af7Sopenharmony_ci m_numberParameterUpdates++; 755e5c31af7Sopenharmony_ci 756e5c31af7Sopenharmony_ci return imageSetCreateResult; 757e5c31af7Sopenharmony_ci} 758e5c31af7Sopenharmony_ci 759e5c31af7Sopenharmony_ciVkResult NvPerFrameDecodeResources::CreateImage( DeviceContext& vkDevCtx, 760e5c31af7Sopenharmony_ci const VkImageCreateInfo* pDpbImageCreateInfo, 761e5c31af7Sopenharmony_ci const VkImageCreateInfo* pOutImageCreateInfo, 762e5c31af7Sopenharmony_ci deUint32 imageIndex, 763e5c31af7Sopenharmony_ci VkSharedBaseObj<VkImageResource>& imageArrayParent, 764e5c31af7Sopenharmony_ci VkSharedBaseObj<VkImageResourceView>& imageViewArrayParent, 765e5c31af7Sopenharmony_ci bool useSeparateOutputImage, 766e5c31af7Sopenharmony_ci bool useLinearOutput) 767e5c31af7Sopenharmony_ci{ 768e5c31af7Sopenharmony_ci VkResult result = VK_SUCCESS; 769e5c31af7Sopenharmony_ci 770e5c31af7Sopenharmony_ci if (!ImageExist() || m_recreateImage) { 771e5c31af7Sopenharmony_ci 772e5c31af7Sopenharmony_ci DE_ASSERT(m_vkDevCtx != nullptr); 773e5c31af7Sopenharmony_ci 774e5c31af7Sopenharmony_ci m_currentDpbImageLayerLayout = pDpbImageCreateInfo->initialLayout; 775e5c31af7Sopenharmony_ci m_currentOutputImageLayout = pOutImageCreateInfo->initialLayout; 776e5c31af7Sopenharmony_ci 777e5c31af7Sopenharmony_ci VkSharedBaseObj<VkImageResource> imageResource; 778e5c31af7Sopenharmony_ci if (!imageArrayParent) { 779e5c31af7Sopenharmony_ci result = VkImageResource::Create(vkDevCtx, 780e5c31af7Sopenharmony_ci pDpbImageCreateInfo, 781e5c31af7Sopenharmony_ci imageResource); 782e5c31af7Sopenharmony_ci if (result != VK_SUCCESS) { 783e5c31af7Sopenharmony_ci return result; 784e5c31af7Sopenharmony_ci } 785e5c31af7Sopenharmony_ci } else { 786e5c31af7Sopenharmony_ci // We are using a parent array image 787e5c31af7Sopenharmony_ci imageResource = imageArrayParent; 788e5c31af7Sopenharmony_ci } 789e5c31af7Sopenharmony_ci 790e5c31af7Sopenharmony_ci if (!imageViewArrayParent) { 791e5c31af7Sopenharmony_ci 792e5c31af7Sopenharmony_ci deUint32 baseArrayLayer = imageArrayParent ? imageIndex : 0; 793e5c31af7Sopenharmony_ci VkImageSubresourceRange subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, baseArrayLayer, 1 }; 794e5c31af7Sopenharmony_ci result = VkImageResourceView::Create(vkDevCtx, imageResource, 795e5c31af7Sopenharmony_ci subresourceRange, 796e5c31af7Sopenharmony_ci m_frameDpbImageView); 797e5c31af7Sopenharmony_ci 798e5c31af7Sopenharmony_ci if (result != VK_SUCCESS) { 799e5c31af7Sopenharmony_ci return result; 800e5c31af7Sopenharmony_ci } 801e5c31af7Sopenharmony_ci 802e5c31af7Sopenharmony_ci if (!(useSeparateOutputImage || useLinearOutput)) { 803e5c31af7Sopenharmony_ci m_outImageView = m_frameDpbImageView; 804e5c31af7Sopenharmony_ci } 805e5c31af7Sopenharmony_ci 806e5c31af7Sopenharmony_ci } else { 807e5c31af7Sopenharmony_ci 808e5c31af7Sopenharmony_ci m_frameDpbImageView = imageViewArrayParent; 809e5c31af7Sopenharmony_ci 810e5c31af7Sopenharmony_ci if (!(useSeparateOutputImage || useLinearOutput)) { 811e5c31af7Sopenharmony_ci VkImageSubresourceRange subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, imageIndex, 1 }; 812e5c31af7Sopenharmony_ci result = VkImageResourceView::Create(vkDevCtx, imageResource, 813e5c31af7Sopenharmony_ci subresourceRange, 814e5c31af7Sopenharmony_ci m_outImageView); 815e5c31af7Sopenharmony_ci if (result != VK_SUCCESS) { 816e5c31af7Sopenharmony_ci return result; 817e5c31af7Sopenharmony_ci } 818e5c31af7Sopenharmony_ci } 819e5c31af7Sopenharmony_ci } 820e5c31af7Sopenharmony_ci 821e5c31af7Sopenharmony_ci if (useSeparateOutputImage || useLinearOutput) { 822e5c31af7Sopenharmony_ci 823e5c31af7Sopenharmony_ci VkSharedBaseObj<VkImageResource> displayImageResource; 824e5c31af7Sopenharmony_ci result = VkImageResource::Create(vkDevCtx, 825e5c31af7Sopenharmony_ci pOutImageCreateInfo, 826e5c31af7Sopenharmony_ci displayImageResource); 827e5c31af7Sopenharmony_ci if (result != VK_SUCCESS) { 828e5c31af7Sopenharmony_ci return result; 829e5c31af7Sopenharmony_ci } 830e5c31af7Sopenharmony_ci 831e5c31af7Sopenharmony_ci VkImageSubresourceRange subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; 832e5c31af7Sopenharmony_ci result = VkImageResourceView::Create(vkDevCtx, displayImageResource, 833e5c31af7Sopenharmony_ci subresourceRange, 834e5c31af7Sopenharmony_ci m_outImageView); 835e5c31af7Sopenharmony_ci if (result != VK_SUCCESS) { 836e5c31af7Sopenharmony_ci return result; 837e5c31af7Sopenharmony_ci } 838e5c31af7Sopenharmony_ci } 839e5c31af7Sopenharmony_ci } 840e5c31af7Sopenharmony_ci 841e5c31af7Sopenharmony_ci m_currentDpbImageLayerLayout = VK_IMAGE_LAYOUT_UNDEFINED; 842e5c31af7Sopenharmony_ci m_currentOutputImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; 843e5c31af7Sopenharmony_ci m_recreateImage = false; 844e5c31af7Sopenharmony_ci 845e5c31af7Sopenharmony_ci return result; 846e5c31af7Sopenharmony_ci} 847e5c31af7Sopenharmony_ci 848e5c31af7Sopenharmony_ciVkResult NvPerFrameDecodeResources::init(DeviceContext& vkDevCtx) 849e5c31af7Sopenharmony_ci{ 850e5c31af7Sopenharmony_ci m_vkDevCtx = &vkDevCtx; 851e5c31af7Sopenharmony_ci auto& vk = vkDevCtx.getDeviceDriver(); 852e5c31af7Sopenharmony_ci auto device = vkDevCtx.device; 853e5c31af7Sopenharmony_ci 854e5c31af7Sopenharmony_ci // The fence waited on for the first frame should be signaled. 855e5c31af7Sopenharmony_ci const VkFenceCreateInfo fenceFrameCompleteInfo = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 856e5c31af7Sopenharmony_ci VK_FENCE_CREATE_SIGNALED_BIT }; 857e5c31af7Sopenharmony_ci VkResult result = vk.createFence(device, &fenceFrameCompleteInfo, nullptr, &m_frameCompleteFence); 858e5c31af7Sopenharmony_ci 859e5c31af7Sopenharmony_ci VkFenceCreateInfo fenceInfo{}; 860e5c31af7Sopenharmony_ci fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 861e5c31af7Sopenharmony_ci result = vk.createFence(device, &fenceInfo, nullptr, &m_frameConsumerDoneFence); 862e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_SUCCESS); 863e5c31af7Sopenharmony_ci 864e5c31af7Sopenharmony_ci VkSemaphoreCreateInfo semInfo{}; 865e5c31af7Sopenharmony_ci semInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 866e5c31af7Sopenharmony_ci result = vk.createSemaphore(device, &semInfo, nullptr, &m_frameCompleteSemaphore); 867e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_SUCCESS); 868e5c31af7Sopenharmony_ci result = vk.createSemaphore(device, &semInfo, nullptr, &m_frameConsumerDoneSemaphore); 869e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_SUCCESS); 870e5c31af7Sopenharmony_ci 871e5c31af7Sopenharmony_ci Reset(); 872e5c31af7Sopenharmony_ci 873e5c31af7Sopenharmony_ci return result; 874e5c31af7Sopenharmony_ci} 875e5c31af7Sopenharmony_ci 876e5c31af7Sopenharmony_civoid NvPerFrameDecodeResources::Deinit() 877e5c31af7Sopenharmony_ci{ 878e5c31af7Sopenharmony_ci bitstreamData = nullptr; 879e5c31af7Sopenharmony_ci stdPps = nullptr; 880e5c31af7Sopenharmony_ci stdSps = nullptr; 881e5c31af7Sopenharmony_ci stdVps = nullptr; 882e5c31af7Sopenharmony_ci 883e5c31af7Sopenharmony_ci if (m_vkDevCtx == nullptr) { 884e5c31af7Sopenharmony_ci assert ((m_frameCompleteFence == VK_NULL_HANDLE) && 885e5c31af7Sopenharmony_ci (m_frameConsumerDoneFence == VK_NULL_HANDLE) && 886e5c31af7Sopenharmony_ci (m_frameCompleteSemaphore == VK_NULL_HANDLE) && 887e5c31af7Sopenharmony_ci (m_frameConsumerDoneSemaphore == VK_NULL_HANDLE) && 888e5c31af7Sopenharmony_ci !m_frameDpbImageView && 889e5c31af7Sopenharmony_ci !m_outImageView); 890e5c31af7Sopenharmony_ci return; 891e5c31af7Sopenharmony_ci } 892e5c31af7Sopenharmony_ci 893e5c31af7Sopenharmony_ci DE_ASSERT(m_vkDevCtx); 894e5c31af7Sopenharmony_ci auto& vk = m_vkDevCtx->getDeviceDriver(); 895e5c31af7Sopenharmony_ci auto device = m_vkDevCtx->device; 896e5c31af7Sopenharmony_ci 897e5c31af7Sopenharmony_ci if (m_frameCompleteFence != VK_NULL_HANDLE) { 898e5c31af7Sopenharmony_ci vk.destroyFence(device, m_frameCompleteFence, nullptr); 899e5c31af7Sopenharmony_ci m_frameCompleteFence = VK_NULL_HANDLE; 900e5c31af7Sopenharmony_ci } 901e5c31af7Sopenharmony_ci 902e5c31af7Sopenharmony_ci if (m_frameConsumerDoneFence != VK_NULL_HANDLE) { 903e5c31af7Sopenharmony_ci vk.destroyFence(device, m_frameConsumerDoneFence, nullptr); 904e5c31af7Sopenharmony_ci m_frameConsumerDoneFence = VK_NULL_HANDLE; 905e5c31af7Sopenharmony_ci } 906e5c31af7Sopenharmony_ci 907e5c31af7Sopenharmony_ci if (m_frameCompleteSemaphore != VK_NULL_HANDLE) { 908e5c31af7Sopenharmony_ci vk.destroySemaphore(device, m_frameCompleteSemaphore, nullptr); 909e5c31af7Sopenharmony_ci m_frameCompleteSemaphore = VK_NULL_HANDLE; 910e5c31af7Sopenharmony_ci } 911e5c31af7Sopenharmony_ci 912e5c31af7Sopenharmony_ci if (m_frameConsumerDoneSemaphore != VK_NULL_HANDLE) { 913e5c31af7Sopenharmony_ci vk.destroySemaphore(device, m_frameConsumerDoneSemaphore, nullptr); 914e5c31af7Sopenharmony_ci m_frameConsumerDoneSemaphore = VK_NULL_HANDLE; 915e5c31af7Sopenharmony_ci } 916e5c31af7Sopenharmony_ci 917e5c31af7Sopenharmony_ci m_frameDpbImageView = nullptr; 918e5c31af7Sopenharmony_ci m_outImageView = nullptr; 919e5c31af7Sopenharmony_ci 920e5c31af7Sopenharmony_ci m_vkDevCtx = nullptr; 921e5c31af7Sopenharmony_ci 922e5c31af7Sopenharmony_ci Reset(); 923e5c31af7Sopenharmony_ci} 924e5c31af7Sopenharmony_ci 925e5c31af7Sopenharmony_ciint32_t NvPerFrameDecodeImageSet::init(DeviceContext& vkDevCtx, 926e5c31af7Sopenharmony_ci const VkVideoProfileInfoKHR* pDecodeProfile, 927e5c31af7Sopenharmony_ci deUint32 numImages, 928e5c31af7Sopenharmony_ci VkFormat dpbImageFormat, 929e5c31af7Sopenharmony_ci VkFormat outImageFormat, 930e5c31af7Sopenharmony_ci const VkExtent2D& maxImageExtent, 931e5c31af7Sopenharmony_ci VkImageUsageFlags dpbImageUsage, 932e5c31af7Sopenharmony_ci VkImageUsageFlags outImageUsage, 933e5c31af7Sopenharmony_ci deUint32 queueFamilyIndex, 934e5c31af7Sopenharmony_ci bool useImageArray, 935e5c31af7Sopenharmony_ci bool useImageViewArray, 936e5c31af7Sopenharmony_ci bool useSeparateOutputImage, 937e5c31af7Sopenharmony_ci bool useLinearOutput) 938e5c31af7Sopenharmony_ci{ 939e5c31af7Sopenharmony_ci if (numImages > m_perFrameDecodeResources.size()) { 940e5c31af7Sopenharmony_ci DE_ASSERT(!"Number of requested images exceeds the max size of the image array"); 941e5c31af7Sopenharmony_ci return -1; 942e5c31af7Sopenharmony_ci } 943e5c31af7Sopenharmony_ci 944e5c31af7Sopenharmony_ci const bool reconfigureImages = (m_numImages && 945e5c31af7Sopenharmony_ci (m_dpbImageCreateInfo.sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO)) && 946e5c31af7Sopenharmony_ci ((m_dpbImageCreateInfo.format != dpbImageFormat) || 947e5c31af7Sopenharmony_ci (m_dpbImageCreateInfo.extent.width < maxImageExtent.width) || 948e5c31af7Sopenharmony_ci (m_dpbImageCreateInfo.extent.height < maxImageExtent.height)); 949e5c31af7Sopenharmony_ci 950e5c31af7Sopenharmony_ci for (deUint32 imageIndex = m_numImages; imageIndex < numImages; imageIndex++) { 951e5c31af7Sopenharmony_ci VkResult result = m_perFrameDecodeResources[imageIndex].init(vkDevCtx); 952e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_SUCCESS); 953e5c31af7Sopenharmony_ci if (result != VK_SUCCESS) { 954e5c31af7Sopenharmony_ci return -1; 955e5c31af7Sopenharmony_ci } 956e5c31af7Sopenharmony_ci } 957e5c31af7Sopenharmony_ci 958e5c31af7Sopenharmony_ci if (useImageViewArray) { 959e5c31af7Sopenharmony_ci useImageArray = true; 960e5c31af7Sopenharmony_ci } 961e5c31af7Sopenharmony_ci 962e5c31af7Sopenharmony_ci m_videoProfile.InitFromProfile(pDecodeProfile); 963e5c31af7Sopenharmony_ci 964e5c31af7Sopenharmony_ci m_queueFamilyIndex = queueFamilyIndex; 965e5c31af7Sopenharmony_ci 966e5c31af7Sopenharmony_ci // Image create info for the DPBs 967e5c31af7Sopenharmony_ci m_dpbImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 968e5c31af7Sopenharmony_ci // m_imageCreateInfo.pNext = m_videoProfile.GetProfile(); 969e5c31af7Sopenharmony_ci m_dpbImageCreateInfo.pNext = m_videoProfile.GetProfileListInfo(); 970e5c31af7Sopenharmony_ci m_dpbImageCreateInfo.imageType = VK_IMAGE_TYPE_2D; 971e5c31af7Sopenharmony_ci m_dpbImageCreateInfo.format = dpbImageFormat; 972e5c31af7Sopenharmony_ci m_dpbImageCreateInfo.extent = { maxImageExtent.width, maxImageExtent.height, 1 }; 973e5c31af7Sopenharmony_ci m_dpbImageCreateInfo.mipLevels = 1; 974e5c31af7Sopenharmony_ci m_dpbImageCreateInfo.arrayLayers = useImageArray ? numImages : 1; 975e5c31af7Sopenharmony_ci m_dpbImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; 976e5c31af7Sopenharmony_ci m_dpbImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; 977e5c31af7Sopenharmony_ci m_dpbImageCreateInfo.usage = dpbImageUsage; 978e5c31af7Sopenharmony_ci m_dpbImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 979e5c31af7Sopenharmony_ci m_dpbImageCreateInfo.queueFamilyIndexCount = 1; 980e5c31af7Sopenharmony_ci m_dpbImageCreateInfo.pQueueFamilyIndices = &m_queueFamilyIndex; 981e5c31af7Sopenharmony_ci m_dpbImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 982e5c31af7Sopenharmony_ci m_dpbImageCreateInfo.flags = 0; 983e5c31af7Sopenharmony_ci 984e5c31af7Sopenharmony_ci // Image create info for the output 985e5c31af7Sopenharmony_ci if (useSeparateOutputImage || useLinearOutput) { 986e5c31af7Sopenharmony_ci m_outImageCreateInfo = m_dpbImageCreateInfo; 987e5c31af7Sopenharmony_ci m_outImageCreateInfo.format = outImageFormat; 988e5c31af7Sopenharmony_ci m_outImageCreateInfo.arrayLayers = 1; 989e5c31af7Sopenharmony_ci m_outImageCreateInfo.tiling = useLinearOutput ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL; 990e5c31af7Sopenharmony_ci m_outImageCreateInfo.usage = outImageUsage; 991e5c31af7Sopenharmony_ci 992e5c31af7Sopenharmony_ci if ((outImageUsage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR) == 0) { 993e5c31af7Sopenharmony_ci // A simple output image not directly used by the decoder 994e5c31af7Sopenharmony_ci m_outImageCreateInfo.pNext = nullptr; 995e5c31af7Sopenharmony_ci } 996e5c31af7Sopenharmony_ci } 997e5c31af7Sopenharmony_ci 998e5c31af7Sopenharmony_ci if (useImageArray) { 999e5c31af7Sopenharmony_ci // Create an image that has the same number of layers as the DPB images required. 1000e5c31af7Sopenharmony_ci VkResult result = VkImageResource::Create(vkDevCtx, 1001e5c31af7Sopenharmony_ci &m_dpbImageCreateInfo, 1002e5c31af7Sopenharmony_ci m_imageArray); 1003e5c31af7Sopenharmony_ci if (result != VK_SUCCESS) { 1004e5c31af7Sopenharmony_ci return -1; 1005e5c31af7Sopenharmony_ci } 1006e5c31af7Sopenharmony_ci } else { 1007e5c31af7Sopenharmony_ci m_imageArray = nullptr; 1008e5c31af7Sopenharmony_ci } 1009e5c31af7Sopenharmony_ci 1010e5c31af7Sopenharmony_ci if (useImageViewArray) { 1011e5c31af7Sopenharmony_ci DE_ASSERT(m_imageArray); 1012e5c31af7Sopenharmony_ci // Create an image view that has the same number of layers as the image. 1013e5c31af7Sopenharmony_ci // In that scenario, while specifying the resource, the API must specifically choose the image layer. 1014e5c31af7Sopenharmony_ci VkImageSubresourceRange subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, numImages }; 1015e5c31af7Sopenharmony_ci VkResult result = VkImageResourceView::Create(vkDevCtx, m_imageArray, 1016e5c31af7Sopenharmony_ci subresourceRange, 1017e5c31af7Sopenharmony_ci m_imageViewArray); 1018e5c31af7Sopenharmony_ci 1019e5c31af7Sopenharmony_ci if (result != VK_SUCCESS) { 1020e5c31af7Sopenharmony_ci return -1; 1021e5c31af7Sopenharmony_ci } 1022e5c31af7Sopenharmony_ci } 1023e5c31af7Sopenharmony_ci 1024e5c31af7Sopenharmony_ci deUint32 firstIndex = reconfigureImages ? 0 : m_numImages; 1025e5c31af7Sopenharmony_ci deUint32 maxNumImages = std::max(m_numImages, numImages); 1026e5c31af7Sopenharmony_ci for (deUint32 imageIndex = firstIndex; imageIndex < maxNumImages; imageIndex++) { 1027e5c31af7Sopenharmony_ci 1028e5c31af7Sopenharmony_ci if (m_perFrameDecodeResources[imageIndex].ImageExist() && reconfigureImages) { 1029e5c31af7Sopenharmony_ci 1030e5c31af7Sopenharmony_ci m_perFrameDecodeResources[imageIndex].m_recreateImage = true; 1031e5c31af7Sopenharmony_ci 1032e5c31af7Sopenharmony_ci } else if (!m_perFrameDecodeResources[imageIndex].ImageExist()) { 1033e5c31af7Sopenharmony_ci 1034e5c31af7Sopenharmony_ci VkResult result = 1035e5c31af7Sopenharmony_ci m_perFrameDecodeResources[imageIndex].CreateImage(vkDevCtx, 1036e5c31af7Sopenharmony_ci &m_dpbImageCreateInfo, 1037e5c31af7Sopenharmony_ci &m_outImageCreateInfo, 1038e5c31af7Sopenharmony_ci imageIndex, 1039e5c31af7Sopenharmony_ci m_imageArray, 1040e5c31af7Sopenharmony_ci m_imageViewArray, 1041e5c31af7Sopenharmony_ci useSeparateOutputImage, 1042e5c31af7Sopenharmony_ci useLinearOutput); 1043e5c31af7Sopenharmony_ci 1044e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_SUCCESS); 1045e5c31af7Sopenharmony_ci if (result != VK_SUCCESS) { 1046e5c31af7Sopenharmony_ci return -1; 1047e5c31af7Sopenharmony_ci } 1048e5c31af7Sopenharmony_ci } 1049e5c31af7Sopenharmony_ci } 1050e5c31af7Sopenharmony_ci 1051e5c31af7Sopenharmony_ci m_numImages = numImages; 1052e5c31af7Sopenharmony_ci m_usesImageArray = useImageArray; 1053e5c31af7Sopenharmony_ci m_usesImageViewArray = useImageViewArray; 1054e5c31af7Sopenharmony_ci m_usesSeparateOutputImage = useSeparateOutputImage; 1055e5c31af7Sopenharmony_ci m_usesLinearOutput = useLinearOutput; 1056e5c31af7Sopenharmony_ci 1057e5c31af7Sopenharmony_ci return (int32_t)numImages; 1058e5c31af7Sopenharmony_ci} 1059e5c31af7Sopenharmony_ci 1060e5c31af7Sopenharmony_ci} // namespace video 1061e5c31af7Sopenharmony_ci} // namespace vkt 1062