summaryrefslogtreecommitdiffstats
path: root/tools/gfx/vulkan/render-vk.cpp
diff options
context:
space:
mode:
authorKai Yao <kyao@nvidia.com>2021-09-30 20:25:34 -0700
committerGitHub <noreply@github.com>2021-09-30 20:25:34 -0700
commit6c6200f547c7387598743b23bb3c8f0d375d9494 (patch)
treebcc7dacc0975fb383d1535ad2424083c2cd5cb0f /tools/gfx/vulkan/render-vk.cpp
parent627fc976bac5c2381dbace9c7925cb6a68b8de12 (diff)
VK Resource Barrier (#1955)
* Resource barrier API and VK implementation * Stub implementations * Handle VK Acceleration Structure flag * Add a couple more cases to pipeline barrier stages
Diffstat (limited to 'tools/gfx/vulkan/render-vk.cpp')
-rw-r--r--tools/gfx/vulkan/render-vk.cpp154
1 files changed, 154 insertions, 0 deletions
diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp
index 70eb8de03..186c7eb40 100644
--- a/tools/gfx/vulkan/render-vk.cpp
+++ b/tools/gfx/vulkan/render-vk.cpp
@@ -3944,6 +3944,118 @@ public:
, public RefObject
{
public:
+ static VkImageLayout translateImageLayout(ResourceState state)
+ {
+ switch (state)
+ {
+ case ResourceState::Undefined:
+ return VK_IMAGE_LAYOUT_UNDEFINED;
+ case ResourceState::PreInitialized:
+ return VK_IMAGE_LAYOUT_PREINITIALIZED;
+ case ResourceState::UnorderedAccess:
+ return VK_IMAGE_LAYOUT_GENERAL;
+ case ResourceState::RenderTarget:
+ return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ case ResourceState::DepthRead:
+ return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
+ case ResourceState::DepthWrite:
+ return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+ case ResourceState::ShaderResource:
+ return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+ case ResourceState::ResolveDestination:
+ case ResourceState::CopyDestination:
+ return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ case ResourceState::ResolveSource:
+ case ResourceState::CopySource:
+ return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+ case ResourceState::Present:
+ return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+ default:
+ assert(!"Unsupported");
+ return VK_IMAGE_LAYOUT_UNDEFINED;
+ }
+ }
+
+ static VkAccessFlagBits calcAccessFlags(ResourceState state)
+ {
+ switch (state)
+ {
+ case ResourceState::Undefined:
+ case ResourceState::Present:
+ case ResourceState::PreInitialized:
+ return VkAccessFlagBits(0);
+ case ResourceState::VertexBuffer:
+ return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
+ case ResourceState::ConstantBuffer:
+ return VK_ACCESS_UNIFORM_READ_BIT;
+ case ResourceState::IndexBuffer:
+ return VK_ACCESS_INDEX_READ_BIT;
+ case ResourceState::RenderTarget:
+ return VkAccessFlagBits(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT);
+ case ResourceState::ShaderResource:
+ return VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
+ case ResourceState::UnorderedAccess:
+ return VkAccessFlagBits(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);
+ case ResourceState::DepthRead:
+ return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
+ case ResourceState::DepthWrite:
+ return VkAccessFlagBits(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT);
+ case ResourceState::IndirectArgument:
+ return VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
+ case ResourceState::ResolveDestination:
+ case ResourceState::CopyDestination:
+ return VK_ACCESS_TRANSFER_WRITE_BIT;
+ case ResourceState::ResolveSource:
+ case ResourceState::CopySource:
+ return VK_ACCESS_TRANSFER_READ_BIT;
+ case ResourceState::AccelerationStructure:
+ return VkAccessFlagBits(VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR);
+ default:
+ assert(!"Unsupported");
+ return VkAccessFlagBits(0);
+ }
+ }
+
+ static VkPipelineStageFlagBits calcPipelineStageFlags(ResourceState state, bool src)
+ {
+ switch (state)
+ {
+ case ResourceState::Undefined:
+ case ResourceState::PreInitialized:
+ assert(src);
+ return VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+ case ResourceState::IndexBuffer:
+ return VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
+ case ResourceState::ConstantBuffer:
+ case ResourceState::UnorderedAccess:
+ return VkPipelineStageFlagBits(VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
+ VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
+ VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT |
+ VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT |
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
+ VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
+ case ResourceState::ShaderResource:
+ return VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ case ResourceState::RenderTarget:
+ return VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ case ResourceState::DepthRead:
+ case ResourceState::DepthWrite:
+ return VkPipelineStageFlagBits(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
+ case ResourceState::IndirectArgument:
+ return VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
+ case ResourceState::CopySource:
+ case ResourceState::CopyDestination:
+ case ResourceState::ResolveSource:
+ case ResourceState::ResolveDestination:
+ return VK_PIPELINE_STAGE_TRANSFER_BIT;
+ case ResourceState::Present:
+ return src ? VkPipelineStageFlagBits(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+ default:
+ assert(!"Unsupported");
+ return VkPipelineStageFlagBits(0);
+ }
+ }
+ public:
CommandBufferImpl* m_commandBuffer;
public:
virtual SLANG_NO_THROW void SLANG_MCALL copyBuffer(
@@ -3984,6 +4096,48 @@ public:
size,
data);
}
+ virtual SLANG_NO_THROW void SLANG_MCALL textureBarrier(ITextureResource* texture, ResourceState src, ResourceState dst)
+ {
+ auto image = static_cast<TextureResourceImpl*>(texture);
+ auto desc = image->getDesc();
+
+ VkImageMemoryBarrier barrier = {};
+ barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ barrier.image = image->m_image;
+ barrier.oldLayout = translateImageLayout(src);
+ barrier.newLayout = translateImageLayout(dst);
+ barrier.subresourceRange.aspectMask;
+ barrier.subresourceRange.baseArrayLayer = 0;
+ barrier.subresourceRange.baseMipLevel = 0;
+ barrier.subresourceRange.layerCount = desc->arraySize;
+ barrier.subresourceRange.levelCount = desc->numMipLevels;
+ barrier.srcAccessMask = calcAccessFlags(src);
+ barrier.dstAccessMask = calcAccessFlags(dst);
+
+ VkPipelineStageFlagBits srcStage = calcPipelineStageFlags(src, true);
+ VkPipelineStageFlagBits dstStage = calcPipelineStageFlags(dst, false);
+
+ auto& vkApi = m_commandBuffer->m_renderer->m_api;
+ vkApi.vkCmdPipelineBarrier(m_commandBuffer->m_commandBuffer, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier);
+ }
+ virtual SLANG_NO_THROW void SLANG_MCALL bufferBarrier(IBufferResource* buffer, ResourceState src, ResourceState dst)
+ {
+ auto bufferImpl = static_cast<BufferResourceImpl*>(buffer);
+
+ VkBufferMemoryBarrier barrier = {};
+ barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
+ barrier.srcAccessMask = calcAccessFlags(src);
+ barrier.dstAccessMask = calcAccessFlags(dst);
+ barrier.buffer = bufferImpl->m_buffer.m_buffer;
+ barrier.offset = 0;
+ barrier.size = buffer->getDesc()->sizeInBytes;
+
+ VkPipelineStageFlagBits srcStage = calcPipelineStageFlags(src, true);
+ VkPipelineStageFlagBits dstStage = calcPipelineStageFlags(dst, false);
+
+ auto& vkApi = m_commandBuffer->m_renderer->m_api;
+ vkApi.vkCmdPipelineBarrier(m_commandBuffer->m_commandBuffer, srcStage, dstStage, 0, 0, nullptr, 1, &barrier, 0, nullptr);
+ }
virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override
{
// Insert memory barrier to ensure transfers are visible to the GPU.