perf(sync): scope frame-loop barriers to swapchain image + real per-pass stages (#115)
The inter-pass and acquire/present barriers in the frame loop set both stage masks to ALL_COMMANDS, and the inter-pass dependency used a queue-wide VkMemoryBarrier — fully serialising against every pipeline stage and flushing all caches every frame, when all the next pass needs is the swapchain image the previous one wrote. Replace the inter-pass global VkMemoryBarrier with an image memory barrier scoped to the swapchain image's single colour subresource (as the intra-pass UI barrier already does), and derive the barrier stage masks per pass: RenderPass::SwapchainStage() is overridden by UIRenderer (COMPUTE_SHADER) and RTPass (RAY_TRACING_SHADER), so a compute->compute edge only serialises COMPUTE while an RT pass pulls in RAY_TRACING — the acquire/present frame-edge masks use the real union of the frame's passes (SwapchainStageUnion). The base default and the empty-passes fallback are the conservative COMPUTE | RAY_TRACING | TRANSFER union, so a polymorphic or un-overridden pass can only be over- not under-synchronised. Adds SwapchainBarrierScope (pure CPU) pinning the per-pass derivation, the union narrowing, and the inter-pass barrier scope; FrameLoopSync already drives the real GPU frame loop with validation enabled. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
9d9f9d9d2c
commit
9414863cff
6 changed files with 316 additions and 8 deletions
29
project.cpp
29
project.cpp
|
|
@ -473,6 +473,35 @@ extern "C" Configuration CrafterBuildProject(std::span<const std::string_view> a
|
|||
mbc.GetInterfacesAndImplementations(ifaces, mipBarrierImpls);
|
||||
cfg.tests.push_back(std::move(mipBarrierTest));
|
||||
|
||||
// Issue #115: the frame loop's inter-pass and acquire/present barriers
|
||||
// no longer use ALL_COMMANDS / a queue-wide VkMemoryBarrier. The stage
|
||||
// masks are derived per pass via RenderPass::SwapchainStage() (compute
|
||||
// vs ray-tracing) and unioned across the frame by SwapchainStageUnion,
|
||||
// and the inter-pass dependency is scoped to the swapchain image by
|
||||
// BuildSwapchainInterPassBarrier — all pure CPU logic over the pass
|
||||
// list, so this test drives them directly with no GPU at runtime.
|
||||
Test swapBarrierTest;
|
||||
Configuration& sbc = swapBarrierTest.config;
|
||||
sbc.path = cfg.path;
|
||||
sbc.name = "SwapchainBarrierScope";
|
||||
sbc.outputName = "SwapchainBarrierScope";
|
||||
sbc.type = ConfigurationType::Executable;
|
||||
sbc.target = cfg.target;
|
||||
sbc.march = cfg.march;
|
||||
sbc.mtune = cfg.mtune;
|
||||
sbc.debug = cfg.debug;
|
||||
sbc.sysroot = cfg.sysroot;
|
||||
sbc.dependencies = cfg.dependencies;
|
||||
sbc.externalDependencies = cfg.externalDependencies;
|
||||
sbc.compileFlags = cfg.compileFlags;
|
||||
sbc.linkFlags = cfg.linkFlags;
|
||||
sbc.defines = cfg.defines;
|
||||
sbc.cFiles = cfg.cFiles;
|
||||
std::vector<fs::path> swapBarrierImpls(impls.begin(), impls.end());
|
||||
swapBarrierImpls.emplace_back("tests/SwapchainBarrierScope/main");
|
||||
sbc.GetInterfacesAndImplementations(ifaces, swapBarrierImpls);
|
||||
cfg.tests.push_back(std::move(swapBarrierTest));
|
||||
|
||||
// Issue #47: the fused UI uber-kernel (shaders/ui-fused.comp.glsl) and
|
||||
// its C++ push-constant mirror UIFusedHeader. Compiles the real shader
|
||||
// with glslang, validates with spirv-val, and pins the push-constant
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue