mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-27 18:02:16 +00:00
Dump every lsfg stage and require null descriptors
This commit is contained in:
@@ -25,6 +25,17 @@ bool IsBlueFirst(VkFormat format) {
|
|||||||
return format == VK_FORMAT_B8G8R8A8_UNORM || format == VK_FORMAT_B8G8R8A8_SRGB;
|
return format == VK_FORMAT_B8G8R8A8_UNORM || format == VK_FORMAT_B8G8R8A8_SRGB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkDeviceSize BytesPerTexel(VkFormat format) {
|
||||||
|
switch (format) {
|
||||||
|
case VK_FORMAT_R8_UNORM:
|
||||||
|
return 1;
|
||||||
|
case VK_FORMAT_R16G16B16A16_SFLOAT:
|
||||||
|
return 8;
|
||||||
|
default:
|
||||||
|
return COLOR_CHANNELS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WritePortablePixmap(const std::filesystem::path& path, const std::string& magic,
|
void WritePortablePixmap(const std::filesystem::path& path, const std::string& magic,
|
||||||
VkExtent2D extent, std::span<const u8> pixels) {
|
VkExtent2D extent, std::span<const u8> pixels) {
|
||||||
Common::FS::IOFile file{path, Common::FS::FileAccessMode::Write,
|
Common::FS::IOFile file{path, Common::FS::FileAccessMode::Write,
|
||||||
@@ -49,6 +60,16 @@ void WriteGrayscalePgm(const std::filesystem::path& path, VkExtent2D extent,
|
|||||||
WritePortablePixmap(path, "P5", extent, pixels.subspan(0, std::min(expected, pixels.size())));
|
WritePortablePixmap(path, "P5", extent, pixels.subspan(0, std::min(expected, pixels.size())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WriteRaw(const std::filesystem::path& path, std::span<const u8> pixels) {
|
||||||
|
Common::FS::IOFile file{path, Common::FS::FileAccessMode::Write,
|
||||||
|
Common::FS::FileType::BinaryFile};
|
||||||
|
if (!file.IsOpen()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void(file.Write(pixels));
|
||||||
|
void(file.Flush());
|
||||||
|
}
|
||||||
|
|
||||||
void WriteColorPpm(const std::filesystem::path& path, VkExtent2D extent,
|
void WriteColorPpm(const std::filesystem::path& path, VkExtent2D extent,
|
||||||
std::span<const u8> pixels, bool blue_first) {
|
std::span<const u8> pixels, bool blue_first) {
|
||||||
const size_t pixel_count = static_cast<size_t>(extent.width) * extent.height;
|
const size_t pixel_count = static_cast<size_t>(extent.width) * extent.height;
|
||||||
@@ -175,7 +196,7 @@ void FrameGen::Process(const Device& device, Frame* frame, VkFormat format) {
|
|||||||
if (!dump_requested) {
|
if (!dump_requested) {
|
||||||
dumped = false;
|
dumped = false;
|
||||||
} else if (!dumped) {
|
} else if (!dumped) {
|
||||||
DumpDebugImages();
|
DumpDebugImages(count);
|
||||||
dumped = true;
|
dumped = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,46 +210,65 @@ void FrameGen::Rebuild(const Device& device, VkExtent2D extent, VkFormat format)
|
|||||||
frame_count = 0;
|
frame_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameGen::DumpDebugImages() {
|
void FrameGen::DumpDebugImages(u64 count) {
|
||||||
const std::filesystem::path directory =
|
const std::filesystem::path directory =
|
||||||
Common::FS::GetEdenPath(Common::FS::EdenPath::LosslessDir) / "debug";
|
Common::FS::GetEdenPath(Common::FS::EdenPath::LosslessDir) / "debug";
|
||||||
if (!Common::FS::CreateDirs(directory)) {
|
if (!Common::FS::CreateDirs(directory)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto readback = [&](LsfgImage& image, VkDeviceSize size) {
|
const auto dump = [&](const std::string& name, LsfgImage& image) {
|
||||||
vk::Buffer buffer = CreateWrappedBuffer(memory_allocator, size, MemoryUsage::Download);
|
|
||||||
const VkExtent2D extent = image.Extent();
|
const VkExtent2D extent = image.Extent();
|
||||||
|
const VkFormat format = image.Format();
|
||||||
|
const VkDeviceSize texel_size = BytesPerTexel(format);
|
||||||
|
const VkDeviceSize size =
|
||||||
|
static_cast<VkDeviceSize>(extent.width) * extent.height * texel_size;
|
||||||
|
|
||||||
|
vk::Buffer buffer = CreateWrappedBuffer(memory_allocator, size, MemoryUsage::Download);
|
||||||
|
|
||||||
scheduler.RequestOutsideRenderPassOperationContext();
|
scheduler.RequestOutsideRenderPassOperationContext();
|
||||||
scheduler.Record([handle = image.Handle(), dst = *buffer,
|
scheduler.Record(
|
||||||
extent](vk::CommandBuffer cmdbuf) {
|
[handle = image.Handle(), dst = *buffer, extent](vk::CommandBuffer cmdbuf) {
|
||||||
DownloadColorImage(cmdbuf, handle, dst,
|
DownloadColorImage(
|
||||||
VkExtent3D{.width = extent.width,
|
cmdbuf, handle, dst,
|
||||||
.height = extent.height,
|
VkExtent3D{.width = extent.width, .height = extent.height, .depth = 1});
|
||||||
.depth = 1});
|
});
|
||||||
});
|
|
||||||
scheduler.Finish();
|
scheduler.Finish();
|
||||||
|
|
||||||
buffer.Invalidate();
|
buffer.Invalidate();
|
||||||
return buffer;
|
const std::span<u8> mapped = buffer.Mapped();
|
||||||
|
|
||||||
|
if (format == LSFG_FLOW_FORMAT) {
|
||||||
|
WriteGrayscalePgm(directory / (name + ".pgm"), extent, mapped);
|
||||||
|
} else if (texel_size == COLOR_CHANNELS) {
|
||||||
|
WriteColorPpm(directory / (name + ".ppm"), extent, mapped, IsBlueFirst(format));
|
||||||
|
} else {
|
||||||
|
WriteRaw(directory / (name + "_" + std::to_string(extent.width) + "x" +
|
||||||
|
std::to_string(extent.height) + ".f16"),
|
||||||
|
mapped.subspan(0, std::min<size_t>(size, mapped.size())));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
dump("in0", chain->Input(0));
|
||||||
|
dump("in1", chain->Input(1));
|
||||||
|
|
||||||
for (size_t level = 0; level < LSFG_MIP_LEVELS; ++level) {
|
for (size_t level = 0; level < LSFG_MIP_LEVELS; ++level) {
|
||||||
LsfgImage& image = chain->FlowLevel(level);
|
dump("flow_mip" + std::to_string(level), chain->FlowLevel(level));
|
||||||
const VkExtent2D extent = image.Extent();
|
}
|
||||||
const VkDeviceSize size = static_cast<VkDeviceSize>(extent.width) * extent.height;
|
for (size_t index = 0; index < 2; ++index) {
|
||||||
vk::Buffer buffer = readback(image, size);
|
dump("alpha0_" + std::to_string(index), chain->AlphaOutput(0, count, index));
|
||||||
WriteGrayscalePgm(directory / ("flow_mip" + std::to_string(level) + ".pgm"), extent,
|
dump("alpha6_" + std::to_string(index), chain->AlphaOutput(LSFG_MIP_LEVELS - 1, count,
|
||||||
buffer.Mapped());
|
index));
|
||||||
|
}
|
||||||
|
for (size_t level = 0; level < LSFG_BETA_OUTPUTS; ++level) {
|
||||||
|
dump("beta_" + std::to_string(level), chain->BetaOutput(level));
|
||||||
}
|
}
|
||||||
|
|
||||||
LsfgImage& output = chain->Output();
|
dump("gamma0", chain->GammaOutput(0));
|
||||||
const VkExtent2D extent = output.Extent();
|
dump("gamma6", chain->GammaOutput(LSFG_MIP_LEVELS - 1));
|
||||||
const VkDeviceSize size =
|
dump("delta2_out1", chain->DeltaOutput1(LSFG_DELTA_INSTANCES - 1));
|
||||||
static_cast<VkDeviceSize>(extent.width) * extent.height * COLOR_CHANNELS;
|
dump("delta2_out2", chain->DeltaOutput2(LSFG_DELTA_INSTANCES - 1));
|
||||||
vk::Buffer buffer = readback(output, size);
|
dump("generated", chain->Output());
|
||||||
WriteColorPpm(directory / "generated.ppm", extent, buffer.Mapped(), IsBlueFirst(built_format));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void Rebuild(const Device& device, VkExtent2D extent, VkFormat format);
|
void Rebuild(const Device& device, VkExtent2D extent, VkFormat format);
|
||||||
void DumpDebugImages();
|
void DumpDebugImages(u64 count);
|
||||||
|
|
||||||
MemoryAllocator& memory_allocator;
|
MemoryAllocator& memory_allocator;
|
||||||
Scheduler& scheduler;
|
Scheduler& scheduler;
|
||||||
|
|||||||
@@ -43,6 +43,26 @@ public:
|
|||||||
return mipmaps.Output(level);
|
return mipmaps.Output(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] LsfgImage& AlphaOutput(size_t level, u64 frame_count, size_t index) {
|
||||||
|
return alpha[level].Outputs()[frame_count % LSFG_HISTORY_SLOTS][index];
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] LsfgImage& BetaOutput(size_t level) {
|
||||||
|
return beta.Output(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] LsfgImage& GammaOutput(size_t index) {
|
||||||
|
return gamma[index].Output();
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] LsfgImage& DeltaOutput1(size_t index) {
|
||||||
|
return delta[index].Output1();
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] LsfgImage& DeltaOutput2(size_t index) {
|
||||||
|
return delta[index].Output2();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LsfgResources resources;
|
LsfgResources resources;
|
||||||
vk::DescriptorPool descriptor_pool;
|
vk::DescriptorPool descriptor_pool;
|
||||||
|
|||||||
@@ -89,8 +89,8 @@ VkImageMemoryBarrier MakeBarrier(const LsfgImage& image, VkAccessFlags src_acces
|
|||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
LsfgImage::LsfgImage(const Device& device, MemoryAllocator& memory_allocator, VkExtent2D extent_,
|
LsfgImage::LsfgImage(const Device& device, MemoryAllocator& memory_allocator, VkExtent2D extent_,
|
||||||
VkFormat format)
|
VkFormat format_)
|
||||||
: extent{std::max(1u, extent_.width), std::max(1u, extent_.height)} {
|
: extent{std::max(1u, extent_.width), std::max(1u, extent_.height)}, format{format_} {
|
||||||
image = CreateChainImage(memory_allocator, extent, format);
|
image = CreateChainImage(memory_allocator, extent, format);
|
||||||
view = CreateWrappedImageView(device, image, format);
|
view = CreateWrappedImageView(device, image, format);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ public:
|
|||||||
return extent;
|
return extent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] VkFormat Format() const {
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] VkImageLayout Layout() const {
|
[[nodiscard]] VkImageLayout Layout() const {
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
@@ -57,6 +61,7 @@ private:
|
|||||||
vk::Image image;
|
vk::Image image;
|
||||||
vk::ImageView view;
|
vk::ImageView view;
|
||||||
VkExtent2D extent{};
|
VkExtent2D extent{};
|
||||||
|
VkFormat format{VK_FORMAT_UNDEFINED};
|
||||||
VkImageLayout layout{VK_IMAGE_LAYOUT_UNDEFINED};
|
VkImageLayout layout{VK_IMAGE_LAYOUT_UNDEFINED};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
|
|
||||||
LsfgShaders::LsfgShaders(const Device& device) {
|
LsfgShaders::LsfgShaders(const Device& device) {
|
||||||
if (!device.IsVulkanMemoryModelSupported()) {
|
if (!device.IsVulkanMemoryModelSupported() || !device.HasNullDescriptor()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user