diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp index 0ac7086995..88b3717498 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index c4b72b5888..ccaa8da9e0 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -461,7 +461,11 @@ void VectorTypes::Define(Sirit::Module& sirit_ctx, Id base_type, std::string_vie EmitContext::EmitContext(const Profile& profile_, const RuntimeInfo& runtime_info_, IR::Program& program, Bindings& bindings) : Sirit::Module(profile_.supported_spirv), profile{profile_}, runtime_info{runtime_info_}, - stage{program.stage}, emulate_int64{program.info.uses_int64 && !profile.support_int64}, + stage{program.stage}, + // Enable int64 emulation if host lacks int64 but we either use int64 ops + // or we need 64-bit addressing for global memory operations. + emulate_int64{!profile.support_int64 && + (program.info.uses_int64 || program.info.uses_global_memory)}, texture_rescaling_index{bindings.texture_scaling_index}, image_rescaling_index{bindings.image_scaling_index} { const bool is_unified{profile.unified_descriptor_binding}; diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.h b/src/shader_recompiler/backend/spirv/spirv_emit_context.h index 2dbeeb0911..c0c28e4e3f 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.h +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp index 2d4feca02c..14ada93ac2 100644 --- a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp +++ b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -293,6 +296,14 @@ std::optional TrackLowAddress(IR::Inst* inst) { } // This address is expected to either be a PackUint2x32, a IAdd64, or a CompositeConstructU32x2 IR::Inst* addr_inst{addr.InstRecursive()}; + // Unwrap Identity ops introduced by lowerings (e.g., PackUint2x32 -> Identity) + while (addr_inst->GetOpcode() == IR::Opcode::Identity) { + const IR::Value id_arg{addr_inst->Arg(0)}; + if (id_arg.IsImmediate()) { + return std::nullopt; + } + addr_inst = id_arg.InstRecursive(); + } s32 imm_offset{0}; if (addr_inst->GetOpcode() == IR::Opcode::IAdd64) { // If it's an IAdd64, get the immediate offset it is applying and grab the address @@ -308,6 +319,14 @@ std::optional TrackLowAddress(IR::Inst* inst) { return std::nullopt; } addr_inst = iadd_addr.InstRecursive(); + // Unwrap Identity again if present after folding IAdd64 + while (addr_inst->GetOpcode() == IR::Opcode::Identity) { + const IR::Value id_arg{addr_inst->Arg(0)}; + if (id_arg.IsImmediate()) { + return std::nullopt; + } + addr_inst = id_arg.InstRecursive(); + } } // With IAdd64 handled, now PackUint2x32 is expected if (addr_inst->GetOpcode() == IR::Opcode::PackUint2x32) { @@ -317,6 +336,14 @@ std::optional TrackLowAddress(IR::Inst* inst) { return std::nullopt; } addr_inst = vector.InstRecursive(); + // Unwrap Identity that may replace PackUint2x32 + while (addr_inst->GetOpcode() == IR::Opcode::Identity) { + const IR::Value id_arg{addr_inst->Arg(0)}; + if (id_arg.IsImmediate()) { + return std::nullopt; + } + addr_inst = id_arg.InstRecursive(); + } } // The vector is expected to be a CompositeConstructU32x2 if (addr_inst->GetOpcode() != IR::Opcode::CompositeConstructU32x2) {