From 4fedfb87266c8fa7e4bd1b5e291dd6e79261b6b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Miko=C5=82ajczyk?= Date: Wed, 13 May 2026 00:39:42 +0200 Subject: [PATCH 1/2] Properly handle BaryCoord attributes on non-AMD GPUs --- .../backend/spirv/emit_spirv.cpp | 1 + .../spirv/emit_spirv_context_get_set.cpp | 30 ++++++++++++++----- .../backend/spirv/spirv_emit_context.cpp | 14 ++++----- .../backend/spirv/spirv_emit_context.h | 1 + 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index 4c880e4a1..518f027fa 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp @@ -301,6 +301,7 @@ void SetupCapabilities(const Info& info, const Profile& profile, const RuntimeIn } else if (profile.supports_fragment_shader_barycentric) { ctx.AddExtension("SPV_KHR_fragment_shader_barycentric"); ctx.AddCapability(spv::Capability::FragmentBarycentricKHR); + ctx.AddCapability(spv::Capability::InterpolationFunction); } if (info.loads.Get(IR::Attribute::SampleIndex) || runtime_info.fs_info.addr_flags.linear_sample_ena || diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index 47a87958c..147d2f78e 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp @@ -127,15 +127,31 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, u32 comp, u32 index) { return ctx.OpLoad(ctx.F32[1], ctx.OpAccessChain(ctx.input_f32, ctx.tess_coord, ctx.ConstU32(1U))); case IR::Attribute::BaryCoordSmooth: - return ctx.OpLoad(ctx.F32[1], ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_smooth, - ctx.ConstU32(comp))); + if (ctx.profile.supports_amd_shader_explicit_vertex_parameter) { + return ctx.OpLoad(ctx.F32[1], ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_smooth, + ctx.ConstU32(comp))); + } else { + return ctx.OpCompositeExtract(ctx.F32[1], ctx.OpLoad(ctx.F32[3], ctx.bary_coord), comp); + } case IR::Attribute::BaryCoordSmoothCentroid: - return ctx.OpLoad( - ctx.F32[1], - ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_smooth_centroid, ctx.ConstU32(comp))); + if (ctx.profile.supports_amd_shader_explicit_vertex_parameter) { + return ctx.OpLoad(ctx.F32[1], + ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_smooth_centroid, + ctx.ConstU32(comp))); + } else { + return ctx.OpCompositeExtract( + ctx.F32[1], ctx.OpInterpolateAtCentroid(ctx.F32[3], ctx.bary_coord), comp); + } case IR::Attribute::BaryCoordSmoothSample: - return ctx.OpLoad(ctx.F32[1], ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_smooth_sample, - ctx.ConstU32(comp))); + if (ctx.profile.supports_amd_shader_explicit_vertex_parameter) { + return ctx.OpLoad( + ctx.F32[1], + ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_smooth_sample, ctx.ConstU32(comp))); + } else { + return ctx.OpCompositeExtract( + ctx.F32[1], ctx.OpInterpolateAtSample(ctx.F32[3], ctx.bary_coord, ctx.sample_index), + comp); + } case IR::Attribute::BaryCoordNoPersp: return ctx.OpLoad(ctx.F32[1], ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_nopersp, ctx.ConstU32(comp))); diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index 0c2bc2de8..c4c9569f7 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -356,8 +356,8 @@ void EmitContext::DefineInputs() { if (profile.supports_amd_shader_explicit_vertex_parameter) { bary_coord_smooth = DefineVariable(F32[2], spv::BuiltIn::BaryCoordSmoothAMD, spv::StorageClass::Input); - } else if (profile.supports_fragment_shader_barycentric) { - bary_coord_smooth = + } else if (profile.supports_fragment_shader_barycentric && !ValidId(bary_coord)) { + bary_coord = DefineVariable(F32[3], spv::BuiltIn::BaryCoordKHR, spv::StorageClass::Input); } } @@ -365,20 +365,18 @@ void EmitContext::DefineInputs() { if (profile.supports_amd_shader_explicit_vertex_parameter) { bary_coord_smooth_centroid = DefineVariable( F32[2], spv::BuiltIn::BaryCoordSmoothCentroidAMD, spv::StorageClass::Input); - } else if (profile.supports_fragment_shader_barycentric) { - bary_coord_smooth_centroid = + } else if (profile.supports_fragment_shader_barycentric && !ValidId(bary_coord)) { + bary_coord = DefineVariable(F32[3], spv::BuiltIn::BaryCoordKHR, spv::StorageClass::Input); - // Decorate(bary_coord_smooth_centroid, spv::Decoration::Centroid); } } if (info.loads.GetAny(IR::Attribute::BaryCoordSmoothSample)) { if (profile.supports_amd_shader_explicit_vertex_parameter) { bary_coord_smooth_sample = DefineVariable( F32[2], spv::BuiltIn::BaryCoordSmoothSampleAMD, spv::StorageClass::Input); - } else if (profile.supports_fragment_shader_barycentric) { - bary_coord_smooth_sample = + } else if (profile.supports_fragment_shader_barycentric && !ValidId(bary_coord)) { + bary_coord = DefineVariable(F32[3], spv::BuiltIn::BaryCoordKHR, spv::StorageClass::Input); - // Decorate(bary_coord_smooth_sample, spv::Decoration::Sample); } } if (info.loads.GetAny(IR::Attribute::BaryCoordNoPersp)) { diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.h b/src/shader_recompiler/backend/spirv/spirv_emit_context.h index 3815f824c..c55551d54 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.h +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.h @@ -284,6 +284,7 @@ public: Id shared_memory_u32_type{}; Id shared_memory_u64_type{}; + Id bary_coord{}; Id bary_coord_smooth{}; Id bary_coord_smooth_centroid{}; Id bary_coord_smooth_sample{}; From 1f82b24a6bcc98a06ad38969fd3850054284fd75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Miko=C5=82ajczyk?= Date: Thu, 14 May 2026 18:28:11 +0200 Subject: [PATCH 2/2] Fix BaryCoordSmoothSample --- src/shader_recompiler/backend/spirv/emit_spirv.cpp | 5 ++++- .../backend/spirv/emit_spirv_context_get_set.cpp | 4 +++- src/shader_recompiler/backend/spirv/spirv_emit_context.cpp | 6 ++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index 518f027fa..f948a3ccc 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp @@ -305,7 +305,10 @@ void SetupCapabilities(const Info& info, const Profile& profile, const RuntimeIn } if (info.loads.Get(IR::Attribute::SampleIndex) || runtime_info.fs_info.addr_flags.linear_sample_ena || - runtime_info.fs_info.addr_flags.persp_sample_ena) { + runtime_info.fs_info.addr_flags.persp_sample_ena || + (!profile.supports_amd_shader_explicit_vertex_parameter && + profile.supports_fragment_shader_barycentric && + info.loads.Get(IR::Attribute::BaryCoordSmoothSample))) { ctx.AddCapability(spv::Capability::SampleRateShading); } if (info.loads.GetAny(IR::Attribute::RenderTargetIndex)) { diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index 147d2f78e..858d511dc 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp @@ -149,7 +149,9 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, u32 comp, u32 index) { ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_smooth_sample, ctx.ConstU32(comp))); } else { return ctx.OpCompositeExtract( - ctx.F32[1], ctx.OpInterpolateAtSample(ctx.F32[3], ctx.bary_coord, ctx.sample_index), + ctx.F32[1], + ctx.OpInterpolateAtSample(ctx.F32[3], ctx.bary_coord, + ctx.OpLoad(ctx.U32[1], ctx.sample_index)), comp); } case IR::Attribute::BaryCoordNoPersp: diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index c4c9569f7..094f944e4 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -377,6 +377,12 @@ void EmitContext::DefineInputs() { } else if (profile.supports_fragment_shader_barycentric && !ValidId(bary_coord)) { bary_coord = DefineVariable(F32[3], spv::BuiltIn::BaryCoordKHR, spv::StorageClass::Input); + // we would need sample_index to interpolate the bary_coord later + if (!ValidId(sample_index)) { + sample_index = + DefineVariable(U32[1], spv::BuiltIn::SampleId, spv::StorageClass::Input); + Decorate(sample_index, spv::Decoration::Flat); + } } } if (info.loads.GetAny(IR::Attribute::BaryCoordNoPersp)) {