From f722b6b85f0fa79cadaa035f1f52290384cef26d Mon Sep 17 00:00:00 2001 From: "Herman S." <429230+has207@users.noreply.github.com> Date: Sat, 27 Sep 2025 15:16:54 +0900 Subject: [PATCH] [Vulkan] Workaround for glslang 11.6.0+ change in accesschain semantics --- src/xenia/gpu/spirv_builder.h | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/xenia/gpu/spirv_builder.h b/src/xenia/gpu/spirv_builder.h index 7422d7c63..a15010277 100644 --- a/src/xenia/gpu/spirv_builder.h +++ b/src/xenia/gpu/spirv_builder.h @@ -32,6 +32,47 @@ class SpirvBuilder : public spv::Builder { // Make public rather than protected. using spv::Builder::createSelectionMerge; + // Backward compatibility wrapper for createBranch + void createBranch(spv::Block* block) { + spv::Builder::createBranch(true, block); + } + + // Backward compatibility wrapper for makeFunctionEntry + // For shaders, we use LinkageType::Max which means no linkage decoration + spv::Function* makeFunctionEntry( + spv::Decoration precision, spv::Id returnType, const char* name, + const std::vector& paramTypes, + const std::vector>& precisions, + spv::Block** entry = nullptr) { + // LinkageType::Max means no linkage decoration will be added (correct for + // shader entry points) + return spv::Builder::makeFunctionEntry(precision, returnType, name, + spv::LinkageType::Max, paramTypes, + precisions, entry); + } + + // Hide base class createAccessChain to workaround the way + // glslang 11.6.0+ uses internal accessChain state instead of parameters. + spv::Id createAccessChain(spv::StorageClass storage_class, spv::Id base, + const std::vector& offsets) { + // glslang 11.6.0+ uses the accessChain member + // in getResultingAccessChainType() but doesn't populate it from the + // parameters. We need to set it up correctly before calling the parent. + clearAccessChain(); + setAccessChainLValue(base); + for (const auto& offset : offsets) { + accessChainPush(offset, {}, 0); + } + + spv::Id result = + spv::Builder::createAccessChain(storage_class, base, offsets); + + // Clear the state again to avoid affecting subsequent operations + clearAccessChain(); + + return result; + } + spv::Id createQuadOp(spv::Op op_code, spv::Id type_id, spv::Id operand1, spv::Id operand2, spv::Id operand3, spv::Id operand4);