|
|
|
@ -536,6 +536,7 @@ struct RangedBarrierRange { |
|
|
|
}; |
|
|
|
void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage image, |
|
|
|
VkImageAspectFlags aspect_mask, bool is_initialized, |
|
|
|
bool use_unified_layouts, |
|
|
|
std::span<const VkBufferImageCopy> copies) { |
|
|
|
static constexpr VkAccessFlags WRITE_ACCESS_FLAGS = |
|
|
|
VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | |
|
|
|
@ -550,6 +551,8 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im |
|
|
|
range.AddLayers(region.imageSubresource); |
|
|
|
} |
|
|
|
const VkImageSubresourceRange subresource_range = range.SubresourceRange(aspect_mask); |
|
|
|
const VkImageLayout transfer_dst_layout = |
|
|
|
use_unified_layouts ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; |
|
|
|
|
|
|
|
const VkImageMemoryBarrier read_barrier{ |
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
|
|
|
@ -557,7 +560,7 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im |
|
|
|
.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, |
|
|
|
.newLayout = transfer_dst_layout, |
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
.image = image, |
|
|
|
@ -569,7 +572,7 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im |
|
|
|
.pNext = nullptr, |
|
|
|
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, |
|
|
|
.dstAccessMask = WRITE_ACCESS_FLAGS | READ_ACCESS_FLAGS, |
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, |
|
|
|
.oldLayout = transfer_dst_layout, |
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
@ -581,7 +584,7 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im |
|
|
|
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); |
|
|
|
cmdbuf.CopyBufferToImage(src_buffer, image, transfer_dst_layout, copies); |
|
|
|
// TODO: Move this to another API
|
|
|
|
cmdbuf.PipelineBarrier( |
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT, |
|
|
|
@ -703,7 +706,7 @@ void TryTransformSwizzleIfNeeded(PixelFormat format, std::array<SwizzleSource, 4 |
|
|
|
|
|
|
|
void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const ImageInfo& info, |
|
|
|
VkImageAspectFlags aspect_mask, const Settings::ResolutionScalingInfo& resolution, |
|
|
|
bool up_scaling = true) { |
|
|
|
bool use_unified_layouts, bool up_scaling = true) { |
|
|
|
const bool is_2d = info.type == ImageType::e2D; |
|
|
|
const auto resources = info.resources; |
|
|
|
const VkExtent2D extent{ |
|
|
|
@ -777,6 +780,10 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const |
|
|
|
.baseArrayLayer = 0, |
|
|
|
.layerCount = VK_REMAINING_ARRAY_LAYERS, |
|
|
|
}; |
|
|
|
const VkImageLayout transfer_src_layout = |
|
|
|
use_unified_layouts ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; |
|
|
|
const VkImageLayout transfer_dst_layout = |
|
|
|
use_unified_layouts ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; |
|
|
|
const std::array read_barriers{ |
|
|
|
VkImageMemoryBarrier{ |
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
|
|
|
@ -784,7 +791,7 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const |
|
|
|
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, |
|
|
|
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT, |
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
|
|
|
.newLayout = transfer_src_layout, |
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
.image = src_image, |
|
|
|
@ -798,7 +805,7 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const |
|
|
|
VK_ACCESS_TRANSFER_WRITE_BIT, |
|
|
|
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, |
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, // Discard contents
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, |
|
|
|
.newLayout = transfer_dst_layout, |
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
.image = dst_image, |
|
|
|
@ -812,7 +819,7 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const |
|
|
|
.srcAccessMask = 0, |
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | |
|
|
|
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
|
|
|
.oldLayout = transfer_src_layout, |
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
@ -825,7 +832,7 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const |
|
|
|
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, |
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | |
|
|
|
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, |
|
|
|
.oldLayout = transfer_dst_layout, |
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
@ -843,8 +850,8 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const |
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT; |
|
|
|
cmdbuf.PipelineBarrier(src_stages, VK_PIPELINE_STAGE_TRANSFER_BIT, |
|
|
|
0, nullptr, nullptr, read_barriers); |
|
|
|
cmdbuf.BlitImage(src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_image, |
|
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, regions, vk_filter); |
|
|
|
cmdbuf.BlitImage(src_image, transfer_src_layout, dst_image, |
|
|
|
transfer_dst_layout, regions, vk_filter); |
|
|
|
// After transfer, images may be used in graphics, compute, or as attachments
|
|
|
|
const VkPipelineStageFlags dst_stages = |
|
|
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | |
|
|
|
@ -1743,9 +1750,11 @@ void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset, |
|
|
|
const VkImage temp_vk_image = *temp_wrapper->original_image; |
|
|
|
const VkImageAspectFlags vk_aspect_mask = temp_wrapper->aspect_mask; |
|
|
|
|
|
|
|
scheduler->Record([src_buffer, temp_vk_image, vk_aspect_mask, vk_copies, |
|
|
|
const bool use_unified_layouts = runtime->device.IsKhrUnifiedImageLayoutsSupported(); |
|
|
|
scheduler->Record([src_buffer, temp_vk_image, vk_aspect_mask, vk_copies, use_unified_layouts, |
|
|
|
keep = temp_wrapper](vk::CommandBuffer cmdbuf) { |
|
|
|
CopyBufferToImage(cmdbuf, src_buffer, temp_vk_image, vk_aspect_mask, false, VideoCommon::FixSmallVectorADL(vk_copies)); |
|
|
|
CopyBufferToImage(cmdbuf, src_buffer, temp_vk_image, vk_aspect_mask, false, |
|
|
|
use_unified_layouts, VideoCommon::FixSmallVectorADL(vk_copies)); |
|
|
|
}); |
|
|
|
|
|
|
|
// Use MSAACopyPass to convert from non-MSAA to MSAA
|
|
|
|
@ -1782,9 +1791,11 @@ void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset, |
|
|
|
const VkImageAspectFlags vk_aspect_mask = aspect_mask; |
|
|
|
const bool was_initialized = std::exchange(initialized, true); |
|
|
|
|
|
|
|
const bool use_unified_layouts = runtime->device.IsKhrUnifiedImageLayoutsSupported(); |
|
|
|
scheduler->Record([src_buffer, vk_image, vk_aspect_mask, was_initialized, |
|
|
|
vk_copies](vk::CommandBuffer cmdbuf) { |
|
|
|
CopyBufferToImage(cmdbuf, src_buffer, vk_image, vk_aspect_mask, was_initialized, VideoCommon::FixSmallVectorADL(vk_copies)); |
|
|
|
vk_copies, use_unified_layouts](vk::CommandBuffer cmdbuf) { |
|
|
|
CopyBufferToImage(cmdbuf, src_buffer, vk_image, vk_aspect_mask, was_initialized, |
|
|
|
use_unified_layouts, VideoCommon::FixSmallVectorADL(vk_copies)); |
|
|
|
}); |
|
|
|
|
|
|
|
if (is_rescaled) { |
|
|
|
@ -2071,7 +2082,8 @@ bool Image::ScaleUp(bool ignore) { |
|
|
|
if (NeedsScaleHelper()) { |
|
|
|
return BlitScaleHelper(true); |
|
|
|
} else { |
|
|
|
BlitScale(*scheduler, *original_image, *scaled_image, info, aspect_mask, resolution); |
|
|
|
BlitScale(*scheduler, *original_image, *scaled_image, info, aspect_mask, resolution, |
|
|
|
runtime->device.IsKhrUnifiedImageLayoutsSupported()); |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
@ -2096,7 +2108,8 @@ bool Image::ScaleDown(bool ignore) { |
|
|
|
if (NeedsScaleHelper()) { |
|
|
|
return BlitScaleHelper(false); |
|
|
|
} else { |
|
|
|
BlitScale(*scheduler, *scaled_image, *original_image, info, aspect_mask, resolution, false); |
|
|
|
BlitScale(*scheduler, *scaled_image, *original_image, info, aspect_mask, resolution, |
|
|
|
runtime->device.IsKhrUnifiedImageLayoutsSupported(), false); |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
|