145 lines
6.5 KiB
C++
145 lines
6.5 KiB
C++
#include <tuple>
|
|
#include "vkn/vulkan_api_help.h"
|
|
namespace vkn {
|
|
VkImageLayout GetVkLayout(ResourceState layout) {
|
|
switch (layout) {
|
|
case ResourceState::UNDEFINED:
|
|
return VK_IMAGE_LAYOUT_UNDEFINED;
|
|
case ResourceState::READ_WRITE:
|
|
return VK_IMAGE_LAYOUT_GENERAL;
|
|
case ResourceState::READ_ONLY:
|
|
return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
|
case ResourceState::TRANSFER_SRC:
|
|
return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
|
case ResourceState::TRANSFER_DST:
|
|
return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
|
case ResourceState::DEPTH_ATTACHMENT:
|
|
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
case ResourceState::DEPTH_SAMPLER:
|
|
return VK_IMAGE_LAYOUT_GENERAL;
|
|
case ResourceState::PRESENT:
|
|
return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
|
// Filament sometimes samples from one miplevel while writing to another level in the
|
|
// same texture (e.g. bloom does this). Moreover we'd like to avoid lots of expensive
|
|
// layout transitions. So, keep it simple and use GENERAL for all color-attachable
|
|
// textures.
|
|
case ResourceState::COLOR_ATTACHMENT:
|
|
return VK_IMAGE_LAYOUT_GENERAL;
|
|
case ResourceState::COLOR_ATTACHMENT_RESOLVE:
|
|
return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
}
|
|
}
|
|
VkImageMemoryBarrier GetVkTextureTransition(VkPipelineStageFlags& mSrcStage, VkPipelineStageFlags mDstStage, const TextureBarrier& barrier) {
|
|
VkAccessFlags srcAccessMask, dstAccessMask;
|
|
VkPipelineStageFlags srcStage, dstStage;
|
|
|
|
switch (barrier.mSrcState) {
|
|
case ResourceState::UNDEFINED:
|
|
srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
|
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
|
break;
|
|
case ResourceState::COLOR_ATTACHMENT:
|
|
srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT |
|
|
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
|
|
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
|
srcStage = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
|
break;
|
|
case ResourceState::READ_WRITE:
|
|
srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
|
|
srcStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
|
break;
|
|
case ResourceState::READ_ONLY:
|
|
srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
|
srcStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
|
break;
|
|
case ResourceState::TRANSFER_SRC:
|
|
srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
|
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
|
break;
|
|
case ResourceState::TRANSFER_DST:
|
|
srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
|
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
|
break;
|
|
case ResourceState::DEPTH_ATTACHMENT:
|
|
srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
|
srcStage = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
|
break;
|
|
case ResourceState::DEPTH_SAMPLER:
|
|
srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
|
srcStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
|
break;
|
|
case ResourceState::COLOR_ATTACHMENT_RESOLVE:
|
|
srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
|
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
|
break;
|
|
case ResourceState::PRESENT:
|
|
srcAccessMask = VK_ACCESS_NONE;
|
|
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
|
break;
|
|
}
|
|
|
|
switch (barrier.mDstState) {
|
|
case ResourceState::COLOR_ATTACHMENT:
|
|
dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT
|
|
| VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
|
|
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
|
dstStage = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
|
|
| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
|
break;
|
|
case ResourceState::READ_WRITE:
|
|
dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
|
|
dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
|
break;
|
|
case ResourceState::READ_ONLY:
|
|
dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
|
dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
|
|
break;
|
|
case ResourceState::TRANSFER_SRC:
|
|
dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
|
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
|
break;
|
|
case ResourceState::TRANSFER_DST:
|
|
dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
|
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
|
break;
|
|
case ResourceState::DEPTH_ATTACHMENT:
|
|
dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
|
|
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
|
dstStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
|
break;
|
|
case ResourceState::DEPTH_SAMPLER:
|
|
dstAccessMask =
|
|
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
|
dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
|
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
|
break;
|
|
case ResourceState::PRESENT:
|
|
case ResourceState::COLOR_ATTACHMENT_RESOLVE:
|
|
case ResourceState::UNDEFINED:
|
|
dstAccessMask = 0;
|
|
dstStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
|
break;
|
|
}
|
|
mSrcStage |= srcStage;
|
|
mDstStage |= dstStage;
|
|
VkImageSubresourceRange subresources{
|
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
.baseMipLevel = 0,
|
|
.levelCount = 1,
|
|
.baseArrayLayer = 0,
|
|
.layerCount = 1,
|
|
};
|
|
return VkImageMemoryBarrier{
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
.srcAccessMask = srcAccessMask,
|
|
.dstAccessMask = dstAccessMask,
|
|
.oldLayout = GetVkLayout(barrier.mSrcState),
|
|
.newLayout = GetVkLayout(barrier.mDstState),
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
.image = (VkImage)barrier.mTexture.image,
|
|
.subresourceRange = subresources
|
|
};
|
|
}
|
|
} |