|
|
@ -593,6 +593,82 @@ struct RangedBarrierRange { |
|
|
UNREACHABLE_MSG("Invalid image format={}", format); |
|
|
UNREACHABLE_MSG("Invalid image format={}", format); |
|
|
return VK_FORMAT_R32_UINT; |
|
|
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
|
|
|
} // Anonymous namespace
|
|
|
|
|
|
|
|
|
void TextureCacheRuntime::Init() { |
|
|
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) { |
|
|
bool Image::ScaleUp(bool save_as_backup) { |
|
|
if (True(flags & ImageFlagBits::Rescaled)) { |
|
|
if (True(flags & ImageFlagBits::Rescaled)) { |
|
|
return false; |
|
|
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; |
|
|
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) { |
|
|
if (save_as_backup) { |
|
|
backup_image = std::move(image); |
|
|
backup_image = std::move(image); |
|
|
backup_commit = std::move(commit); |
|
|
backup_commit = std::move(commit); |
|
|
|