@ -508,58 +508,84 @@ TransformBufferCopies(std::span<const VideoCommon::BufferCopy> copies, size_t bu
return value ;
}
}
struct RangedBarrierRange {
u32 min_mip = std : : numeric_limits < u32 > : : max ( ) ;
u32 max_mip = std : : numeric_limits < u32 > : : min ( ) ;
u32 min_layer = std : : numeric_limits < u32 > : : max ( ) ;
u32 max_layer = std : : numeric_limits < u32 > : : min ( ) ;
void AddLayers ( const VkImageSubresourceLayers & layers ) {
min_mip = std : : min ( min_mip , layers . mipLevel ) ;
max_mip = std : : max ( max_mip , layers . mipLevel + 1 ) ;
min_layer = std : : min ( min_layer , layers . baseArrayLayer ) ;
max_layer = std : : max ( max_layer , layers . baseArrayLayer + layers . layerCount ) ;
}
VkImageSubresourceRange SubresourceRange ( VkImageAspectFlags aspect_mask ) const noexcept {
return VkImageSubresourceRange {
. aspectMask = aspect_mask ,
. baseMipLevel = min_mip ,
. levelCount = max_mip - min_mip ,
. baseArrayLayer = min_layer ,
. layerCount = max_layer - min_layer ,
} ;
}
} ;
void CopyBufferToImage ( vk : : CommandBuffer cmdbuf , VkBuffer src_buffer , VkImage image ,
VkImageAspectFlags aspect_mask , bool is_initialized ,
std : : span < const VkBufferImageCopy > copies ) {
static constexpr VkAccessFlags WRITE_ACCESS_FLAGS =
VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT ;
VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT ;
static constexpr VkAccessFlags READ_ACCESS_FLAGS = VK_ACCESS_SHADER_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT ;
// Compute exact mip/layer range being written to
RangedBarrierRange range ;
for ( const auto & region : copies ) {
range . AddLayers ( region . imageSubresource ) ;
}
const VkImageSubresourceRange subresource_range = range . SubresourceRange ( aspect_mask ) ;
const VkImageMemoryBarrier read_barrier {
. sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER ,
. pNext = nullptr ,
. srcAccessMask = WRITE_ACCESS_FLAGS ,
. dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT ,
. oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED ,
. newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ,
. srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
. dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
. image = image ,
. subresourceRange {
. aspectMask = aspect_mask ,
. baseMipLevel = 0 ,
. levelCount = VK_REMAINING_MIP_LEVELS ,
. baseArrayLayer = 0 ,
. layerCount = VK_REMAINING_ARRAY_LAYERS ,
} ,
. sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER ,
. pNext = nullptr ,
. srcAccessMask = WRITE_ACCESS_FLAGS ,
. dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT ,
. oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED ,
. newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ,
. srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
. dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
. image = image ,
. subresourceRange = subresource_range ,
} ;
const VkImageMemoryBarrier write_barrier {
. sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER ,
. pNext = nullptr ,
. srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT ,
. dstAccessMask = WRITE_ACCESS_FLAGS | READ_ACCESS_FLAGS ,
. oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ,
. newLayout = VK_IMAGE_LAYOUT_GENERAL ,
. srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
. dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
. image = image ,
. subresourceRange {
. aspectMask = aspect_mask ,
. baseMipLevel = 0 ,
. levelCount = VK_REMAINING_MIP_LEVELS ,
. baseArrayLayer = 0 ,
. layerCount = VK_REMAINING_ARRAY_LAYERS ,
} ,
. sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER ,
. pNext = nullptr ,
. srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT ,
. dstAccessMask = WRITE_ACCESS_FLAGS | READ_ACCESS_FLAGS ,
. oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ,
. newLayout = VK_IMAGE_LAYOUT_GENERAL ,
. srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
. dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
. image = image ,
. subresourceRange = subresource_range ,
} ;
cmdbuf . PipelineBarrier ( VK_PIPELINE_STAGE_ALL_COMMANDS_BIT , VK_PIPELINE_STAGE_TRANSFER_BIT , 0 ,
cmdbuf . PipelineBarrier ( VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT , VK_PIPELINE_STAGE_TRANSFER_BIT , 0 ,
read_barrier ) ;
cmdbuf . CopyBufferToImage ( src_buffer , image , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL , copies ) ;
// TODO: Move this to another API
cmdbuf . PipelineBarrier ( VK_PIPELINE_STAGE_TRANSFER_BIT , VK_PIPELINE_STAGE_ALL_COMMANDS_BIT , 0 ,
write_barrier ) ;
cmdbuf . PipelineBarrier (
VK_PIPELINE_STAGE_TRANSFER_BIT ,
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT ,
0 , nullptr , nullptr , write_barrier ) ;
}
[[nodiscard]] VkImageBlit MakeImageBlit ( const Region2D & dst_region , const Region2D & src_region ,
@ -652,29 +678,7 @@ void TryTransformSwizzleIfNeeded(PixelFormat format, std::array<SwizzleSource, 4
}
}
struct RangedBarrierRange {
u32 min_mip = std : : numeric_limits < u32 > : : max ( ) ;
u32 max_mip = std : : numeric_limits < u32 > : : min ( ) ;
u32 min_layer = std : : numeric_limits < u32 > : : max ( ) ;
u32 max_layer = std : : numeric_limits < u32 > : : min ( ) ;
void AddLayers ( const VkImageSubresourceLayers & layers ) {
min_mip = std : : min ( min_mip , layers . mipLevel ) ;
max_mip = std : : max ( max_mip , layers . mipLevel + 1 ) ;
min_layer = std : : min ( min_layer , layers . baseArrayLayer ) ;
max_layer = std : : max ( max_layer , layers . baseArrayLayer + layers . layerCount ) ;
}
VkImageSubresourceRange SubresourceRange ( VkImageAspectFlags aspect_mask ) const noexcept {
return VkImageSubresourceRange {
. aspectMask = aspect_mask ,
. baseMipLevel = min_mip ,
. levelCount = max_mip - min_mip ,
. baseArrayLayer = min_layer ,
. layerCount = max_layer - min_layer ,
} ;
}
} ;
[[nodiscard]] VkFormat Format ( Shader : : ImageFormat format ) {
switch ( format ) {
@ -1458,12 +1462,18 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
. subresourceRange = dst_range . SubresourceRange ( aspect_mask ) ,
} ,
} ;
cmdbuf . PipelineBarrier ( VK_PIPELINE_STAGE_ALL_COMMANDS_BIT , VK_PIPELINE_STAGE_TRANSFER_BIT ,
0 , { } , { } , pre_barriers ) ;
cmdbuf . PipelineBarrier (
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT ,
VK_PIPELINE_STAGE_TRANSFER_BIT ,
0 , nullptr , nullptr , pre_barriers ) ;
cmdbuf . CopyImage ( src_image , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL , dst_image ,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL , vk_copies ) ;
cmdbuf . PipelineBarrier ( VK_PIPELINE_STAGE_TRANSFER_BIT , VK_PIPELINE_STAGE_ALL_COMMANDS_BIT ,
0 , { } , { } , post_barriers ) ;
cmdbuf . PipelineBarrier (
VK_PIPELINE_STAGE_TRANSFER_BIT ,
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT ,
0 , nullptr , nullptr , post_barriers ) ;
} ) ;
}
@ -2377,7 +2387,7 @@ void TextureCacheRuntime::TransitionImageLayout(Image& image) {
} ;
scheduler . RequestOutsideRenderPassOperationContext ( ) ;
scheduler . Record ( [ barrier ] ( vk : : CommandBuffer cmdbuf ) {
cmdbuf . PipelineBarrier ( VK_PIPELINE_STAGE_ALL_COMMANDS _BIT ,
cmdbuf . PipelineBarrier ( VK_PIPELINE_STAGE_TOP_OF_PIPE _BIT ,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT , 0 , barrier ) ;
} ) ;
}