diff --git a/src/shader_recompiler/frontend/translate/scalar_alu.cpp b/src/shader_recompiler/frontend/translate/scalar_alu.cpp index b85917b6..c090d8ce 100644 --- a/src/shader_recompiler/frontend/translate/scalar_alu.cpp +++ b/src/shader_recompiler/frontend/translate/scalar_alu.cpp @@ -196,6 +196,9 @@ void Translator::S_AND_B64(bool negate, const GcnInst& inst) { case OperandField::ScalarGPR: ir.SetThreadBitScalarReg(IR::ScalarReg(inst.dst[0].code), result); break; + case OperandField::ExecLo: + ir.SetExec(result); + break; default: UNREACHABLE(); } @@ -325,4 +328,20 @@ void Translator::S_BREV_B32(const GcnInst& inst) { SetDst(inst.dst[0], ir.BitReverse(GetSrc(inst.src[0]))); } +void Translator::S_ADD_U32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.IAdd(src0, src1)); + // TODO: Carry out + ir.SetScc(ir.Imm1(false)); +} + +void Translator::S_SUB_U32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.ISub(src0, src1)); + // TODO: Carry out + ir.SetScc(ir.Imm1(false)); +} + } // namespace Shader::Gcn diff --git a/src/shader_recompiler/frontend/translate/translate.cpp b/src/shader_recompiler/frontend/translate/translate.cpp index 2d1679f3..6867591a 100644 --- a/src/shader_recompiler/frontend/translate/translate.cpp +++ b/src/shader_recompiler/frontend/translate/translate.cpp @@ -105,7 +105,11 @@ IR::U32F32 Translator::GetSrc(const InstOperand& operand, bool force_flt) { } break; case OperandField::ConstFloatPos_1_0: - value = ir.Imm32(1.f); + if (force_flt) { + value = ir.Imm32(1.f); + } else { + value = ir.Imm32(std::bit_cast(1.f)); + } break; case OperandField::ConstFloatPos_0_5: value = ir.Imm32(0.5f); @@ -274,6 +278,9 @@ void Translate(IR::Block* block, std::span inst_list, Info& info) case Opcode::S_LOAD_DWORDX8: translator.S_LOAD_DWORD(8, inst); break; + case Opcode::S_LOAD_DWORDX16: + translator.S_LOAD_DWORD(16, inst); + break; case Opcode::S_BUFFER_LOAD_DWORD: translator.S_BUFFER_LOAD_DWORD(1, inst); break; @@ -437,9 +444,18 @@ void Translate(IR::Block* block, std::span inst_list, Info& info) case Opcode::BUFFER_LOAD_FORMAT_X: translator.BUFFER_LOAD_FORMAT(1, false, inst); break; + case Opcode::BUFFER_LOAD_FORMAT_XYZ: + translator.BUFFER_LOAD_FORMAT(3, false, inst); + break; + case Opcode::BUFFER_LOAD_FORMAT_XYZW: + translator.BUFFER_LOAD_FORMAT(4, false, inst); + break; case Opcode::BUFFER_STORE_FORMAT_X: translator.BUFFER_STORE_FORMAT(1, false, inst); break; + case Opcode::BUFFER_STORE_FORMAT_XYZW: + translator.BUFFER_STORE_FORMAT(4, false, inst); + break; case Opcode::V_MAX_F32: translator.V_MAX_F32(inst); break; @@ -696,6 +712,29 @@ void Translate(IR::Block* block, std::span inst_list, Info& info) case Opcode::S_BREV_B32: translator.S_BREV_B32(inst); break; + case Opcode::S_ADD_U32: + translator.S_ADD_U32(inst); + break; + case Opcode::S_SUB_U32: + translator.S_SUB_U32(inst); + break; + // TODO: Separate implementation for legacy variants. + case Opcode::V_MUL_LEGACY_F32: + translator.V_MUL_F32(inst); + break; + case Opcode::V_MAC_LEGACY_F32: + translator.V_MAC_F32(inst); + break; + case Opcode::V_MAD_LEGACY_F32: + translator.V_MAD_F32(inst); + break; + case Opcode::V_RSQ_LEGACY_F32: + case Opcode::V_RSQ_CLAMP_F32: + translator.V_RSQ_F32(inst); + break; + case Opcode::V_RCP_IFLAG_F32: + translator.V_RCP_F32(inst); + break; case Opcode::S_TTRACEDATA: LOG_WARNING(Render_Vulkan, "S_TTRACEDATA instruction!"); break; diff --git a/src/shader_recompiler/frontend/translate/translate.h b/src/shader_recompiler/frontend/translate/translate.h index 9c6d6a30..ace9042e 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -54,6 +54,8 @@ public: void S_BFM_B32(const GcnInst& inst); void S_NOT_B64(const GcnInst& inst); void S_BREV_B32(const GcnInst& inst); + void S_ADD_U32(const GcnInst& inst); + void S_SUB_U32(const GcnInst& inst); // Scalar Memory void S_LOAD_DWORD(int num_dwords, const GcnInst& inst); diff --git a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp index a1f599ba..8e1c186c 100644 --- a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp +++ b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp @@ -315,8 +315,11 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip const u32 arg_pos = inst_info.is_depth ? 5 : 4; inst.SetArg(arg_pos, arg); } - if (inst_info.explicit_lod && inst.GetOpcode() == IR::Opcode::ImageFetch) { - inst.SetArg(3, arg); + if (inst_info.explicit_lod) { + ASSERT(inst.GetOpcode() == IR::Opcode::ImageFetch || + inst.GetOpcode() == IR::Opcode::ImageSampleExplicitLod); + const u32 pos = inst.GetOpcode() == IR::Opcode::ImageFetch ? 3 : 2; + inst.SetArg(pos, arg); } } diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp index f82a976a..384d3167 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp @@ -354,6 +354,9 @@ vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat nu if (data_format == AmdGpu::DataFormat::FormatBc2 && num_format == AmdGpu::NumberFormat::Unorm) { return vk::Format::eBc2UnormBlock; } + if (data_format == AmdGpu::DataFormat::Format16_16 && num_format == AmdGpu::NumberFormat::Snorm) { + return vk::Format::eR16G16Snorm; + } UNREACHABLE_MSG("Unknown data_format={} and num_format={}", u32(data_format), u32(num_format)); }