fix(rendering): prevent MSAA+FSR2 framebuffer mismatch crash

When saved settings loaded MSAA before FSR2 on startup, the pending MSAA
change (e.g. 8x) was queued before FSR2 was enabled. Since FSR2 checked
the current MSAA (still 1x), it didn't override the pending change.
On the next frame, applyMsaaChange created a 4-attachment MSAA render pass,
then FSR2 lazily created a 2-attachment framebuffer against it — SIGSEGV.

Add guards in both applyMsaaChange (force 1x if FSR2 is blocking) and
setFSR2Enabled (override any pending MSAA >1x when enabling FSR2).
This commit is contained in:
Kelsi 2026-04-03 21:41:14 -07:00
parent 7264ba1706
commit 746ac25c14

View file

@ -729,6 +729,13 @@ void Renderer::applyMsaaChange() {
VkSampleCountFlagBits samples = pendingMsaaSamples_;
msaaChangePending_ = false;
// FSR2 requires non-MSAA render pass — if FSR2 was enabled after the MSAA
// change was queued (startup race), force 1x to avoid framebuffer mismatch.
if (samples > VK_SAMPLE_COUNT_1_BIT &&
postProcessPipeline_ && postProcessPipeline_->isFsr2BlockingMsaa()) {
samples = VK_SAMPLE_COUNT_1_BIT;
}
VkSampleCountFlagBits current = vkCtx->getMsaaSamples();
if (samples == current) return;
@ -1916,6 +1923,11 @@ void Renderer::setFSR2Enabled(bool enabled) {
pendingMsaaSamples_ = req.samples;
msaaChangePending_ = true;
}
// If enabling FSR2 and there's already a pending MSAA change to >1x
// (e.g. startup settings loaded MSAA before FSR2), override it to 1x.
if (enabled && msaaChangePending_ && pendingMsaaSamples_ > VK_SAMPLE_COUNT_1_BIT) {
pendingMsaaSamples_ = VK_SAMPLE_COUNT_1_BIT;
}
}
bool Renderer::isFSR2Enabled() const {
return postProcessPipeline_ && postProcessPipeline_->isFSR2Enabled();