CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Common/GPU/Vulkan/VulkanBarrier.cpp
Views: 1401
#include "VulkanLoader.h"1#include "VulkanContext.h"2#include "VulkanBarrier.h"3#include "VulkanFramebuffer.h"45#include "Common/Log.h"67VulkanBarrierBatch::~VulkanBarrierBatch() {8// _dbg_assert_(imageBarriers_.empty());9if (!imageBarriers_.empty()) {10ERROR_LOG(Log::G3D, "~VulkanBarrierBatch: %d barriers remaining", (int)imageBarriers_.size());11}12}1314void VulkanBarrierBatch::Flush(VkCommandBuffer cmd) {15if (!imageBarriers_.empty()) {16vkCmdPipelineBarrier(cmd, srcStageMask_, dstStageMask_, dependencyFlags_, 0, nullptr, 0, nullptr, (uint32_t)imageBarriers_.size(), imageBarriers_.data());17}18imageBarriers_.clear();19srcStageMask_ = 0;20dstStageMask_ = 0;21dependencyFlags_ = 0;22}2324void VulkanBarrierBatch::TransitionImage(25VkImage image, int baseMip, int numMipLevels, int numLayers, VkImageAspectFlags aspectMask,26VkImageLayout oldImageLayout, VkImageLayout newImageLayout,27VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask,28VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask29) {30_dbg_assert_(image != VK_NULL_HANDLE);3132srcStageMask_ |= srcStageMask;33dstStageMask_ |= dstStageMask;34dependencyFlags_ |= VK_DEPENDENCY_BY_REGION_BIT;3536VkImageMemoryBarrier &imageBarrier = imageBarriers_.push_uninitialized();37imageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;38imageBarrier.pNext = nullptr;39imageBarrier.srcAccessMask = srcAccessMask;40imageBarrier.dstAccessMask = dstAccessMask;41imageBarrier.oldLayout = oldImageLayout;42imageBarrier.newLayout = newImageLayout;43imageBarrier.image = image;44imageBarrier.subresourceRange.aspectMask = aspectMask;45imageBarrier.subresourceRange.baseMipLevel = baseMip;46imageBarrier.subresourceRange.levelCount = numMipLevels;47imageBarrier.subresourceRange.layerCount = numLayers; // NOTE: We could usually use VK_REMAINING_ARRAY_LAYERS/VK_REMAINING_MIP_LEVELS, but really old Mali drivers have problems with those.48imageBarrier.subresourceRange.baseArrayLayer = 0;49imageBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;50imageBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;51}5253void VulkanBarrierBatch::TransitionColorImageAuto(54VkImage image, VkImageLayout *imageLayout, VkImageLayout newImageLayout, int baseMip, int numMipLevels, int numLayers) {55_dbg_assert_(image != VK_NULL_HANDLE);56VkAccessFlags srcAccessMask = 0;57VkAccessFlags dstAccessMask = 0;58switch (*imageLayout) {59case VK_IMAGE_LAYOUT_UNDEFINED:60srcAccessMask = 0;61srcStageMask_ |= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;62break;63case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:64srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;65srcStageMask_ |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;66break;67case VK_IMAGE_LAYOUT_GENERAL:68// We came from the Mali workaround, and are transitioning back to COLOR_ATTACHMENT_OPTIMAL.69srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;70srcStageMask_ |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;71break;72case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:73// We only texture from images in the fragment shader, so can do this simply.74srcAccessMask = VK_ACCESS_SHADER_READ_BIT;75srcStageMask_ |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;76break;77case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:78srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;79srcStageMask_ |= VK_PIPELINE_STAGE_TRANSFER_BIT;80break;81case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:82srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;83srcStageMask_ |= VK_PIPELINE_STAGE_TRANSFER_BIT;84break;85default:86_assert_msg_(false, "Unexpected oldLayout: %s", VulkanImageLayoutToString(*imageLayout));87break;88}8990switch (newImageLayout) {91case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:92dstAccessMask = VK_ACCESS_SHADER_READ_BIT;93dstStageMask_ |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;94break;95case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:96dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;97dstStageMask_ |= VK_PIPELINE_STAGE_TRANSFER_BIT;98break;99case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:100dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;101dstStageMask_ |= VK_PIPELINE_STAGE_TRANSFER_BIT;102break;103case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:104dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;105dstStageMask_ |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;106break;107default:108_assert_msg_(false, "Unexpected newLayout: %s", VulkanImageLayoutToString(newImageLayout));109break;110}111112VkImageMemoryBarrier &imageBarrier = imageBarriers_.push_uninitialized();113imageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;114imageBarrier.pNext = nullptr;115imageBarrier.srcAccessMask = srcAccessMask;116imageBarrier.dstAccessMask = dstAccessMask;117imageBarrier.oldLayout = *imageLayout;118imageBarrier.newLayout = newImageLayout;119imageBarrier.image = image;120imageBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;121imageBarrier.subresourceRange.baseMipLevel = baseMip;122imageBarrier.subresourceRange.levelCount = numMipLevels;123imageBarrier.subresourceRange.layerCount = numLayers; // NOTE: We could usually use VK_REMAINING_ARRAY_LAYERS/VK_REMAINING_MIP_LEVELS, but really old Mali drivers have problems with those.124imageBarrier.subresourceRange.baseArrayLayer = 0;125imageBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;126imageBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;127128*imageLayout = newImageLayout;129}130131void VulkanBarrierBatch::TransitionDepthStencilImageAuto(132VkImage image, VkImageLayout *imageLayout, VkImageLayout newImageLayout, int baseMip, int numMipLevels, int numLayers) {133_dbg_assert_(image != VK_NULL_HANDLE);134135VkAccessFlags srcAccessMask = 0;136VkAccessFlags dstAccessMask = 0;137switch (*imageLayout) {138case VK_IMAGE_LAYOUT_UNDEFINED:139srcAccessMask = 0;140srcStageMask_ |= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;141break;142case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:143srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;144srcStageMask_ |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;145break;146case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:147// We only texture from images in the fragment shader, so can do this simply.148srcAccessMask = VK_ACCESS_SHADER_READ_BIT;149srcStageMask_ |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;150break;151case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:152srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;153srcStageMask_ |= VK_PIPELINE_STAGE_TRANSFER_BIT;154break;155case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:156srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;157srcStageMask_ |= VK_PIPELINE_STAGE_TRANSFER_BIT;158break;159default:160_assert_msg_(false, "Unexpected oldLayout: %s", VulkanImageLayoutToString(*imageLayout));161break;162}163164switch (newImageLayout) {165case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:166dstAccessMask = VK_ACCESS_SHADER_READ_BIT;167dstStageMask_ |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;168break;169case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:170dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;171dstStageMask_ |= VK_PIPELINE_STAGE_TRANSFER_BIT;172break;173case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:174dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;175dstStageMask_ |= VK_PIPELINE_STAGE_TRANSFER_BIT;176break;177case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:178dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;179dstStageMask_ |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;180break;181default:182_assert_msg_(false, "Unexpected newLayout: %s", VulkanImageLayoutToString(newImageLayout));183break;184}185186VkImageMemoryBarrier &imageBarrier = imageBarriers_.push_uninitialized();187imageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;188imageBarrier.pNext = nullptr;189imageBarrier.srcAccessMask = srcAccessMask;190imageBarrier.dstAccessMask = dstAccessMask;191imageBarrier.oldLayout = *imageLayout;192imageBarrier.newLayout = newImageLayout;193imageBarrier.image = image;194imageBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;195imageBarrier.subresourceRange.baseMipLevel = baseMip;196imageBarrier.subresourceRange.levelCount = numMipLevels;197imageBarrier.subresourceRange.layerCount = numLayers; // NOTE: We could usually use VK_REMAINING_ARRAY_LAYERS/VK_REMAINING_MIP_LEVELS, but really old Mali drivers have problems with those.198imageBarrier.subresourceRange.baseArrayLayer = 0;199imageBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;200imageBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;201202*imageLayout = newImageLayout;203}204205void VulkanBarrierBatch::TransitionColorImageAuto(VKRImage *image, VkImageLayout newImageLayout) {206TransitionColorImageAuto(image->image, &image->layout, newImageLayout, 0, 1, image->numLayers);207}208209void VulkanBarrierBatch::TransitionDepthStencilImageAuto(VKRImage *image, VkImageLayout newImageLayout) {210TransitionDepthStencilImageAuto(image->image, &image->layout, newImageLayout, 0, 1, image->numLayers);211}212213214