Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions code/graphics/vulkan/VulkanPostProcessingLDR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,14 +362,38 @@ void VulkanLDR::executeFXAA(vk::CommandBuffer cmd)
nullptr, 0);
}

// FXAA main pass: Scene_luminance → Scene_ldr
// The FXAA main pass discards non-edge fragments (FXAA_DISCARD), so those
// pixels must keep the tonemapped image already sitting in Scene_ldr. That
// requires a load-preserving render pass (loadOp=eLoad) — with the default
// eDontCare/eUndefined pass the discarded pixels are left undefined, which
// on IMR GPUs (NVIDIA) happens to preserve the old contents but on tiled /
// AMD Vega / MoltenVK gets scrambled, leaving only the FXAA-written edge
// pixels visible. Transition Scene_ldr to a color attachment first (mirrors
// executeLightshafts). This also orders the main pass's color writes after
// the prepass's sampled read of Scene_ldr (WAR hazard).
{
ImageBarrier2 barrier;
barrier.image = m_sceneLdr.image;
barrier.levelCount = 1;
barrier.layerCount = 1;
barrier.oldLayout = vk::ImageLayout::eShaderReadOnlyOptimal;
barrier.newLayout = vk::ImageLayout::eColorAttachmentOptimal;
barrier.srcStage = vk::PipelineStageFlagBits2::eFragmentShader;
barrier.srcAccess = vk::AccessFlagBits2::eShaderSampledRead;
barrier.dstStage = vk::PipelineStageFlagBits2::eColorAttachmentOutput;
barrier.dstAccess = vk::AccessFlagBits2::eColorAttachmentRead | vk::AccessFlagBits2::eColorAttachmentWrite;

cmdImageBarrier(cmd, barrier);
}

// FXAA main pass: Scene_luminance → Scene_ldr (loadOp=eLoad preserves non-edge pixels)
graphics::generic_data::fxaa_data fxaaData;
fxaaData.rt_w = static_cast<float>(m_ctx->sceneExtent.width);
fxaaData.rt_h = static_cast<float>(m_ctx->sceneExtent.height);
fxaaData.pad[0] = 0.0f;
fxaaData.pad[1] = 0.0f;

m_ctx->drawFullscreenTriangle(cmd, m_ldrRenderPass,
m_ctx->drawFullscreenTriangle(cmd, m_ldrLoadRenderPass,
m_sceneLdrFB, m_ctx->sceneExtent,
SDR_TYPE_POST_PROCESS_FXAA,
m_sceneLuminance.view, m_ctx->linearSampler,
Expand Down
6 changes: 3 additions & 3 deletions code/graphics/vulkan/VulkanShaderCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,11 @@ SCP_string VulkanShaderCompiler::buildHeader(vk::ShaderStageFlagBits /*stage*/,
header += temp;
}
}
} else if (sdrType == SDR_TYPE_POST_PROCESS_FXAA) {
} else if (gr_is_fxaa_mode(Gr_aa_mode) && sdrType == SDR_TYPE_POST_PROCESS_FXAA) {
// GLSL 450 always has textureGather
header += shader_get_fxaa_defines(Gr_aa_mode, true);
} else if (sdrType == SDR_TYPE_POST_PROCESS_SMAA_EDGE || sdrType == SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT ||
sdrType == SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING) {
} else if (gr_is_smaa_mode(Gr_aa_mode) && (sdrType == SDR_TYPE_POST_PROCESS_SMAA_EDGE || sdrType == SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT ||
sdrType == SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING)) {
// GLSL 450 always has textureGather
header += shader_get_smaa_defines(Gr_aa_mode, true);
} else {
Expand Down
Loading