Dump every lsfg stage and require null descriptors

This commit is contained in:
CamilleLaVey
2026-08-13 00:24:18 -04:00
parent 30be8a5e18
commit a18d2b5c05
6 changed files with 93 additions and 28 deletions
@@ -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;
} }