diff --git a/vk_video_decoder/demos/vk-video-dec/Main.cpp b/vk_video_decoder/demos/vk-video-dec/Main.cpp index 3e499c32..f3a7ae9a 100644 --- a/vk_video_decoder/demos/vk-video-dec/Main.cpp +++ b/vk_video_decoder/demos/vk-video-dec/Main.cpp @@ -115,7 +115,7 @@ int main(int argc, const char **argv) vkDevCtxt.CreateVulkanDevice(numDecodeQueues, // numDecodeQueues 0, // num encode queues videoCodecOperation, // videoCodecs - false, // createTransferQueue + ((vkDevCtxt.GetVideoDecodeQueueFlag() & VK_QUEUE_TRANSFER_BIT) == 0), // createTransferQueue true, // createGraphicsQueue true, // createDisplayQueue requestVideoComputeQueueMask != 0 // createComputeQueue diff --git a/vk_video_decoder/libs/VkVideoDecoder/VkVideoDecoder.cpp b/vk_video_decoder/libs/VkVideoDecoder/VkVideoDecoder.cpp index 6bff5ce5..fd3cc17e 100644 --- a/vk_video_decoder/libs/VkVideoDecoder/VkVideoDecoder.cpp +++ b/vk_video_decoder/libs/VkVideoDecoder/VkVideoDecoder.cpp @@ -1132,7 +1132,7 @@ int VkVideoDecoder::DecodePictureWithParameters(VkParserPerFrameDecodeParameters VkVideoEndCodingInfoKHR decodeEndInfo = { VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR }; m_vkDevCtx->CmdEndVideoCodingKHR(frameDataSlot.commandBuffer, &decodeEndInfo); - if (m_useTransferOperation == VK_TRUE) { + if (m_useTransferOperation == VK_TRUE && m_transferCommandPool == VK_NULL_HANDLE) { assert((pOutputPictureResource != nullptr) && (pOutputPictureResourceInfo != nullptr)); @@ -1270,6 +1270,47 @@ int VkVideoDecoder::DecodePictureWithParameters(VkParserPerFrameDecodeParameters } } + if (m_useTransferOperation == VK_TRUE && m_transferCommandPool != VK_NULL_HANDLE) { + VkFence transferCompleteFence = VkFence(); + VkFenceCreateInfo fence_info = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; + assert(m_vkDevCtx->CreateFence(*m_vkDevCtx, &fence_info, nullptr, &transferCompleteFence) == VK_SUCCESS); + const VkPipelineStageFlags waitDstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; + assert((pOutputPictureResource != nullptr) && (pOutputPictureResourceInfo != nullptr)); + VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; + beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + beginInfo.pInheritanceInfo = nullptr; + + m_vkDevCtx->BeginCommandBuffer(m_transferCommandBuffers[0], &beginInfo); + + CopyOptimalToLinearImage(m_transferCommandBuffers[0], + *pOutputPictureResource, + *pOutputPictureResourceInfo, + *pFrameFilterOutResource, + *pFrameFilterOutResourceInfo, + &frameSynchronizationInfo); + m_vkDevCtx->EndCommandBuffer(m_transferCommandBuffers[0]); + + const VkSubmitInfo transferSubmitInfo{ + VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; + nullptr, // const void* pNext; + 1u, // uint32_t waitSemaphoreCount; + &videoDecodeCompleteSemaphore, // const VkSemaphore* pWaitSemaphores; + &waitDstStageMask, // const VkPipelineStageFlags* pWaitDstStageMask; + 1u, // uint32_t commandBufferCount; + &m_transferCommandBuffers[0], // const VkCommandBuffer* pCommandBuffers; + 1u, // uint32_t signalSemaphoreCount; + &videoDecodeCompleteSemaphore, // const VkSemaphore* pSignalSemaphores; + }; + assert(VK_NOT_READY == m_vkDevCtx->GetFenceStatus(*m_vkDevCtx, transferCompleteFence)); + VkResult result = m_vkDevCtx->MultiThreadedQueueSubmit(VulkanDeviceContext::TRANSFER, m_vkDevCtx->GetTransferQueueFamilyIdx(), + 1, &transferSubmitInfo, transferCompleteFence); + result = m_vkDevCtx->WaitForFences(*m_vkDevCtx, 1, &transferCompleteFence, true, gFenceTimeout); + assert(result == VK_SUCCESS); + result = m_vkDevCtx->GetFenceStatus(*m_vkDevCtx, transferCompleteFence); + assert(result == VK_SUCCESS); + } + if (m_dumpDecodeData && (m_hwLoadBalancingTimelineSemaphore != VK_NULL_HANDLE)) { // For TL semaphore debug uint64_t currSemValue = 0; VkResult semResult = m_vkDevCtx->GetSemaphoreCounterValue(*m_vkDevCtx, m_hwLoadBalancingTimelineSemaphore, &currSemValue); diff --git a/vk_video_decoder/libs/VkVideoDecoder/VkVideoDecoder.h b/vk_video_decoder/libs/VkVideoDecoder/VkVideoDecoder.h index 32839be4..6b6976c3 100644 --- a/vk_video_decoder/libs/VkVideoDecoder/VkVideoDecoder.h +++ b/vk_video_decoder/libs/VkVideoDecoder/VkVideoDecoder.h @@ -237,8 +237,8 @@ class VkVideoDecoder : public IVulkanVideoDecoderHandler { , m_numBitstreamBuffersToPreallocate(numBitstreamBuffersToPreallocate) , m_maxStreamBufferSize() , m_filterType(filterType) + , m_transferCommandPool() { - assert(m_vkDevCtx->GetVideoDecodeQueueFamilyIdx() != -1); assert(m_vkDevCtx->GetVideoDecodeNumQueues() > 0); @@ -279,6 +279,30 @@ class VkVideoDecoder : public IVulkanVideoDecoderHandler { << m_vkDevCtx->GetVideoDecodeNumQueues() << " queues" << std::endl; } + if (m_vkDevCtx->GetTransferQueue() != VkQueue()) { + VkCommandPoolCreateInfo cmdPoolInfo = {}; + cmdPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + cmdPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + cmdPoolInfo.queueFamilyIndex = m_vkDevCtx->GetTransferQueueFamilyIdx(); + VkResult result = m_vkDevCtx->CreateCommandPool(*m_vkDevCtx, &cmdPoolInfo, nullptr, &m_transferCommandPool); + assert(result == VK_SUCCESS); + if (result != VK_SUCCESS) { + fprintf(stderr, "\nERROR: CreateCommandPool() result: 0x%x\n", result); + } + + VkCommandBufferAllocateInfo cmdInfo = {}; + cmdInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + cmdInfo.commandBufferCount = 1; + cmdInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + cmdInfo.commandPool = m_transferCommandPool; + + m_transferCommandBuffers.resize(1); + result = m_vkDevCtx->AllocateCommandBuffers(*m_vkDevCtx, &cmdInfo, &m_transferCommandBuffers[0]); + if (result != VK_SUCCESS) { + fprintf(stderr, "\nERROR: AllocateCommandBuffers() result: 0x%x\n", result); + } + } + } virtual ~VkVideoDecoder(); @@ -339,4 +363,7 @@ class VkVideoDecoder : public IVulkanVideoDecoderHandler { VkDeviceSize m_maxStreamBufferSize; VulkanFilterYuvCompute::FilterType m_filterType; VkSharedBaseObj m_yuvFilter; + VkCommandPool m_transferCommandPool; + std::vector m_transferCommandBuffers; + }; diff --git a/vk_video_decoder/test/vulkan-video-dec/Main.cpp b/vk_video_decoder/test/vulkan-video-dec/Main.cpp index 5a02d1b3..f0fbe764 100644 --- a/vk_video_decoder/test/vulkan-video-dec/Main.cpp +++ b/vk_video_decoder/test/vulkan-video-dec/Main.cpp @@ -90,7 +90,7 @@ int main(int argc, const char** argv) requestVideoComputeQueueMask = VK_QUEUE_COMPUTE_BIT; } - VkVideoCodecOperationFlagsKHR videoCodec = decoderConfig.forceParserType != VK_VIDEO_CODEC_OPERATION_NONE_KHR ? + VkVideoCodecOperationFlagsKHR videoCodec = decoderConfig.forceParserType != VK_VIDEO_CODEC_OPERATION_NONE_KHR ? decoderConfig.forceParserType : videoStreamDemuxer->GetVideoCodec(); @@ -126,7 +126,7 @@ int main(int argc, const char** argv) vkDevCtxt.CreateVulkanDevice(numDecodeQueues, 0, // num encode queues videoCodec, - false, // createTransferQueue + ((vkDevCtxt.GetVideoDecodeQueueFlag() & VK_QUEUE_TRANSFER_BIT) == 0), // createTransferQueue true, // createGraphicsQueue true, // createDisplayQueue requestVideoComputeQueueMask != 0 // createComputeQueue