|
|
|
@ -593,6 +593,82 @@ struct RangedBarrierRange {
|
|
|
|
|
UNREACHABLE_MSG("Invalid image format={}", format);
|
|
|
|
|
return VK_FORMAT_R32_UINT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BlitScale(VKScheduler& scheduler, VkImage src_image, VkImage dst_image,
|
|
|
|
|
boost::container::small_vector<VkImageBlit, 4>&& blit_regions,
|
|
|
|
|
VkImageAspectFlags aspect_mask) {
|
|
|
|
|
scheduler.RequestOutsideRenderPassOperationContext();
|
|
|
|
|
scheduler.Record([dst_image, src_image, aspect_mask,
|
|
|
|
|
regions = std::move(blit_regions)](vk::CommandBuffer cmdbuf) {
|
|
|
|
|
const VkImageSubresourceRange subresource_range{
|
|
|
|
|
.aspectMask = aspect_mask,
|
|
|
|
|
.baseMipLevel = 0,
|
|
|
|
|
.levelCount = VK_REMAINING_MIP_LEVELS,
|
|
|
|
|
.baseArrayLayer = 0,
|
|
|
|
|
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
|
|
|
|
};
|
|
|
|
|
const std::array read_barriers{
|
|
|
|
|
VkImageMemoryBarrier{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
|
|
|
.pNext = nullptr,
|
|
|
|
|
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
|
|
|
|
|
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
|
|
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.image = src_image,
|
|
|
|
|
.subresourceRange = subresource_range,
|
|
|
|
|
},
|
|
|
|
|
VkImageMemoryBarrier{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
|
|
|
.pNext = nullptr,
|
|
|
|
|
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT |
|
|
|
|
|
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
|
|
|
|
|
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,
|
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.image = dst_image,
|
|
|
|
|
.subresourceRange = subresource_range,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
const std::array write_barriers{
|
|
|
|
|
VkImageMemoryBarrier{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
|
|
|
.pNext = nullptr,
|
|
|
|
|
.srcAccessMask = 0,
|
|
|
|
|
.dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT,
|
|
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.image = src_image,
|
|
|
|
|
.subresourceRange = subresource_range,
|
|
|
|
|
},
|
|
|
|
|
VkImageMemoryBarrier{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
|
|
|
.pNext = nullptr,
|
|
|
|
|
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
|
|
|
.dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT,
|
|
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.image = dst_image,
|
|
|
|
|
.subresourceRange = subresource_range,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 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_NEAREST);
|
|
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
|
|
|
|
0, nullptr, nullptr, write_barriers);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} // Anonymous namespace
|
|
|
|
|
|
|
|
|
|
void TextureCacheRuntime::Init() {
|
|
|
|
@ -983,85 +1059,6 @@ void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferIm
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BlitScale(VKScheduler& scheduler, VkImage src_image, VkImage dst_image,
|
|
|
|
|
boost::container::small_vector<VkImageBlit, 4>& blit_regions,
|
|
|
|
|
VkImageAspectFlags aspect_mask) {
|
|
|
|
|
scheduler.RequestOutsideRenderPassOperationContext();
|
|
|
|
|
scheduler.Record([dst_image, src_image, aspect_mask,
|
|
|
|
|
regions = std::move(blit_regions)](vk::CommandBuffer cmdbuf) {
|
|
|
|
|
const std::array read_barriers{
|
|
|
|
|
VkImageMemoryBarrier{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
|
|
|
.pNext = nullptr,
|
|
|
|
|
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT |
|
|
|
|
|
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
|
|
|
|
|
VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
|
|
|
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
|
|
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.image = src_image,
|
|
|
|
|
.subresourceRange{
|
|
|
|
|
.aspectMask = aspect_mask,
|
|
|
|
|
.baseMipLevel = 0,
|
|
|
|
|
.levelCount = VK_REMAINING_MIP_LEVELS,
|
|
|
|
|
.baseArrayLayer = 0,
|
|
|
|
|
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
VkImageMemoryBarrier{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
|
|
|
.pNext = nullptr,
|
|
|
|
|
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT |
|
|
|
|
|
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
|
|
|
|
|
VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
|
|
|
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.image = dst_image,
|
|
|
|
|
.subresourceRange{
|
|
|
|
|
.aspectMask = aspect_mask,
|
|
|
|
|
.baseMipLevel = 0,
|
|
|
|
|
.levelCount = VK_REMAINING_MIP_LEVELS,
|
|
|
|
|
.baseArrayLayer = 0,
|
|
|
|
|
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
VkImageMemoryBarrier write_barrier{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
|
|
|
.pNext = nullptr,
|
|
|
|
|
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT |
|
|
|
|
|
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
|
|
|
|
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
|
|
|
|
|
VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.image = dst_image,
|
|
|
|
|
.subresourceRange{
|
|
|
|
|
.aspectMask = aspect_mask,
|
|
|
|
|
.baseMipLevel = 0,
|
|
|
|
|
.levelCount = VK_REMAINING_MIP_LEVELS,
|
|
|
|
|
.baseArrayLayer = 0,
|
|
|
|
|
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
|
0, nullptr, nullptr, read_barriers);
|
|
|
|
|
const VkFilter vk_filter = VK_FILTER_NEAREST;
|
|
|
|
|
cmdbuf.BlitImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image,
|
|
|
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, regions, vk_filter);
|
|
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
|
|
|
|
0, write_barrier);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Image::ScaleUp(bool save_as_backup) {
|
|
|
|
|
if (True(flags & ImageFlagBits::Rescaled)) {
|
|
|
|
|
return false;
|
|
|
|
@ -1155,7 +1152,7 @@ bool Image::ScaleUp(bool save_as_backup) {
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
BlitScale(*scheduler, *image, *rescaled_image, regions, aspect_mask);
|
|
|
|
|
BlitScale(*scheduler, *image, *rescaled_image, std::move(regions), aspect_mask);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1239,7 +1236,7 @@ bool Image::ScaleDown(bool save_as_backup) {
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
BlitScale(*scheduler, *image, *downscaled_image, regions, aspect_mask);
|
|
|
|
|
BlitScale(*scheduler, *image, *downscaled_image, std::move(regions), aspect_mask);
|
|
|
|
|
if (save_as_backup) {
|
|
|
|
|
backup_image = std::move(image);
|
|
|
|
|
backup_commit = std::move(commit);
|
|
|
|
|