mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-19 18:36:53 +02:00
gpu: bound overlapping image copies by both native backings
This commit is contained in:
@@ -353,8 +353,12 @@ void Image::CopyImage(Image& source) {
|
||||
std::vector<vk::ImageCopy> copies;
|
||||
copies.reserve(levels);
|
||||
for (uint32_t level = 0; level < levels; level++) {
|
||||
const auto width = std::max(source.backing.extent.width >> level, 1u);
|
||||
const auto height = std::max(source.backing.extent.height >> level, 1u);
|
||||
// Overlapping cache images can differ in size; copying the source extent into a smaller
|
||||
// destination writes out of bounds and loses the device.
|
||||
const auto width = std::min(std::max(source.backing.extent.width >> level, 1u),
|
||||
std::max(backing.extent.width >> level, 1u));
|
||||
const auto height = std::min(std::max(source.backing.extent.height >> level, 1u),
|
||||
std::max(backing.extent.height >> level, 1u));
|
||||
const auto depth = std::max(base_depth >> level, 1u);
|
||||
const auto [source_layers, destination_layers] = SanitizeCopyLayers(source, *this, depth);
|
||||
vk::ImageCopy copy {};
|
||||
|
||||
@@ -6709,6 +6709,51 @@ public:
|
||||
"Image::CopyImage did not retain pinned "
|
||||
"source/destination states");
|
||||
|
||||
auto wide_volume_info = native_volume_info;
|
||||
wide_volume_info.extent = {85, 5, 5};
|
||||
wide_volume_info.pitch = 85;
|
||||
auto narrow_volume_info = wide_volume_info;
|
||||
narrow_volume_info.extent.width = 20;
|
||||
narrow_volume_info.pitch = 20;
|
||||
Libs::Graphics::Image wide_volume(m_runtime_context, scheduler,
|
||||
wide_volume_info);
|
||||
Libs::Graphics::Image narrow_volume(m_runtime_context, scheduler,
|
||||
narrow_volume_info);
|
||||
std::vector<uint32_t> volume_source_words(85 * 5 * 5);
|
||||
for (uint32_t i = 0; i < volume_source_words.size(); ++i)
|
||||
volume_source_words[i] = i + 1;
|
||||
auto volume_upload = CreateHostBuffer(
|
||||
name, volume_source_words.size() * sizeof(uint32_t),
|
||||
vk::BufferUsageFlagBits::eTransferSrc, volume_source_words);
|
||||
auto shrinking_readback =
|
||||
CreateHostBuffer(name, 20 * 5 * 5 * sizeof(uint32_t),
|
||||
vk::BufferUsageFlagBits::eTransferDst, {});
|
||||
vk::BufferImageCopy volume_region{};
|
||||
volume_region.imageSubresource = {vk::ImageAspectFlagBits::eColor, 0, 0,
|
||||
1};
|
||||
volume_region.imageExtent = wide_volume_info.extent;
|
||||
wide_volume.Upload(std::span{&volume_region, 1}, volume_upload.buffer, 0,
|
||||
volume_upload.size);
|
||||
narrow_volume.CopyImage(wide_volume);
|
||||
volume_region.imageExtent = narrow_volume_info.extent;
|
||||
narrow_volume.Download(std::span{&volume_region, 1},
|
||||
shrinking_readback.buffer, 0,
|
||||
shrinking_readback.size);
|
||||
HostReadBarrier(shrinking_readback.buffer, shrinking_readback.size,
|
||||
vk::PipelineStageFlagBits::eTransfer,
|
||||
vk::AccessFlagBits::eTransferWrite);
|
||||
scheduler.Finish();
|
||||
const auto volume_copied_words =
|
||||
ReadBuffer(name, shrinking_readback, 20 * 5 * 5);
|
||||
for (uint32_t row = 0; row < 5 * 5; ++row)
|
||||
Require(name, "shrinking volume copy contents",
|
||||
std::equal(volume_copied_words.begin() + row * 20,
|
||||
volume_copied_words.begin() + (row + 1) * 20,
|
||||
volume_source_words.begin() + row * 85),
|
||||
"85x5x5 to 20x5x5 copy lost a row or depth slice");
|
||||
DestroyBuffer(&shrinking_readback);
|
||||
DestroyBuffer(&volume_upload);
|
||||
|
||||
ImageInfo resolve_source_info{};
|
||||
resolve_source_info.pixel_format = vk::Format::eR8G8B8A8Unorm;
|
||||
resolve_source_info.guest_format = Prospero::BufferFormat::k8_8_8_8UNorm;
|
||||
|
||||
Reference in New Issue
Block a user