test(decompress): cover compressed-staging release on the real GPU path

MeshDecompressStagingRelease drives the real VK_EXT_memory_decompression /
GDeflate path on a headless device and asserts the staging is handed to the
deferred-deletion queue (not pinned), the build is validation-clean with
byte-correct decompressed data, and the entry retires only after framesInFlight
frames. Skips the GPU-path assertions when the extension is absent (CPU fallback
never allocates the staging).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
catbot 2026-06-17 17:40:39 +00:00
commit b29b8f0371
2 changed files with 231 additions and 0 deletions

View file

@ -617,6 +617,40 @@ extern "C" Configuration CrafterBuildProject(std::span<const std::string_view> a
dc.GetInterfacesAndImplementations(ifaces, deferredImpls);
cfg.tests.push_back(std::move(deferredTest));
// Issue #67: the compressed Mesh::Build path no longer pins its
// host-visible `compressedStaging` for the mesh's life — it releases it
// via DeferredClear() right after recording the GPU decompress, so the
// fence-keyed deletion queue (#101/#102) frees it once that submit's
// frame has cleared. Drives the real VK_EXT_memory_decompression /
// GDeflate path on a headless device (no swapchain/window — a decompress
// + BLAS build only needs the queue + command pool) and asserts the
// staging is enqueued (not pinned), the build is validation-clean with
// correct decompressed data, and the entry retires only after
// framesInFlight frames. Shares the native build settings; needs the
// asset pipeline for SaveCompressed/LoadCompressedMesh (cfg.dependencies
// already carries Crafter.Asset).
Test meshStagingTest;
Configuration& msc = meshStagingTest.config;
msc.path = cfg.path;
msc.name = "MeshDecompressStagingRelease";
msc.outputName = "MeshDecompressStagingRelease";
msc.type = ConfigurationType::Executable;
msc.target = cfg.target;
msc.march = cfg.march;
msc.mtune = cfg.mtune;
msc.debug = cfg.debug;
msc.sysroot = cfg.sysroot;
msc.dependencies = cfg.dependencies;
msc.externalDependencies = cfg.externalDependencies;
msc.compileFlags = cfg.compileFlags;
msc.linkFlags = cfg.linkFlags;
msc.defines = cfg.defines;
msc.cFiles = cfg.cFiles;
std::vector<fs::path> meshStagingImpls(impls.begin(), impls.end());
meshStagingImpls.emplace_back("tests/MeshDecompressStagingRelease/main");
msc.GetInterfacesAndImplementations(ifaces, meshStagingImpls);
cfg.tests.push_back(std::move(meshStagingTest));
// Issue #89: Device::PreferDirectDeviceWrite chooses the upload strategy
// for a CPU-written, GPU-read buffer — direct HOST_VISIBLE|DEVICE_LOCAL
// map+write on ReBAR/UMA vs. staged-into-pure-DEVICE_LOCAL on a small