|
|
|
@ -508,84 +508,58 @@ 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 = subresource_range, |
|
|
|
.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, |
|
|
|
}, |
|
|
|
}; |
|
|
|
|
|
|
|
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 = subresource_range, |
|
|
|
.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, |
|
|
|
}, |
|
|
|
}; |
|
|
|
|
|
|
|
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, |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_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_LATE_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, |
|
|
|
0, nullptr, nullptr, write_barrier); |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, |
|
|
|
write_barrier); |
|
|
|
} |
|
|
|
|
|
|
|
[[nodiscard]] VkImageBlit MakeImageBlit(const Region2D& dst_region, const Region2D& src_region, |
|
|
|
@ -678,7 +652,29 @@ 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) { |
|
|
|
@ -1480,18 +1476,12 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src, |
|
|
|
.subresourceRange = dst_range.SubresourceRange(aspect_mask), |
|
|
|
}, |
|
|
|
}; |
|
|
|
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.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, |
|
|
|
0, {}, {}, pre_barriers); |
|
|
|
cmdbuf.CopyImage(src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_image, |
|
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VideoCommon::FixSmallVectorADL(vk_copies)); |
|
|
|
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); |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, |
|
|
|
0, {}, {}, post_barriers); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
@ -2403,7 +2393,7 @@ void TextureCacheRuntime::TransitionImageLayout(Image& image) { |
|
|
|
}; |
|
|
|
scheduler.RequestOutsideRenderPassOperationContext(); |
|
|
|
scheduler.Record([barrier](vk::CommandBuffer cmdbuf) { |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, |
|
|
|
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, barrier); |
|
|
|
}); |
|
|
|
} |
|
|
|
|