From 63938ba8ddabfc10621776c39a019911775669cc Mon Sep 17 00:00:00 2001 From: Lizardy <6063922+lzardy@users.noreply.github.com> Date: Sat, 17 Aug 2024 15:06:06 -0400 Subject: [PATCH 01/12] shader_recompiler: BUFFER_ATOMIC & DS_* Opcodes (#428) * BUFFER_ATOMIC | DS_MINMAX_U32 - Emission of BufferAtomicU32 - Addition of Buffer opcodes to IR - Translator for BUFFER_ATOMIC Opcode - Translators for DS_MAXMIN_U32 Opcodes * Clang Format & UNREACHABLE_MSG * clang * no crash on compile * clang * Shared Atomics * reuse * rm vscode * resolve * opcodes * side effects * attempt fix shader comp * failed attempt to fix * clang * do correct vdata set (still fails) * clang * fixed BUFFER_ATOMIC_ADD, DS_ADD_U32 fails * data share should work * clang * resource tracking for buffer atomic * clang * distinguish RTN opcodes * clean IsBufferInstruction --------- Co-authored-by: microsoftv <6063922+microsoftv@users.noreply.github.com> --- .../backend/spirv/emit_spirv_atomic.cpp | 85 +++++++++++++++++++ .../spirv/emit_spirv_context_get_set.cpp | 1 + .../backend/spirv/emit_spirv_instructions.h | 16 ++++ .../frontend/translate/data_share.cpp | 48 +++++++++++ .../frontend/translate/translate.h | 4 + .../frontend/translate/vector_memory.cpp | 58 +++++++++++++ src/shader_recompiler/ir/ir_emitter.cpp | 66 ++++++++++++++ src/shader_recompiler/ir/ir_emitter.h | 23 +++++ src/shader_recompiler/ir/microinstruction.cpp | 16 ++++ src/shader_recompiler/ir/opcodes.inc | 20 +++++ .../ir/passes/resource_tracking_pass.cpp | 65 ++++++++------ 11 files changed, 375 insertions(+), 27 deletions(-) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp index e0bc4b77..37e91d3b 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp @@ -12,6 +12,25 @@ std::pair AtomicArgs(EmitContext& ctx) { return {scope, semantics}; } +Id SharedAtomicU32(EmitContext& ctx, Id offset, Id value, + Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) { + const Id shift_id{ctx.ConstU32(2U)}; + const Id index{ctx.OpShiftRightArithmetic(ctx.U32[1], offset, shift_id)}; + const Id pointer{ctx.OpAccessChain(ctx.shared_u32, ctx.shared_memory_u32, index)}; + const auto [scope, semantics]{AtomicArgs(ctx)}; + return (ctx.*atomic_func)(ctx.U32[1], pointer, scope, semantics, value); +} + +Id BufferAtomicU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value, + Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) { + auto& buffer = ctx.buffers[handle]; + address = ctx.OpIAdd(ctx.U32[1], address, buffer.offset); + const Id index = ctx.OpShiftRightLogical(ctx.U32[1], address, ctx.ConstU32(2u)); + const Id ptr = ctx.OpAccessChain(buffer.pointer_type, buffer.id, ctx.u32_zero_value, index); + const auto [scope, semantics]{AtomicArgs(ctx)}; + return (ctx.*atomic_func)(ctx.U32[1], ptr, scope, semantics, value); +} + Id ImageAtomicU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value, Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) { const auto& texture = ctx.images[handle & 0xFFFF]; @@ -21,6 +40,72 @@ Id ImageAtomicU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id va } } // Anonymous namespace +Id EmitSharedAtomicIAdd32(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicIAdd); +} + +Id EmitSharedAtomicUMax32(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicUMax); +} + +Id EmitSharedAtomicSMax32(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicSMax); +} + +Id EmitSharedAtomicUMin32(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicUMin); +} + +Id EmitSharedAtomicSMin32(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicSMin); +} + +Id EmitBufferAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicIAdd); +} + +Id EmitBufferAtomicSMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicSMin); +} + +Id EmitBufferAtomicUMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicUMin); +} + +Id EmitBufferAtomicSMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicSMax); +} + +Id EmitBufferAtomicUMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicUMax); +} + +Id EmitBufferAtomicInc32(EmitContext&, IR::Inst*, u32, Id, Id) { + // TODO + UNREACHABLE_MSG("Unsupported BUFFER_ATOMIC opcode: ", IR::Opcode::BufferAtomicInc32); +} + +Id EmitBufferAtomicDec32(EmitContext&, IR::Inst*, u32, Id, Id) { + // TODO + UNREACHABLE_MSG("Unsupported BUFFER_ATOMIC opcode: ", IR::Opcode::BufferAtomicDec32); +} + +Id EmitBufferAtomicAnd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicAnd); +} + +Id EmitBufferAtomicOr32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicOr); +} + +Id EmitBufferAtomicXor32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicXor); +} + +Id EmitBufferAtomicExchange32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicExchange); +} + Id EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value) { return ImageAtomicU32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicIAdd); } 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 f933ed3c..0b02f3a3 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 @@ -495,6 +495,7 @@ static void EmitStoreBufferFormatF32xN(EmitContext& ctx, u32 handle, Id address, case AmdGpu::DataFormat::Format8_8_8_8: case AmdGpu::DataFormat::Format16: case AmdGpu::DataFormat::Format32: + case AmdGpu::DataFormat::Format32_32: case AmdGpu::DataFormat::Format32_32_32_32: { ASSERT(N == AmdGpu::NumComponents(format)); diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h index 8a0fcd4b..bc39bc0f 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h @@ -81,6 +81,17 @@ void EmitStoreBufferFormatF32x2(EmitContext& ctx, IR::Inst* inst, u32 handle, Id void EmitStoreBufferFormatF32x3(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); void EmitStoreBufferFormatF32x4(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); void EmitStoreBufferU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicSMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicUMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicSMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicUMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicInc32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicDec32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicAnd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicOr32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicXor32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicExchange32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, u32 comp); Id EmitGetAttributeU32(EmitContext& ctx, IR::Attribute attr, u32 comp); void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value, u32 comp); @@ -103,6 +114,11 @@ Id EmitLoadSharedU128(EmitContext& ctx, Id offset); void EmitWriteSharedU32(EmitContext& ctx, Id offset, Id value); void EmitWriteSharedU64(EmitContext& ctx, Id offset, Id value); void EmitWriteSharedU128(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicIAdd32(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicUMax32(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicSMax32(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicUMin32(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicSMin32(EmitContext& ctx, Id offset, Id value); Id EmitCompositeConstructU32x2(EmitContext& ctx, Id e1, Id e2); Id EmitCompositeConstructU32x3(EmitContext& ctx, Id e1, Id e2, Id e3); Id EmitCompositeConstructU32x4(EmitContext& ctx, Id e1, Id e2, Id e3, Id e4); diff --git a/src/shader_recompiler/frontend/translate/data_share.cpp b/src/shader_recompiler/frontend/translate/data_share.cpp index 532e024e..b7b5aa13 100644 --- a/src/shader_recompiler/frontend/translate/data_share.cpp +++ b/src/shader_recompiler/frontend/translate/data_share.cpp @@ -25,6 +25,18 @@ void Translator::EmitDataShare(const GcnInst& inst) { return DS_WRITE(32, false, true, inst); case Opcode::DS_WRITE2_B64: return DS_WRITE(64, false, true, inst); + case Opcode::DS_ADD_U32: + return DS_ADD_U32(inst, false); + case Opcode::DS_MIN_U32: + return DS_MIN_U32(inst, false); + case Opcode::DS_MAX_U32: + return DS_MAX_U32(inst, false); + case Opcode::DS_ADD_RTN_U32: + return DS_ADD_U32(inst, true); + case Opcode::DS_MIN_RTN_U32: + return DS_MIN_U32(inst, true); + case Opcode::DS_MAX_RTN_U32: + return DS_MAX_U32(inst, true); default: LogMissingOpcode(inst); } @@ -110,6 +122,42 @@ void Translator::DS_WRITE(int bit_size, bool is_signed, bool is_pair, const GcnI } } +void Translator::DS_ADD_U32(const GcnInst& inst, bool rtn) { + const IR::U32 addr{GetSrc(inst.src[0])}; + const IR::U32 data{GetSrc(inst.src[1])}; + const IR::U32 offset = ir.Imm32(u32(inst.control.ds.offset0)); + const IR::U32 addr_offset = ir.IAdd(addr, offset); + IR::VectorReg dst_reg{inst.dst[0].code}; + const IR::Value original_val = ir.SharedAtomicIAdd(addr_offset, data); + if (rtn) { + SetDst(inst.dst[0], IR::U32{original_val}); + } +} + +void Translator::DS_MIN_U32(const GcnInst& inst, bool rtn) { + const IR::U32 addr{GetSrc(inst.src[0])}; + const IR::U32 data{GetSrc(inst.src[1])}; + const IR::U32 offset = ir.Imm32(u32(inst.control.ds.offset0)); + const IR::U32 addr_offset = ir.IAdd(addr, offset); + IR::VectorReg dst_reg{inst.dst[0].code}; + const IR::Value original_val = ir.SharedAtomicIMin(addr_offset, data, false); + if (rtn) { + SetDst(inst.dst[0], IR::U32{original_val}); + } +} + +void Translator::DS_MAX_U32(const GcnInst& inst, bool rtn) { + const IR::U32 addr{GetSrc(inst.src[0])}; + const IR::U32 data{GetSrc(inst.src[1])}; + const IR::U32 offset = ir.Imm32(u32(inst.control.ds.offset0)); + const IR::U32 addr_offset = ir.IAdd(addr, offset); + IR::VectorReg dst_reg{inst.dst[0].code}; + const IR::Value original_val = ir.SharedAtomicIMax(addr_offset, data, false); + if (rtn) { + SetDst(inst.dst[0], IR::U32{original_val}); + } +} + void Translator::S_BARRIER() { ir.Barrier(); } diff --git a/src/shader_recompiler/frontend/translate/translate.h b/src/shader_recompiler/frontend/translate/translate.h index 9ebcb116..009acabd 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -187,6 +187,7 @@ public: // Vector Memory void BUFFER_LOAD_FORMAT(u32 num_dwords, bool is_typed, bool is_format, const GcnInst& inst); void BUFFER_STORE_FORMAT(u32 num_dwords, bool is_typed, bool is_format, const GcnInst& inst); + void BUFFER_ATOMIC(AtomicOp op, const GcnInst& inst); // Vector interpolation void V_INTERP_P2_F32(const GcnInst& inst); @@ -196,6 +197,9 @@ public: void DS_SWIZZLE_B32(const GcnInst& inst); void DS_READ(int bit_size, bool is_signed, bool is_pair, const GcnInst& inst); void DS_WRITE(int bit_size, bool is_signed, bool is_pair, const GcnInst& inst); + void DS_ADD_U32(const GcnInst& inst, bool rtn); + void DS_MIN_U32(const GcnInst& inst, bool rtn); + void DS_MAX_U32(const GcnInst& inst, bool rtn); void V_READFIRSTLANE_B32(const GcnInst& inst); void V_READLANE_B32(const GcnInst& inst); void V_WRITELANE_B32(const GcnInst& inst); diff --git a/src/shader_recompiler/frontend/translate/vector_memory.cpp b/src/shader_recompiler/frontend/translate/vector_memory.cpp index 01a549f4..08674fa2 100644 --- a/src/shader_recompiler/frontend/translate/vector_memory.cpp +++ b/src/shader_recompiler/frontend/translate/vector_memory.cpp @@ -104,6 +104,10 @@ void Translator::EmitVectorMemory(const GcnInst& inst) { return BUFFER_STORE_FORMAT(3, false, false, inst); case Opcode::BUFFER_STORE_DWORDX4: return BUFFER_STORE_FORMAT(4, false, false, inst); + + // Buffer atomic operations + case Opcode::BUFFER_ATOMIC_ADD: + return BUFFER_ATOMIC(AtomicOp::Add, inst); default: LogMissingOpcode(inst); } @@ -435,6 +439,60 @@ void Translator::BUFFER_STORE_FORMAT(u32 num_dwords, bool is_typed, bool is_form } } +// TODO: U64 +void Translator::BUFFER_ATOMIC(AtomicOp op, const GcnInst& inst) { + const auto& mubuf = inst.control.mubuf; + const IR::VectorReg vaddr{inst.src[0].code}; + const IR::VectorReg vdata{inst.src[1].code}; + const IR::ScalarReg srsrc{inst.src[2].code * 4}; + const IR::U32 soffset{GetSrc(inst.src[3])}; + ASSERT_MSG(soffset.IsImmediate() && soffset.U32() == 0, "Non immediate offset not supported"); + + IR::BufferInstInfo info{}; + info.index_enable.Assign(mubuf.idxen); + info.inst_offset.Assign(mubuf.offset); + info.offset_enable.Assign(mubuf.offen); + + IR::Value vdata_val = ir.GetVectorReg(vdata); + const IR::U32 address = ir.GetVectorReg(vaddr); + const IR::Value handle = + ir.CompositeConstruct(ir.GetScalarReg(srsrc), ir.GetScalarReg(srsrc + 1), + ir.GetScalarReg(srsrc + 2), ir.GetScalarReg(srsrc + 3)); + + const IR::Value original_val = [&] { + switch (op) { + case AtomicOp::Swap: + return ir.BufferAtomicExchange(handle, address, vdata_val, info); + case AtomicOp::Add: + return ir.BufferAtomicIAdd(handle, address, vdata_val, info); + case AtomicOp::Smin: + return ir.BufferAtomicIMin(handle, address, vdata_val, true, info); + case AtomicOp::Umin: + return ir.BufferAtomicIMin(handle, address, vdata_val, false, info); + case AtomicOp::Smax: + return ir.BufferAtomicIMax(handle, address, vdata_val, true, info); + case AtomicOp::Umax: + return ir.BufferAtomicIMax(handle, address, vdata_val, false, info); + case AtomicOp::And: + return ir.BufferAtomicAnd(handle, address, vdata_val, info); + case AtomicOp::Or: + return ir.BufferAtomicOr(handle, address, vdata_val, info); + case AtomicOp::Xor: + return ir.BufferAtomicXor(handle, address, vdata_val, info); + case AtomicOp::Inc: + return ir.BufferAtomicInc(handle, address, vdata_val, info); + case AtomicOp::Dec: + return ir.BufferAtomicDec(handle, address, vdata_val, info); + default: + UNREACHABLE(); + } + }(); + + if (mubuf.glc) { + ir.SetVectorReg(vdata, IR::U32{original_val}); + } +} + void Translator::IMAGE_GET_LOD(const GcnInst& inst) { const auto& mimg = inst.control.mimg; IR::VectorReg dst_reg{inst.dst[0].code}; diff --git a/src/shader_recompiler/ir/ir_emitter.cpp b/src/shader_recompiler/ir/ir_emitter.cpp index 4271ac35..3ae06807 100644 --- a/src/shader_recompiler/ir/ir_emitter.cpp +++ b/src/shader_recompiler/ir/ir_emitter.cpp @@ -286,6 +286,25 @@ void IREmitter::WriteShared(int bit_size, const Value& value, const U32& offset) } } +U32F32 IREmitter::SharedAtomicIAdd(const U32& address, const U32F32& data) { + switch (data.Type()) { + case Type::U32: + return Inst(Opcode::SharedAtomicIAdd32, address, data); + default: + ThrowInvalidType(data.Type()); + } +} + +U32 IREmitter::SharedAtomicIMin(const U32& address, const U32& data, bool is_signed) { + return is_signed ? Inst(Opcode::SharedAtomicSMin32, address, data) + : Inst(Opcode::SharedAtomicUMin32, address, data); +} + +U32 IREmitter::SharedAtomicIMax(const U32& address, const U32& data, bool is_signed) { + return is_signed ? Inst(Opcode::SharedAtomicSMax32, address, data) + : Inst(Opcode::SharedAtomicUMax32, address, data); +} + U32 IREmitter::ReadConst(const Value& base, const U32& offset) { return Inst(Opcode::ReadConst, base, offset); } @@ -347,6 +366,53 @@ void IREmitter::StoreBuffer(int num_dwords, const Value& handle, const Value& ad } } +Value IREmitter::BufferAtomicIAdd(const Value& handle, const Value& address, const Value& value, + BufferInstInfo info) { + return Inst(Opcode::BufferAtomicIAdd32, Flags{info}, handle, address, value); +} + +Value IREmitter::BufferAtomicIMin(const Value& handle, const Value& address, const Value& value, + bool is_signed, BufferInstInfo info) { + return is_signed ? Inst(Opcode::BufferAtomicSMin32, Flags{info}, handle, address, value) + : Inst(Opcode::BufferAtomicUMin32, Flags{info}, handle, address, value); +} + +Value IREmitter::BufferAtomicIMax(const Value& handle, const Value& address, const Value& value, + bool is_signed, BufferInstInfo info) { + return is_signed ? Inst(Opcode::BufferAtomicSMax32, Flags{info}, handle, address, value) + : Inst(Opcode::BufferAtomicUMax32, Flags{info}, handle, address, value); +} + +Value IREmitter::BufferAtomicInc(const Value& handle, const Value& address, const Value& value, + BufferInstInfo info) { + return Inst(Opcode::BufferAtomicInc32, Flags{info}, handle, address, value); +} + +Value IREmitter::BufferAtomicDec(const Value& handle, const Value& address, const Value& value, + BufferInstInfo info) { + return Inst(Opcode::BufferAtomicDec32, Flags{info}, handle, address, value); +} + +Value IREmitter::BufferAtomicAnd(const Value& handle, const Value& address, const Value& value, + BufferInstInfo info) { + return Inst(Opcode::BufferAtomicAnd32, Flags{info}, handle, address, value); +} + +Value IREmitter::BufferAtomicOr(const Value& handle, const Value& address, const Value& value, + BufferInstInfo info) { + return Inst(Opcode::BufferAtomicOr32, Flags{info}, handle, address, value); +} + +Value IREmitter::BufferAtomicXor(const Value& handle, const Value& address, const Value& value, + BufferInstInfo info) { + return Inst(Opcode::BufferAtomicXor32, Flags{info}, handle, address, value); +} + +Value IREmitter::BufferAtomicExchange(const Value& handle, const Value& address, const Value& value, + BufferInstInfo info) { + return Inst(Opcode::BufferAtomicExchange32, Flags{info}, handle, address, value); +} + void IREmitter::StoreBufferFormat(int num_dwords, const Value& handle, const Value& address, const Value& data, BufferInstInfo info) { switch (num_dwords) { diff --git a/src/shader_recompiler/ir/ir_emitter.h b/src/shader_recompiler/ir/ir_emitter.h index 59ced93e..be7f2515 100644 --- a/src/shader_recompiler/ir/ir_emitter.h +++ b/src/shader_recompiler/ir/ir_emitter.h @@ -84,6 +84,10 @@ public: [[nodiscard]] Value LoadShared(int bit_size, bool is_signed, const U32& offset); void WriteShared(int bit_size, const Value& value, const U32& offset); + [[nodiscard]] U32F32 SharedAtomicIAdd(const U32& address, const U32F32& data); + [[nodiscard]] U32 SharedAtomicIMin(const U32& address, const U32& data, bool is_signed); + [[nodiscard]] U32 SharedAtomicIMax(const U32& address, const U32& data, bool is_signed); + [[nodiscard]] U32 ReadConst(const Value& base, const U32& offset); [[nodiscard]] F32 ReadConstBuffer(const Value& handle, const U32& index); @@ -96,6 +100,25 @@ public: void StoreBufferFormat(int num_dwords, const Value& handle, const Value& address, const Value& data, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicIAdd(const Value& handle, const Value& address, + const Value& value, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicIMin(const Value& handle, const Value& address, + const Value& value, bool is_signed, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicIMax(const Value& handle, const Value& address, + const Value& value, bool is_signed, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicInc(const Value& handle, const Value& address, + const Value& value, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicDec(const Value& handle, const Value& address, + const Value& value, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicAnd(const Value& handle, const Value& address, + const Value& value, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicOr(const Value& handle, const Value& address, + const Value& value, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicXor(const Value& handle, const Value& address, + const Value& value, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicExchange(const Value& handle, const Value& address, + const Value& value, BufferInstInfo info); + [[nodiscard]] U32 LaneId(); [[nodiscard]] U32 WarpId(); [[nodiscard]] U32 QuadShuffle(const U32& value, const U32& index); diff --git a/src/shader_recompiler/ir/microinstruction.cpp b/src/shader_recompiler/ir/microinstruction.cpp index a8166125..e35be8a7 100644 --- a/src/shader_recompiler/ir/microinstruction.cpp +++ b/src/shader_recompiler/ir/microinstruction.cpp @@ -60,9 +60,25 @@ bool Inst::MayHaveSideEffects() const noexcept { case Opcode::StoreBufferFormatF32x3: case Opcode::StoreBufferFormatF32x4: case Opcode::StoreBufferU32: + case Opcode::BufferAtomicIAdd32: + case Opcode::BufferAtomicSMin32: + case Opcode::BufferAtomicUMin32: + case Opcode::BufferAtomicSMax32: + case Opcode::BufferAtomicUMax32: + case Opcode::BufferAtomicInc32: + case Opcode::BufferAtomicDec32: + case Opcode::BufferAtomicAnd32: + case Opcode::BufferAtomicOr32: + case Opcode::BufferAtomicXor32: + case Opcode::BufferAtomicExchange32: case Opcode::WriteSharedU128: case Opcode::WriteSharedU64: case Opcode::WriteSharedU32: + case Opcode::SharedAtomicIAdd32: + case Opcode::SharedAtomicSMin32: + case Opcode::SharedAtomicUMin32: + case Opcode::SharedAtomicSMax32: + case Opcode::SharedAtomicUMax32: case Opcode::ImageWrite: case Opcode::ImageAtomicIAdd32: case Opcode::ImageAtomicSMin32: diff --git a/src/shader_recompiler/ir/opcodes.inc b/src/shader_recompiler/ir/opcodes.inc index 4c6122a8..e9ecd435 100644 --- a/src/shader_recompiler/ir/opcodes.inc +++ b/src/shader_recompiler/ir/opcodes.inc @@ -33,6 +33,13 @@ OPCODE(WriteSharedU32, Void, U32, OPCODE(WriteSharedU64, Void, U32, U32x2, ) OPCODE(WriteSharedU128, Void, U32, U32x4, ) +// Shared atomic operations +OPCODE(SharedAtomicIAdd32, U32, U32, U32, ) +OPCODE(SharedAtomicSMin32, U32, U32, U32, ) +OPCODE(SharedAtomicUMin32, U32, U32, U32, ) +OPCODE(SharedAtomicSMax32, U32, U32, U32, ) +OPCODE(SharedAtomicUMax32, U32, U32, U32, ) + // Context getters/setters OPCODE(GetUserData, U32, ScalarReg, ) OPCODE(GetThreadBitScalarReg, U1, ScalarReg, ) @@ -88,6 +95,19 @@ OPCODE(StoreBufferFormatF32x3, Void, Opaq OPCODE(StoreBufferFormatF32x4, Void, Opaque, Opaque, F32x4, ) OPCODE(StoreBufferU32, Void, Opaque, Opaque, U32, ) +// Buffer atomic operations +OPCODE(BufferAtomicIAdd32, U32, Opaque, Opaque, U32 ) +OPCODE(BufferAtomicSMin32, U32, Opaque, Opaque, U32 ) +OPCODE(BufferAtomicUMin32, U32, Opaque, Opaque, U32 ) +OPCODE(BufferAtomicSMax32, U32, Opaque, Opaque, U32 ) +OPCODE(BufferAtomicUMax32, U32, Opaque, Opaque, U32 ) +OPCODE(BufferAtomicInc32, U32, Opaque, Opaque, U32, ) +OPCODE(BufferAtomicDec32, U32, Opaque, Opaque, U32, ) +OPCODE(BufferAtomicAnd32, U32, Opaque, Opaque, U32, ) +OPCODE(BufferAtomicOr32, U32, Opaque, Opaque, U32, ) +OPCODE(BufferAtomicXor32, U32, Opaque, Opaque, U32, ) +OPCODE(BufferAtomicExchange32, U32, Opaque, Opaque, U32, ) + // Vector utility OPCODE(CompositeConstructU32x2, U32x2, U32, U32, ) OPCODE(CompositeConstructU32x3, U32x3, U32, U32, U32, ) diff --git a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp index 97fc5b99..20a66ad0 100644 --- a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp +++ b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp @@ -20,6 +20,42 @@ struct SharpLocation { auto operator<=>(const SharpLocation&) const = default; }; +bool IsBufferAtomic(const IR::Inst& inst) { + switch (inst.GetOpcode()) { + case IR::Opcode::BufferAtomicIAdd32: + case IR::Opcode::BufferAtomicSMin32: + case IR::Opcode::BufferAtomicUMin32: + case IR::Opcode::BufferAtomicSMax32: + case IR::Opcode::BufferAtomicUMax32: + case IR::Opcode::BufferAtomicInc32: + case IR::Opcode::BufferAtomicDec32: + case IR::Opcode::BufferAtomicAnd32: + case IR::Opcode::BufferAtomicOr32: + case IR::Opcode::BufferAtomicXor32: + case IR::Opcode::BufferAtomicExchange32: + return true; + default: + return false; + } +} + +bool IsBufferStore(const IR::Inst& inst) { + switch (inst.GetOpcode()) { + case IR::Opcode::StoreBufferF32: + case IR::Opcode::StoreBufferF32x2: + case IR::Opcode::StoreBufferF32x3: + case IR::Opcode::StoreBufferF32x4: + case IR::Opcode::StoreBufferFormatF32: + case IR::Opcode::StoreBufferFormatF32x2: + case IR::Opcode::StoreBufferFormatF32x3: + case IR::Opcode::StoreBufferFormatF32x4: + case IR::Opcode::StoreBufferU32: + return true; + default: + return IsBufferAtomic(inst); + } +} + bool IsBufferInstruction(const IR::Inst& inst) { switch (inst.GetOpcode()) { case IR::Opcode::LoadBufferF32: @@ -33,18 +69,9 @@ bool IsBufferInstruction(const IR::Inst& inst) { case IR::Opcode::LoadBufferU32: case IR::Opcode::ReadConstBuffer: case IR::Opcode::ReadConstBufferU32: - case IR::Opcode::StoreBufferF32: - case IR::Opcode::StoreBufferF32x2: - case IR::Opcode::StoreBufferF32x3: - case IR::Opcode::StoreBufferF32x4: - case IR::Opcode::StoreBufferFormatF32: - case IR::Opcode::StoreBufferFormatF32x2: - case IR::Opcode::StoreBufferFormatF32x3: - case IR::Opcode::StoreBufferFormatF32x4: - case IR::Opcode::StoreBufferU32: return true; default: - return false; + return IsBufferStore(inst); } } @@ -108,29 +135,13 @@ IR::Type BufferDataType(const IR::Inst& inst, AmdGpu::NumberFormat num_format) { case IR::Opcode::LoadBufferU32: case IR::Opcode::ReadConstBufferU32: case IR::Opcode::StoreBufferU32: + case IR::Opcode::BufferAtomicIAdd32: return IR::Type::U32; default: UNREACHABLE(); } } -bool IsBufferStore(const IR::Inst& inst) { - switch (inst.GetOpcode()) { - case IR::Opcode::StoreBufferF32: - case IR::Opcode::StoreBufferF32x2: - case IR::Opcode::StoreBufferF32x3: - case IR::Opcode::StoreBufferF32x4: - case IR::Opcode::StoreBufferFormatF32: - case IR::Opcode::StoreBufferFormatF32x2: - case IR::Opcode::StoreBufferFormatF32x3: - case IR::Opcode::StoreBufferFormatF32x4: - case IR::Opcode::StoreBufferU32: - return true; - default: - return false; - } -} - bool IsImageInstruction(const IR::Inst& inst) { switch (inst.GetOpcode()) { case IR::Opcode::ImageSampleExplicitLod: From 70576035b04051f04d832c2d5ff160ba6ff17442 Mon Sep 17 00:00:00 2001 From: Xphalnos <164882787+Xphalnos@users.noreply.github.com> Date: Sun, 18 Aug 2024 17:30:26 +0200 Subject: [PATCH 02/12] Misc changes --- .github/workflows/macos.yml | 6 +++--- .github/workflows/windows.yml | 2 +- CMakeLists.txt | 2 +- externals/glslang | 2 +- externals/toml11 | 2 +- externals/vma | 2 +- externals/vulkan-headers | 2 +- externals/xxhash | 2 +- externals/zydis | 2 +- src/qt_gui/main_window.cpp | 5 +++++ src/qt_gui/main_window_ui.h | 7 ++++++- 11 files changed, 22 insertions(+), 12 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index e46401cb..1a2a6eff 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -43,10 +43,10 @@ jobs: mv ${{github.workspace}}/build/shadps4 upload cp $(arch -x86_64 /usr/local/bin/brew --prefix)/opt/molten-vk/lib/libMoltenVK.dylib upload install_name_tool -add_rpath "@loader_path" upload/shadps4 - tar cf shadps4-macos.tar.gz -C upload . + tar cf shadps4-macos-sdl.tar.gz -C upload . - name: Upload executable uses: actions/upload-artifact@v4 with: - name: shadps4-macos - path: shadps4-macos.tar.gz + name: shadps4-macos-sdl + path: shadps4-macos-sdl.tar.gz diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 46dc13a8..49912486 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -29,6 +29,6 @@ jobs: - name: Upload executable uses: actions/upload-artifact@v4 with: - name: shadps4-win64 + name: shadps4-win64-sdl path: | ${{github.workspace}}/build/Release/shadPS4.exe diff --git a/CMakeLists.txt b/CMakeLists.txt index 74e0b32f..9898e406 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,7 +73,7 @@ find_package(glslang 14.2.0 CONFIG) find_package(magic_enum 0.9.6 CONFIG) find_package(RenderDoc 1.6.0 MODULE) find_package(SDL3 3.1.2 CONFIG) -find_package(toml11 3.8.1 CONFIG) +find_package(toml11 4.2.0 CONFIG) find_package(tsl-robin-map 1.3.0 CONFIG) find_package(VulkanHeaders 1.3.289 CONFIG) find_package(VulkanMemoryAllocator 3.1.0 CONFIG) diff --git a/externals/glslang b/externals/glslang index 7c4d91e7..d59c84d3 160000 --- a/externals/glslang +++ b/externals/glslang @@ -1 +1 @@ -Subproject commit 7c4d91e7819a1d27213aa3499953d54ae1a00e8f +Subproject commit d59c84d388c805022e2bddea08aa41cbe7e43e55 diff --git a/externals/toml11 b/externals/toml11 index fcb1d3d7..cc0bee4f 160000 --- a/externals/toml11 +++ b/externals/toml11 @@ -1 +1 @@ -Subproject commit fcb1d3d7e5885edfadbbe9572991dc4b3248af58 +Subproject commit cc0bee4fd46ea1f5db147d63ea545208cc9e8405 diff --git a/externals/vma b/externals/vma index 871913da..e1bdbca9 160000 --- a/externals/vma +++ b/externals/vma @@ -1 +1 @@ -Subproject commit 871913da6a4b132b567d7b65c509600363c0041e +Subproject commit e1bdbca9baf4d682fb6066b380f4aa4a7bdbb58a diff --git a/externals/vulkan-headers b/externals/vulkan-headers index 595c8d47..d205aff4 160000 --- a/externals/vulkan-headers +++ b/externals/vulkan-headers @@ -1 +1 @@ -Subproject commit 595c8d4794410a4e64b98dc58d27c0310d7ea2fd +Subproject commit d205aff40b4e15d4c568523ee6a26f85138126d9 diff --git a/externals/xxhash b/externals/xxhash index ee65ff98..dbea33e4 160000 --- a/externals/xxhash +++ b/externals/xxhash @@ -1 +1 @@ -Subproject commit ee65ff988bab34a184c700e2fbe1e1c5bc27485d +Subproject commit dbea33e47e7c0fe0b7c8592cd931c7430c1f130d diff --git a/externals/zydis b/externals/zydis index 16c6a369..bd73bc03 160000 --- a/externals/zydis +++ b/externals/zydis @@ -1 +1 @@ -Subproject commit 16c6a369c193981e9cf314126589eaa8763f92c3 +Subproject commit bd73bc03b0aacaa89c9c203b9b43cd08f1b1843b diff --git a/src/qt_gui/main_window.cpp b/src/qt_gui/main_window.cpp index f862c064..653987b5 100644 --- a/src/qt_gui/main_window.cpp +++ b/src/qt_gui/main_window.cpp @@ -202,6 +202,11 @@ void MainWindow::CreateConnects() { connect(m_game_list_frame.get(), &QTableWidget::cellDoubleClicked, this, &MainWindow::StartGame); + connect(ui->configureAct, &QAction::triggered, this, [this]() { + auto settingsDialog = new SettingsDialog(m_physical_devices, this); + settingsDialog->exec(); + }); + connect(ui->settingsButton, &QPushButton::clicked, this, [this]() { auto settingsDialog = new SettingsDialog(m_physical_devices, this); settingsDialog->exec(); diff --git a/src/qt_gui/main_window_ui.h b/src/qt_gui/main_window_ui.h index b7132c64..f8de3076 100644 --- a/src/qt_gui/main_window_ui.h +++ b/src/qt_gui/main_window_ui.h @@ -46,6 +46,7 @@ public: QAction* dumpGameListAct; QAction* pkgViewerAct; QAction* aboutAct; + QAction* configureAct; QAction* setThemeDark; QAction* setThemeLight; QAction* setThemeGreen; @@ -143,6 +144,8 @@ public: pkgViewerAct->setIcon(QIcon(":images/file_icon.png")); aboutAct = new QAction(MainWindow); aboutAct->setObjectName("aboutAct"); + configureAct = new QAction(MainWindow); + configureAct->setObjectName("configureAct"); setThemeDark = new QAction(MainWindow); setThemeDark->setObjectName("setThemeDark"); setThemeDark->setCheckable(true); @@ -285,6 +288,7 @@ public: menuGame_List_Mode->addAction(setlistModeListAct); menuGame_List_Mode->addAction(setlistModeGridAct); menuGame_List_Mode->addAction(setlistElfAct); + menuSettings->addAction(configureAct); menuSettings->addAction(gameInstallPathAct); menuSettings->addAction(menuUtils->menuAction()); menuUtils->addAction(dumpGameListAct); @@ -303,7 +307,8 @@ public: bootInstallPkgAct->setText( QCoreApplication::translate("MainWindow", "Install Packages (PKG)", nullptr)); bootGameAct->setText(QCoreApplication::translate("MainWindow", "Boot Game", nullptr)); - aboutAct->setText(QCoreApplication::translate("MainWindow", "About", nullptr)); + aboutAct->setText(QCoreApplication::translate("MainWindow", "About shadPS4", nullptr)); + configureAct->setText(QCoreApplication::translate("MainWindow", "Configure...", nullptr)); #if QT_CONFIG(tooltip) bootInstallPkgAct->setToolTip(QCoreApplication::translate( "MainWindow", "Install application from a .pkg file", nullptr)); From 1c898d084237a02b5e9e4c81eb50e056c1b28470 Mon Sep 17 00:00:00 2001 From: Vladislav Mikhalin Date: Sun, 18 Aug 2024 20:37:29 +0300 Subject: [PATCH 03/12] Fix stencil buffer not being used (#464) --- src/video_core/amdgpu/liverpool.h | 2 +- .../renderer_vulkan/vk_graphics_pipeline.cpp | 18 +++++++++++++----- .../renderer_vulkan/vk_scheduler.cpp | 1 + 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/video_core/amdgpu/liverpool.h b/src/video_core/amdgpu/liverpool.h index 92a24795..896927df 100644 --- a/src/video_core/amdgpu/liverpool.h +++ b/src/video_core/amdgpu/liverpool.h @@ -452,7 +452,7 @@ struct Liverpool { BitField<11, 1, u32> enable_polygon_offset_front; BitField<12, 1, u32> enable_polygon_offset_back; BitField<13, 1, u32> enable_polygon_offset_para; - BitField<13, 1, u32> enable_window_offset; + BitField<16, 1, u32> enable_window_offset; BitField<19, 1, ProvokingVtxLast> provoking_vtx_last; PolygonMode PolyMode() const { diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 6bfe471c..2d502737 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -172,10 +172,17 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul .reference = key.stencil_ref_front.stencil_test_val, }, .back{ - .failOp = LiverpoolToVK::StencilOp(key.stencil.stencil_fail_back), - .passOp = LiverpoolToVK::StencilOp(key.stencil.stencil_zpass_back), - .depthFailOp = LiverpoolToVK::StencilOp(key.stencil.stencil_zfail_back), - .compareOp = LiverpoolToVK::CompareOp(key.depth.stencil_bf_func), + .failOp = LiverpoolToVK::StencilOp(key.depth.backface_enable + ? key.stencil.stencil_fail_back + : key.stencil.stencil_fail_front), + .passOp = LiverpoolToVK::StencilOp(key.depth.backface_enable + ? key.stencil.stencil_zpass_back + : key.stencil.stencil_zpass_front), + .depthFailOp = LiverpoolToVK::StencilOp(key.depth.backface_enable + ? key.stencil.stencil_zfail_back + : key.stencil.stencil_zfail_front), + .compareOp = LiverpoolToVK::CompareOp( + key.depth.backface_enable ? key.depth.stencil_bf_func : key.depth.stencil_ref_func), .compareMask = key.stencil_ref_back.stencil_mask, .writeMask = key.stencil_ref_back.stencil_write_mask, .reference = key.stencil_ref_back.stencil_test_val, @@ -207,7 +214,8 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul .colorAttachmentCount = num_color_formats, .pColorAttachmentFormats = key.color_formats.data(), .depthAttachmentFormat = key.depth_format, - .stencilAttachmentFormat = vk::Format::eUndefined, + .stencilAttachmentFormat = + key.depth.stencil_enable ? key.depth_format : vk::Format::eUndefined, }; std::array attachments; diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index a6c2536b..10ee6ea6 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -39,6 +39,7 @@ void Scheduler::BeginRendering(const RenderState& new_state) { .colorAttachmentCount = render_state.num_color_attachments, .pColorAttachments = render_state.color_attachments.data(), .pDepthAttachment = render_state.has_depth ? &render_state.depth_attachment : nullptr, + .pStencilAttachment = render_state.has_stencil ? &render_state.depth_attachment : nullptr, }; current_cmdbuf.beginRendering(rendering_info); From 5891900c6ecebf9909d002bcbd12caa45768d6ce Mon Sep 17 00:00:00 2001 From: DanielSvoboda Date: Sun, 18 Aug 2024 16:04:48 -0300 Subject: [PATCH 04/12] alphabetical order console language --- src/qt_gui/settings_dialog.cpp | 51 ++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/src/qt_gui/settings_dialog.cpp b/src/qt_gui/settings_dialog.cpp index ca47f331..c1d1e8a3 100644 --- a/src/qt_gui/settings_dialog.cpp +++ b/src/qt_gui/settings_dialog.cpp @@ -4,6 +4,39 @@ #include "settings_dialog.h" #include "ui_settings_dialog.h" +const QVector languageIndexes = { + 21, // Arabic + 23, // Czech + 14, // Danish + 6, // Dutch + 18, // English (United Kingdom) + 1, // English (United States) + 12, // Finnish + 22, // French (Canada) + 2, // French (France) + 4, // German + 25, // Greek + 24, // Hungarian + 29, // Indonesian + 5, // Italian + 0, // Japanese + 9, // Korean + 15, // Norwegian + 16, // Polish + 17, // Portuguese (Brazil) + 7, // Portuguese (Portugal) + 26, // Romanian + 8, // Russian + 11, // Simplified Chinese + 20, // Spanish (Latin America) + 3, // Spanish (Spain) + 13, // Swedish + 27, // Thai + 10, // Traditional Chinese + 19, // Turkish + 28, // Vietnamese +}; + SettingsDialog::SettingsDialog(std::span physical_devices, QWidget* parent) : QDialog(parent), ui(new Ui::SettingsDialog) { ui->setupUi(this); @@ -44,8 +77,13 @@ SettingsDialog::SettingsDialog(std::span physical_devices, QWidge connect(ui->userNameLineEdit, &QLineEdit::textChanged, this, [](const QString& text) { Config::setUserName(text.toStdString()); }); - connect(ui->consoleLanguageComboBox, &QComboBox::currentIndexChanged, this, - [](int index) { Config::setLanguage(index); }); + connect(ui->consoleLanguageComboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, [this](int index) { + if (index >= 0 && index < languageIndexes.size()) { + int languageCode = languageIndexes[index]; + Config::setLanguage(languageCode); + } + }); connect(ui->fullscreenCheckBox, &QCheckBox::stateChanged, this, [](int val) { Config::setFullscreenMode(val); }); @@ -106,8 +144,11 @@ SettingsDialog::SettingsDialog(std::span physical_devices, QWidge } void SettingsDialog::LoadValuesFromConfig() { - ui->consoleLanguageComboBox->setCurrentIndex(Config::GetLanguage()); - + ui->consoleLanguageComboBox->setCurrentIndex( + std::distance( + languageIndexes.begin(), + std::find(languageIndexes.begin(), languageIndexes.end(), Config::GetLanguage())) % + languageIndexes.size()); ui->graphicsAdapterBox->setCurrentIndex(Config::getGpuId() + 1); ui->widthSpinBox->setValue(Config::getScreenWidth()); ui->heightSpinBox->setValue(Config::getScreenHeight()); @@ -133,4 +174,4 @@ int SettingsDialog::exec() { return QDialog::exec(); } -SettingsDialog::~SettingsDialog() {} \ No newline at end of file +SettingsDialog::~SettingsDialog() {} From ed96a9fb8e71613f7d88180354dc31670b04b5a4 Mon Sep 17 00:00:00 2001 From: DanielSvoboda Date: Sun, 18 Aug 2024 16:15:06 -0300 Subject: [PATCH 05/12] alphabetical order console language --- src/qt_gui/settings_dialog.ui | 150 +++++++++++++++++----------------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/src/qt_gui/settings_dialog.ui b/src/qt_gui/settings_dialog.ui index 11ba38d0..40ed905f 100644 --- a/src/qt_gui/settings_dialog.ui +++ b/src/qt_gui/settings_dialog.ui @@ -115,32 +115,17 @@ - Japanese + Arabic - English (United States) + Czech - French (France) - - - - - Spanish (Spain) - - - - - German - - - - - Italian + Danish @@ -150,27 +135,12 @@ - Portuguese (Portugal) + English (United Kingdom) - Russian - - - - - Korean - - - - - Traditional Chinese - - - - - Simplified Chinese + English (United States) @@ -180,12 +150,47 @@ - Swedish + French (Canada) - Danish + French (France) + + + + + German + + + + + Greek + + + + + Hungarian + + + + + Indonesian + + + + + Italian + + + + + Japanese + + + + + Korean @@ -205,42 +210,7 @@ - English (United Kingdom) - - - - - Turkish - - - - - Spanish (Latin America) - - - - - Arabic - - - - - French (Canada) - - - - - Czech - - - - - Hungarian - - - - - Greek + Portuguese (Portugal) @@ -248,6 +218,31 @@ Romanian + + + Russian + + + + + Simplified Chinese + + + + + Spanish (Latin America) + + + + + Spanish (Spain) + + + + + Swedish + + Thai @@ -255,12 +250,17 @@ - Vietnamese + Traditional Chinese - Indonesian + Turkish + + + + + Vietnamese From c9a502b31a3fbbb8cc220d8a5e706ab97385b161 Mon Sep 17 00:00:00 2001 From: DanielSvoboda Date: Sun, 18 Aug 2024 17:24:35 -0300 Subject: [PATCH 06/12] alphabetical order console language --- src/qt_gui/settings_dialog.ui | 150 ---------------------------------- 1 file changed, 150 deletions(-) diff --git a/src/qt_gui/settings_dialog.ui b/src/qt_gui/settings_dialog.ui index 40ed905f..dbb15206 100644 --- a/src/qt_gui/settings_dialog.ui +++ b/src/qt_gui/settings_dialog.ui @@ -113,156 +113,6 @@ - - - Arabic - - - - - Czech - - - - - Danish - - - - - Dutch - - - - - English (United Kingdom) - - - - - English (United States) - - - - - Finnish - - - - - French (Canada) - - - - - French (France) - - - - - German - - - - - Greek - - - - - Hungarian - - - - - Indonesian - - - - - Italian - - - - - Japanese - - - - - Korean - - - - - Norwegian - - - - - Polish - - - - - Portuguese (Brazil) - - - - - Portuguese (Portugal) - - - - - Romanian - - - - - Russian - - - - - Simplified Chinese - - - - - Spanish (Latin America) - - - - - Spanish (Spain) - - - - - Swedish - - - - - Thai - - - - - Traditional Chinese - - - - - Turkish - - - - - Vietnamese - - From c58ad6d3b5a384035f628a27e266f79ecfd9261a Mon Sep 17 00:00:00 2001 From: DanielSvoboda Date: Sun, 18 Aug 2024 17:24:41 -0300 Subject: [PATCH 07/12] alphabetical order console language --- src/qt_gui/settings_dialog.cpp | 72 +++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/src/qt_gui/settings_dialog.cpp b/src/qt_gui/settings_dialog.cpp index c1d1e8a3..aa2c7338 100644 --- a/src/qt_gui/settings_dialog.cpp +++ b/src/qt_gui/settings_dialog.cpp @@ -1,41 +1,43 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include #include "settings_dialog.h" #include "ui_settings_dialog.h" -const QVector languageIndexes = { - 21, // Arabic - 23, // Czech - 14, // Danish - 6, // Dutch - 18, // English (United Kingdom) - 1, // English (United States) - 12, // Finnish - 22, // French (Canada) - 2, // French (France) - 4, // German - 25, // Greek - 24, // Hungarian - 29, // Indonesian - 5, // Italian - 0, // Japanese - 9, // Korean - 15, // Norwegian - 16, // Polish - 17, // Portuguese (Brazil) - 7, // Portuguese (Portugal) - 26, // Romanian - 8, // Russian - 11, // Simplified Chinese - 20, // Spanish (Latin America) - 3, // Spanish (Spain) - 13, // Swedish - 27, // Thai - 10, // Traditional Chinese - 19, // Turkish - 28, // Vietnamese -}; +QStringList languageNames = {"Arabic", + "Czech", + "Danish", + "Dutch", + "English (United Kingdom)", + "English (United States)", + "Finnish", + "French (Canada)", + "French (France)", + "German", + "Greek", + "Hungarian", + "Indonesian", + "Italian", + "Japanese", + "Korean", + "Norwegian", + "Polish", + "Portuguese (Brazil)", + "Portuguese (Portugal)", + "Romanian", + "Russian", + "Simplified Chinese", + "Spanish (Latin America)", + "Spanish (Spain)", + "Swedish", + "Thai", + "Traditional Chinese", + "Turkish", + "Vietnamese"}; + +const QVector languageIndexes = {21, 23, 14, 6, 18, 1, 12, 22, 2, 4, 25, 24, 29, 5, 0, + 9, 15, 16, 17, 7, 26, 8, 11, 20, 3, 13, 27, 10, 19, 28}; SettingsDialog::SettingsDialog(std::span physical_devices, QWidget* parent) : QDialog(parent), ui(new Ui::SettingsDialog) { @@ -51,6 +53,12 @@ SettingsDialog::SettingsDialog(std::span physical_devices, QWidge ui->graphicsAdapterBox->addItem(device); } + ui->consoleLanguageComboBox->addItems(languageNames); + + QCompleter* completer = new QCompleter(languageNames, this); + completer->setCaseSensitivity(Qt::CaseInsensitive); + ui->consoleLanguageComboBox->setCompleter(completer); + LoadValuesFromConfig(); connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QWidget::close); From d5e978c6f2a3aaccaa60004af06d3a1dc2bc3fff Mon Sep 17 00:00:00 2001 From: DanielSvoboda Date: Mon, 19 Aug 2024 01:25:15 -0300 Subject: [PATCH 08/12] Copy submenu --- src/qt_gui/gui_context_menus.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/qt_gui/gui_context_menus.h b/src/qt_gui/gui_context_menus.h index 146d5c34..2f4b884c 100644 --- a/src/qt_gui/gui_context_menus.h +++ b/src/qt_gui/gui_context_menus.h @@ -3,6 +3,7 @@ #pragma once +#include #include #include #include @@ -53,6 +54,18 @@ public: menu.addAction(&openSfoViewer); menu.addAction(&openTrophyViewer); + // "Copy" submenu. + QMenu* copyMenu = new QMenu("Copy info", widget); + QAction* copyName = new QAction("Copy Name", widget); + QAction* copySerial = new QAction("Copy Serial", widget); + QAction* copyNameAll = new QAction("Copy All", widget); + + copyMenu->addAction(copyName); + copyMenu->addAction(copySerial); + copyMenu->addAction(copyNameAll); + + menu.addMenu(copyMenu); + // Show menu. auto selected = menu.exec(global_pos); if (!selected) { @@ -191,6 +204,27 @@ public: } } } + + // Handle the "Copy" actions + if (selected == copyName) { + QClipboard* clipboard = QGuiApplication::clipboard(); + clipboard->setText(QString::fromStdString(m_games[itemID].name)); + } + + if (selected == copySerial) { + QClipboard* clipboard = QGuiApplication::clipboard(); + clipboard->setText(QString::fromStdString(m_games[itemID].serial)); + } + + if (selected == copyNameAll) { + QClipboard* clipboard = QGuiApplication::clipboard(); + QString combinedText = QString("Name:%1 | Serial:%2 | Version:%3 | Size:%4") + .arg(QString::fromStdString(m_games[itemID].name)) + .arg(QString::fromStdString(m_games[itemID].serial)) + .arg(QString::fromStdString(m_games[itemID].version)) + .arg(QString::fromStdString(m_games[itemID].size)); + clipboard->setText(combinedText); + } } int GetRowIndex(QTreeWidget* treeWidget, QTreeWidgetItem* item) { From 138c9ce787cef7ee3121a6bc5a4488757de79ccc Mon Sep 17 00:00:00 2001 From: Lizardy <6063922+lzardy@users.noreply.github.com> Date: Mon, 19 Aug 2024 03:03:05 -0400 Subject: [PATCH 09/12] [WIP] libSceNgs2 (#439) * init ngs2 * clang * ngs2 HLE for missing LLE * clang * clang * orbis ngs2 error codes * resolve, error codes, ngs2_impl * clang * clang * mac atomic * clang * mac * clang --------- Co-authored-by: microsoftv <6063922+microsoftv@users.noreply.github.com> --- CMakeLists.txt | 2 + src/common/logging/filter.cpp | 1 + src/common/logging/types.h | 1 + src/core/libraries/error_codes.h | 2 +- src/core/libraries/ngs2/ngs2.cpp | 419 ++++++++++++++++++++++++++ src/core/libraries/ngs2/ngs2.h | 72 +++++ src/core/libraries/ngs2/ngs2_error.h | 56 ++++ src/core/libraries/ngs2/ngs2_impl.cpp | 163 ++++++++++ src/core/libraries/ngs2/ngs2_impl.h | 25 ++ src/emulator.cpp | 3 +- 10 files changed, 742 insertions(+), 2 deletions(-) create mode 100644 src/core/libraries/ngs2/ngs2.cpp create mode 100644 src/core/libraries/ngs2/ngs2.h create mode 100644 src/core/libraries/ngs2/ngs2_error.h create mode 100644 src/core/libraries/ngs2/ngs2_impl.cpp create mode 100644 src/core/libraries/ngs2/ngs2_impl.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9898e406..679325ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,6 +127,8 @@ set(AUDIO_LIB src/core/libraries/audio/audioin.cpp src/core/libraries/audio/audioout.h src/core/libraries/ajm/ajm.cpp src/core/libraries/ajm/ajm.h + src/core/libraries/ngs2/ngs2.cpp + src/core/libraries/ngs2/ngs2.h ) set(GNM_LIB src/core/libraries/gnmdriver/gnmdriver.cpp diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp index 2c4a20de..ab3468ca 100644 --- a/src/common/logging/filter.cpp +++ b/src/common/logging/filter.cpp @@ -112,6 +112,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) { SUB(Lib, ErrorDialog) \ SUB(Lib, ImeDialog) \ SUB(Lib, AvPlayer) \ + SUB(Lib, Ngs2) \ CLS(Frontend) \ CLS(Render) \ SUB(Render, Vulkan) \ diff --git a/src/common/logging/types.h b/src/common/logging/types.h index dccb838a..dd2376ea 100644 --- a/src/common/logging/types.h +++ b/src/common/logging/types.h @@ -79,6 +79,7 @@ enum class Class : u8 { Lib_ErrorDialog, ///< The LibSceErrorDialog implementation. Lib_ImeDialog, ///< The LibSceImeDialog implementation. Lib_AvPlayer, ///< The LibSceAvPlayer implementation. + Lib_Ngs2, ///< The LibSceNgs2 implementation. Frontend, ///< Emulator UI Render, ///< Video Core Render_Vulkan, ///< Vulkan backend diff --git a/src/core/libraries/error_codes.h b/src/core/libraries/error_codes.h index 74aeef67..123edcee 100644 --- a/src/core/libraries/error_codes.h +++ b/src/core/libraries/error_codes.h @@ -471,4 +471,4 @@ constexpr int ORBIS_AVPLAYER_ERROR_INFO_AES_ENCRY = 0x806A00B5; constexpr int ORBIS_AVPLAYER_ERROR_INFO_OTHER_ENCRY = 0x806A00BF; // AppContent library -constexpr int ORBIS_APP_CONTENT_ERROR_PARAMETER = 0x80D90002; +constexpr int ORBIS_APP_CONTENT_ERROR_PARAMETER = 0x80D90002; \ No newline at end of file diff --git a/src/core/libraries/ngs2/ngs2.cpp b/src/core/libraries/ngs2/ngs2.cpp new file mode 100644 index 00000000..b66c9b15 --- /dev/null +++ b/src/core/libraries/ngs2/ngs2.cpp @@ -0,0 +1,419 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "ngs2.h" +#include "ngs2_error.h" +#include "ngs2_impl.h" + +#include "common/logging/log.h" +#include "core/libraries/error_codes.h" +#include "core/libraries/libs.h" + +namespace Libraries::Ngs2 { + +int PS4_SYSV_ABI sceNgs2CalcWaveformBlock() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2CustomRackGetModuleInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2FftInit() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2FftProcess() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2FftQuerySize() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2GeomApply() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2GeomCalcListener() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2GeomResetListenerParam() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2GeomResetSourceParam() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2GetWaveformFrameInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2JobSchedulerResetOption() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2ModuleArrayEnumItems() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2ModuleEnumConfigs() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2ModuleQueueEnumItems() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2PanGetVolumeMatrix() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2PanInit() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2ParseWaveformData() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2ParseWaveformFile() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2ParseWaveformUser() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackCreate() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackCreateWithAllocator() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackDestroy() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackGetInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackGetUserData() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackGetVoiceHandle() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackLock() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackQueryBufferSize() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackQueryInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackRunCommands() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackSetUserData() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackUnlock() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2ReportRegisterHandler() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2ReportUnregisterHandler() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemCreate() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemCreateWithAllocator() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemDestroy() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemEnumHandles() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemEnumRackHandles() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemGetInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemGetUserData() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemLock() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemQueryBufferSize() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemQueryInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemRender() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemResetOption() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemRunCommands() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemSetGrainSamples() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemSetLoudThreshold() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemSetSampleRate() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemSetUserData() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemUnlock() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2StreamCreate() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2StreamCreateWithAllocator() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2StreamDestroy() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2StreamQueryBufferSize() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2StreamQueryInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2StreamResetOption() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2StreamRunCommands() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2VoiceControl() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2VoiceGetMatrixInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2VoiceGetOwner() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2VoiceGetPortInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2VoiceGetState() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2VoiceGetStateFlags() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2VoiceQueryInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2VoiceRunCommands() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +void RegisterlibSceNgs2(Core::Loader::SymbolsResolver* sym) { + LIB_FUNCTION("3pCNbVM11UA", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2CalcWaveformBlock); + LIB_FUNCTION("6qN1zaEZuN0", "libSceNgs2", 1, "libSceNgs2", 1, 1, + sceNgs2CustomRackGetModuleInfo); + LIB_FUNCTION("Kg1MA5j7KFk", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2FftInit); + LIB_FUNCTION("D8eCqBxSojA", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2FftProcess); + LIB_FUNCTION("-YNfTO6KOMY", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2FftQuerySize); + LIB_FUNCTION("eF8yRCC6W64", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2GeomApply); + LIB_FUNCTION("1WsleK-MTkE", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2GeomCalcListener); + LIB_FUNCTION("7Lcfo8SmpsU", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2GeomResetListenerParam); + LIB_FUNCTION("0lbbayqDNoE", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2GeomResetSourceParam); + LIB_FUNCTION("ekGJmmoc8j4", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2GetWaveformFrameInfo); + LIB_FUNCTION("BcoPfWfpvVI", "libSceNgs2", 1, "libSceNgs2", 1, 1, + sceNgs2JobSchedulerResetOption); + LIB_FUNCTION("EEemGEQCjO8", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ModuleArrayEnumItems); + LIB_FUNCTION("TaoNtmMKkXQ", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ModuleEnumConfigs); + LIB_FUNCTION("ve6bZi+1sYQ", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ModuleQueueEnumItems); + LIB_FUNCTION("gbMKV+8Enuo", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2PanGetVolumeMatrix); + LIB_FUNCTION("xa8oL9dmXkM", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2PanInit); + LIB_FUNCTION("hyVLT2VlOYk", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ParseWaveformData); + LIB_FUNCTION("iprCTXPVWMI", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ParseWaveformFile); + LIB_FUNCTION("t9T0QM17Kvo", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ParseWaveformUser); + LIB_FUNCTION("cLV4aiT9JpA", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackCreate); + LIB_FUNCTION("U546k6orxQo", "libSceNgs2", 1, "libSceNgs2", 1, 1, + sceNgs2RackCreateWithAllocator); + LIB_FUNCTION("lCqD7oycmIM", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackDestroy); + LIB_FUNCTION("M4LYATRhRUE", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackGetInfo); + LIB_FUNCTION("Mn4XNDg03XY", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackGetUserData); + LIB_FUNCTION("MwmHz8pAdAo", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackGetVoiceHandle); + LIB_FUNCTION("MzTa7VLjogY", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackLock); + LIB_FUNCTION("0eFLVCfWVds", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackQueryBufferSize); + LIB_FUNCTION("TZqb8E-j3dY", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackQueryInfo); + LIB_FUNCTION("MI2VmBx2RbM", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackRunCommands); + LIB_FUNCTION("JNTMIaBIbV4", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackSetUserData); + LIB_FUNCTION("++YZ7P9e87U", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackUnlock); + LIB_FUNCTION("uBIN24Tv2MI", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ReportRegisterHandler); + LIB_FUNCTION("nPzb7Ly-VjE", "libSceNgs2", 1, "libSceNgs2", 1, 1, + sceNgs2ReportUnregisterHandler); + LIB_FUNCTION("koBbCMvOKWw", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemCreate); + LIB_FUNCTION("mPYgU4oYpuY", "libSceNgs2", 1, "libSceNgs2", 1, 1, + sceNgs2SystemCreateWithAllocator); + LIB_FUNCTION("u-WrYDaJA3k", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemDestroy); + LIB_FUNCTION("vubFP0T6MP0", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemEnumHandles); + LIB_FUNCTION("U-+7HsswcIs", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemEnumRackHandles); + LIB_FUNCTION("vU7TQ62pItw", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemGetInfo); + LIB_FUNCTION("4lFaRxd-aLs", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemGetUserData); + LIB_FUNCTION("gThZqM5PYlQ", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemLock); + LIB_FUNCTION("pgFAiLR5qT4", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemQueryBufferSize); + LIB_FUNCTION("3oIK7y7O4k0", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemQueryInfo) + LIB_FUNCTION("i0VnXM-C9fc", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemRender); + LIB_FUNCTION("AQkj7C0f3PY", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemResetOption); + LIB_FUNCTION("gXiormHoZZ4", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemRunCommands); + LIB_FUNCTION("l4Q2dWEH6UM", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemSetGrainSamples); + LIB_FUNCTION("Wdlx0ZFTV9s", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemSetLoudThreshold); + LIB_FUNCTION("-tbc2SxQD60", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemSetSampleRate); + LIB_FUNCTION("GZB2v0XnG0k", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemSetUserData); + LIB_FUNCTION("JXRC5n0RQls", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemUnlock); + LIB_FUNCTION("sU2St3agdjg", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamCreate); + LIB_FUNCTION("I+RLwaauggA", "libSceNgs2", 1, "libSceNgs2", 1, 1, + sceNgs2StreamCreateWithAllocator); + LIB_FUNCTION("bfoMXnTRtwE", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamDestroy); + LIB_FUNCTION("dxulc33msHM", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamQueryBufferSize); + LIB_FUNCTION("rfw6ufRsmow", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamQueryInfo); + LIB_FUNCTION("q+2W8YdK0F8", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamResetOption); + LIB_FUNCTION("qQHCi9pjDps", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamRunCommands); + LIB_FUNCTION("uu94irFOGpA", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceControl); + LIB_FUNCTION("jjBVvPN9964", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceGetMatrixInfo); + LIB_FUNCTION("W-Z8wWMBnhk", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceGetOwner); + LIB_FUNCTION("WCayTgob7-o", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceGetPortInfo); + LIB_FUNCTION("-TOuuAQ-buE", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceGetState); + LIB_FUNCTION("rEh728kXk3w", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceGetStateFlags); + LIB_FUNCTION("9eic4AmjGVI", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceQueryInfo); + LIB_FUNCTION("AbYvTOZ8Pts", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceRunCommands); +}; + +} // namespace Libraries::Ngs2 \ No newline at end of file diff --git a/src/core/libraries/ngs2/ngs2.h b/src/core/libraries/ngs2/ngs2.h new file mode 100644 index 00000000..0df83f56 --- /dev/null +++ b/src/core/libraries/ngs2/ngs2.h @@ -0,0 +1,72 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +#include +#include + +namespace Core::Loader { +class SymbolsResolver; +} + +namespace Libraries::Ngs2 { + +class Ngs2; + +using SceNgs2Handle = Ngs2*; + +enum SceNgs2HandleType { SCE_NGS2_HANDLE_TYPE_SYSTEM = 0 }; + +struct Ngs2Handle { + void* selfPointer; + void* dataPointer; + std::atomic* atomicPtr; + u32 handleType; + u32 flags_unk; + + u32 uid; + u16 maxGrainSamples; + u16 minGrainSamples; + u16 currentGrainSamples; + u16 numGrainSamples; + u16 unknown2; + u32 sampleRate; + u32 unknown3; + + void* flushMutex; + u32 flushMutexInitialized; + void* processMutex; + u32 processMutexInitialized; + + // Linked list pointers for system list + Ngs2Handle* prev; + Ngs2Handle* next; +}; + +struct SystemOptions { + char padding[6]; + s32 maxGrainSamples; + s32 numGrainSamples; + s32 sampleRate; +}; + +struct SystemState { + // TODO +}; + +struct StackBuffer { + void** top; + void* base; + void* curr; + size_t usedSize; + size_t totalSize; + size_t alignment; + char isVerifyEnabled; + char padding[7]; +}; + +void RegisterlibSceNgs2(Core::Loader::SymbolsResolver* sym); +} // namespace Libraries::Ngs2 \ No newline at end of file diff --git a/src/core/libraries/ngs2/ngs2_error.h b/src/core/libraries/ngs2/ngs2_error.h new file mode 100644 index 00000000..254ae26e --- /dev/null +++ b/src/core/libraries/ngs2/ngs2_error.h @@ -0,0 +1,56 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +constexpr int ORBIS_NGS2_ERROR_INVALID_PARAMETERS = 0x804A0001; +constexpr int ORBIS_NGS2_ERROR_INVALID_MAXIMUM_GRAIN_SAMPLES = 0x804A0050; +constexpr int ORBIS_NGS2_ERROR_INVALID_GRAIN_SAMPLES = 0x804A0051; +constexpr int ORBIS_NGS2_ERROR_INVALID_CHANNELS = 0x804A0052; +constexpr int ORBIS_NGS2_ERROR_INVALD_ADDRESS = 0x804A0053; +constexpr int ORBIS_NGS2_ERROR_INVALD_SIZE = 0x804A0054; +constexpr int ORBIS_NGS2_ERROR_INVALID_OPTION_SIZE = 0x804A0081; +constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_OPTION_MAX_MATRICES = 0x804A0100; +constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_OPTION_MAX_PORTS = 0x804A0101; +constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_OPTION_MAX_INPUT_DELAY_BLOCKS = 0x804A0102; +constexpr int ORBIS_NGS2_ERROR_INVALID_MATRIX_LEVELS = 0x804A0150; +constexpr int ORBIS_NGS2_ERROR_SAMPLER_WAVEFORM_TERMINATED = 0x804A0151; +constexpr int ORBIS_NGS2_ERROR_INVALID_ENVELOPE_POINTS = 0x804A0152; +constexpr int ORBIS_NGS2_ERROR_INVALID_MATRIX_LEVEL_ADDRESS = 0x804A0153; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_BLOCK_ADDRESS = 0x804A0154; +constexpr int ORBIS_NGS2_ERROR_INVALID_ENVELOPE_POINT_ADDRESS = 0x804A0155; +constexpr int ORBIS_NGS2_ERROR_INVALID_HANDLE = 0x804A0200; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLE_RATE = 0x804A0201; +constexpr int ORBIS_NGS2_ERROR_INVALID_REPORT_HANDLE = 0x804A0204; +constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_INFO = 0x804A0206; +constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_ADDRESS = 0x804A0207; +constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_ALIGNMENT = 0x804A0208; +constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_SIZE = 0x804A0209; +constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_ALLOCATOR = 0x804A020A; +constexpr int ORBIS_NGS2_ERROR_BUFFER_VERIFY_FAILED = 0x804A020B; +constexpr int ORBIS_NGS2_ERROR_MODULE_PLAYER_DATA_EMPTY = 0x804A020C; +constexpr int ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE = 0x804A0230; +constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_ID = 0x804A0260; +constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE = 0x804A0261; +constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE = 0x804A0300; +constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_INDEX = 0x804A0302; +constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_EVENT = 0x804A0303; +constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_PORT_INDEX = 0x804A0304; +constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_INPUT_OR_RACK_OCCUPIED = 0x804A0305; +constexpr int ORBIS_NGS2_ERROR_INVALID_CONTROL_ID = 0x804A0308; +constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_CONTROL_PARAMETER = 0x804A0309; +constexpr int ORBIS_NGS2_ERROR_INVALID_PARAMETER_SIZE = 0x804A030A; +constexpr int ORBIS_NGS2_ERROR_DETECTED_CIRCULAR_VOICE_CONTROL = 0x804A030B; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_DATA = 0x804A0400; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_FORMAT = 0x804A0401; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_TYPE_NO_ATRAC9_DECODERS = 0x804A0402; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_ATRAC9_CONFIG_DATA = 0x804A0403; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_SAMPLE_RATE = 0x804A0404; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_FRAME = 0x804A0405; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_ADDRESS = 0x804A0406; +constexpr int ORBIS_NGS2_ERROR_INVALID_ENVELOPE_CURVE = 0x804A0500; +constexpr int ORBIS_NGS2_ERROR_INVALID_FILTER_INDEX = 0x804A0600; +constexpr int ORBIS_NGS2_ERROR_INVALID_FILTER_TYPE = 0x804A0601; +constexpr int ORBIS_NGS2_ERROR_INVALID_FILTER_LOCATION = 0x804A0602; +constexpr int ORBIS_NGS2_ERROR_INVALID_LFE_CUT_OFF_FREQUENCY = 0x804A0603; +constexpr int ORBIS_NGS2_ERROR_INVALID_MATRIX_INDEX_OR_TYPE = 0x804A0700; \ No newline at end of file diff --git a/src/core/libraries/ngs2/ngs2_impl.cpp b/src/core/libraries/ngs2/ngs2_impl.cpp new file mode 100644 index 00000000..185be94d --- /dev/null +++ b/src/core/libraries/ngs2/ngs2_impl.cpp @@ -0,0 +1,163 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "ngs2_error.h" +#include "ngs2_impl.h" + +#include "common/logging/log.h" +#include "core/libraries/error_codes.h" +#include "core/libraries/kernel/libkernel.h" + +using namespace Libraries::Kernel; + +namespace Libraries::Ngs2 { + +s32 Ngs2::ReportInvalid(u32 handle_type) const { + switch (handle_type) { + case 1: + LOG_ERROR(Lib_Ngs2, "Invalid system handle {}", this); + return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE; + case 2: + LOG_ERROR(Lib_Ngs2, "Invalid rack handle {}", this); + return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE; + case 4: + LOG_ERROR(Lib_Ngs2, "Invalid voice handle {}", this); + return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE; + case 8: + LOG_ERROR(Lib_Ngs2, "Invalid report handle {}", this); + return ORBIS_NGS2_ERROR_INVALID_REPORT_HANDLE; + default: + LOG_ERROR(Lib_Ngs2, "Invalid handle {}", this); + return ORBIS_NGS2_ERROR_INVALID_HANDLE; + } +} + +s32 Ngs2::HandleSetup(Ngs2Handle* handle, void* data, std::atomic* atomic, u32 type, + u32 flags) { + handle->dataPointer = data; + handle->atomicPtr = atomic; + handle->handleType = type; + handle->flags_unk = flags; + return ORBIS_OK; +} + +s32 Ngs2::HandleCleanup(Ngs2Handle* handle, u32 hType, void* dataOut) { + if (handle && handle->selfPointer == handle) { + std::atomic* tmp_atomic = handle->atomicPtr; + if (tmp_atomic && handle->handleType == hType) { + while (tmp_atomic->load() != 0) { + u32 expected = 1; + if (tmp_atomic->compare_exchange_strong(expected, 0)) { + if (dataOut) { + dataOut = handle->dataPointer; + } + // sceNgs2MemoryClear(handle, 32); + return ORBIS_OK; + } + tmp_atomic = handle->atomicPtr; + } + } + } + return HandleReportInvalid(handle, hType); +} + +s32 Ngs2::HandleEnter(Ngs2Handle* handle, u32 hType, Ngs2Handle* handleOut) { + if (!handle) { + return HandleReportInvalid(handle, 0); + } + + if (handle->selfPointer != handle || !handle->atomicPtr || !handle->dataPointer || + (~hType & handle->handleType)) { + return HandleReportInvalid(handle, handle->handleType); + } + + std::atomic* atomic = handle->atomicPtr; + while (true) { + u32 i = atomic->load(); + if (i == 0) { + return HandleReportInvalid(handle, handle->handleType); + } + if (atomic->compare_exchange_strong(i, i + 1)) { + break; + } + } + + if (handleOut) { + *handleOut = handle; + } + return ORBIS_OK; +} + +s32 Ngs2::HandleLeave(Ngs2Handle* handle) { + std::atomic* tmp_atomic; + u32 i; + do { + tmp_atomic = handle->atomicPtr; + i = tmp_atomic->load(); + } while (!tmp_atomic->compare_exchange_strong(i, i - 1)); + return ORBIS_OK; +} + +s32 Ngs2::StackBufferOpen(StackBuffer* buf, void* base_addr, size_t size, void** stackTop, + bool verify) { + buf->top = stackTop; + buf->base = base_addr; + buf->curr = base_addr; + buf->usedSize = 0; + buf->totalSize = size; + buf->alignment = 8; + buf->isVerifyEnabled = verify; + + if (stackTop) { + *stackTop = nullptr; + } + + return ORBIS_OK; +} + +s32 Ngs2::StackBufferClose(StackBuffer* buf, size_t* usedSize) { + if (usedSize) { + *usedSize = buf->usedSize + buf->alignment; + } + + return ORBIS_OK; +} + +s32 Ngs2::SystemSetupCore(StackBuffer* buf, SystemOptions* options, Ngs2Handle** sysOut) { + u32 maxGrainSamples = 512; + u32 numGrainSamples = 256; + u32 sampleRate = 48000; + + if (options) { + maxGrainSamples = options->maxGrainSamples; + numGrainSamples = options->numGrainSamples; + sampleRate = options->sampleRate; + } + + // Validate maxGrainSamples + if (maxGrainSamples < 64 || maxGrainSamples > 1024 || (maxGrainSamples & 0x3F) != 0) { + LOG_ERROR(Lib_Ngs2, "Invalid system option (maxGrainSamples={},x64)", maxGrainSamples); + return ORBIS_NGS2_ERROR_INVALID_MAXIMUM_GRAIN_SAMPLES; + } + + // Validate numGrainSamples + if (numGrainSamples < 64 || numGrainSamples > 1024 || (numGrainSamples & 0x3F) != 0) { + LOG_ERROR(Lib_Ngs2, "Invalid system option (numGrainSamples={},x64)", numGrainSamples); + return ORBIS_NGS2_ERROR_INVALID_GRAIN_SAMPLES; + } + + // Validate sampleRate + if (sampleRate != 11025 && sampleRate != 12000 && sampleRate != 22050 && sampleRate != 24000 && + sampleRate != 44100 && sampleRate != 48000 && sampleRate != 88200 && sampleRate != 96000) { + LOG_ERROR(Lib_Ngs2, "Invalid system option(sampleRate={}:44.1/48kHz series)", sampleRate); + return ORBIS_NGS2_ERROR_INVALID_SAMPLE_RATE; + } + + int result = ORBIS_OK; + + // TODO + + return result; // Success +} + +} // namespace Libraries::Ngs2 diff --git a/src/core/libraries/ngs2/ngs2_impl.h b/src/core/libraries/ngs2/ngs2_impl.h new file mode 100644 index 00000000..36001779 --- /dev/null +++ b/src/core/libraries/ngs2/ngs2_impl.h @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "ngs2.h" + +namespace Libraries::Ngs2 { + +class Ngs2 { +public: + s32 ReportInvalid(u32 handle_type) const; + s32 HandleSetup(Ngs2Handle* handle, void* data, std::atomic* atomic, u32 type, u32 flags); + s32 HandleCleanup(Ngs2Handle* handle, u32 hType, void* dataOut); + s32 HandleEnter(Ngs2Handle* handle, u32 hType, Ngs2Handle* handleOut); + s32 HandleLeave(Ngs2Handle* handle); + s32 StackBufferOpen(StackBuffer* buf, void* base_addr, size_t size, void** stackTop, + bool verify); + s32 StackBufferClose(StackBuffer* buf, size_t* usedSize); + s32 SystemSetupCore(StackBuffer* buf, SystemOptions* options, Ngs2Handle** sysOut); + +private: +}; + +} // namespace Libraries::Ngs2 diff --git a/src/emulator.cpp b/src/emulator.cpp index 4990b4aa..12e89349 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -22,6 +22,7 @@ #include "core/libraries/libc/libc.h" #include "core/libraries/libc_internal/libc_internal.h" #include "core/libraries/libs.h" +#include "core/libraries/ngs2/ngs2.h" #include "core/libraries/rtc/rtc.h" #include "core/libraries/videoout/video_out.h" #include "core/linker.h" @@ -184,7 +185,7 @@ void Emulator::Run(const std::filesystem::path& file) { void Emulator::LoadSystemModules(const std::filesystem::path& file) { constexpr std::array ModulesToLoad{ - {{"libSceNgs2.sprx", nullptr}, + {{"libSceNgs2.sprx", &Libraries::Ngs2::RegisterlibSceNgs2}, {"libSceFiber.sprx", nullptr}, {"libSceUlt.sprx", nullptr}, {"libSceJson.sprx", nullptr}, From 1f416134e7f2d23d90dcb9713661c58dd0bfb0d9 Mon Sep 17 00:00:00 2001 From: Dzmitry Dubrova Date: Mon, 19 Aug 2024 15:29:13 +0300 Subject: [PATCH 10/12] Add messages to asserts (#476) --- src/core/address_space.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index 91c8b7a1..77d021a6 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -98,7 +98,7 @@ struct AddressSpace::Impl { backing_handle = CreateFileMapping2(INVALID_HANDLE_VALUE, nullptr, FILE_MAP_WRITE | FILE_MAP_READ, PAGE_READWRITE, SEC_COMMIT, BackingSize, nullptr, nullptr, 0); - ASSERT(backing_handle); + ASSERT_MSG(backing_handle, "{}", Common::GetLastErrorMsg()); // Allocate a virtual memory for the backing file map as placeholder backing_base = static_cast(VirtualAlloc2(process, nullptr, BackingSize, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, @@ -106,7 +106,7 @@ struct AddressSpace::Impl { // Map backing placeholder. This will commit the pages void* const ret = MapViewOfFile3(backing_handle, process, backing_base, 0, BackingSize, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, nullptr, 0); - ASSERT(ret == backing_base); + ASSERT_MSG(ret == backing_base, "{}", Common::GetLastErrorMsg()); } ~Impl() { From 9d45b991712a491cfef3fcea709411876eb468fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A5IGA?= <164882787+Xphalnos@users.noreply.github.com> Date: Mon, 19 Aug 2024 17:42:23 +0200 Subject: [PATCH 11/12] Adding icons to categories (#479) --- .reuse/dep5 | 1 + src/images/about_icon.png | Bin 0 -> 8462 bytes src/qt_gui/main_window.cpp | 4 ++++ src/qt_gui/main_window_ui.h | 4 ++++ src/shadps4.qrc | 1 + 5 files changed, 10 insertions(+) create mode 100644 src/images/about_icon.png diff --git a/.reuse/dep5 b/.reuse/dep5 index a80001f8..0140c0c0 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -15,6 +15,7 @@ Files: CMakeSettings.json documents/Screenshots/Undertale.png documents/Screenshots/We are DOOMED.png scripts/ps4_names.txt + src/images/about_icon.png src/images/controller_icon.png src/images/exit_icon.png src/images/file_icon.png diff --git a/src/images/about_icon.png b/src/images/about_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bbb517982e77db1b4ca6ee72633932c2d8530e80 GIT binary patch literal 8462 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 literal 0 HcmV?d00001 diff --git a/src/qt_gui/main_window.cpp b/src/qt_gui/main_window.cpp index 653987b5..d00a6ef6 100644 --- a/src/qt_gui/main_window.cpp +++ b/src/qt_gui/main_window.cpp @@ -702,7 +702,9 @@ QIcon MainWindow::RecolorIcon(const QIcon& icon, bool isWhite) { void MainWindow::SetUiIcons(bool isWhite) { ui->bootInstallPkgAct->setIcon(RecolorIcon(ui->bootInstallPkgAct->icon(), isWhite)); + ui->bootGameAct->setIcon(RecolorIcon(ui->bootGameAct->icon(), isWhite)); ui->exitAct->setIcon(RecolorIcon(ui->exitAct->icon(), isWhite)); + ui->aboutAct->setIcon(RecolorIcon(ui->aboutAct->icon(), isWhite)); ui->setlistModeListAct->setIcon(RecolorIcon(ui->setlistModeListAct->icon(), isWhite)); ui->setlistModeGridAct->setIcon(RecolorIcon(ui->setlistModeGridAct->icon(), isWhite)); ui->gameInstallPathAct->setIcon(RecolorIcon(ui->gameInstallPathAct->icon(), isWhite)); @@ -716,6 +718,8 @@ void MainWindow::SetUiIcons(bool isWhite) { ui->refreshGameListAct->setIcon(RecolorIcon(ui->refreshGameListAct->icon(), isWhite)); ui->menuGame_List_Mode->setIcon(RecolorIcon(ui->menuGame_List_Mode->icon(), isWhite)); ui->pkgViewerAct->setIcon(RecolorIcon(ui->pkgViewerAct->icon(), isWhite)); + ui->configureAct->setIcon(RecolorIcon(ui->configureAct->icon(), isWhite)); + ui->addElfFolderAct->setIcon(RecolorIcon(ui->addElfFolderAct->icon(), isWhite)); } void MainWindow::resizeEvent(QResizeEvent* event) { diff --git a/src/qt_gui/main_window_ui.h b/src/qt_gui/main_window_ui.h index f8de3076..7d0c58dd 100644 --- a/src/qt_gui/main_window_ui.h +++ b/src/qt_gui/main_window_ui.h @@ -98,8 +98,10 @@ public: bootInstallPkgAct->setIcon(QIcon(":images/file_icon.png")); bootGameAct = new QAction(MainWindow); bootGameAct->setObjectName("bootGameAct"); + bootGameAct->setIcon(QIcon(":images/play_icon.png")); addElfFolderAct = new QAction(MainWindow); addElfFolderAct->setObjectName("addElfFolderAct"); + addElfFolderAct->setIcon(QIcon(":images/folder_icon.png")); exitAct = new QAction(MainWindow); exitAct->setObjectName("exitAct"); exitAct->setIcon(QIcon(":images/exit_icon.png")); @@ -144,8 +146,10 @@ public: pkgViewerAct->setIcon(QIcon(":images/file_icon.png")); aboutAct = new QAction(MainWindow); aboutAct->setObjectName("aboutAct"); + aboutAct->setIcon(QIcon(":images/about_icon.png")); configureAct = new QAction(MainWindow); configureAct->setObjectName("configureAct"); + configureAct->setIcon(QIcon(":images/settings_icon.png")); setThemeDark = new QAction(MainWindow); setThemeDark->setObjectName("setThemeDark"); setThemeDark->setCheckable(true); diff --git a/src/shadps4.qrc b/src/shadps4.qrc index cdbae786..c22b837b 100644 --- a/src/shadps4.qrc +++ b/src/shadps4.qrc @@ -1,6 +1,7 @@ images/shadps4.ico + images/about_icon.png images/play_icon.png images/pause_icon.png images/stop_icon.png From 09da94b7b28a64c17a229324bc9a87aac5964b16 Mon Sep 17 00:00:00 2001 From: Random <28494085+Random06457@users.noreply.github.com> Date: Mon, 19 Aug 2024 17:45:42 +0200 Subject: [PATCH 12/12] fix gcc compilation error in vk_graphics_pipeline.cpp (#477) gcc fails to infer the type of the two parts of a ternary expression whose types are different but both contain an implicit cast operator to the same type --- .../renderer_vulkan/vk_graphics_pipeline.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 2d502737..04486290 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -173,16 +173,17 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul }, .back{ .failOp = LiverpoolToVK::StencilOp(key.depth.backface_enable - ? key.stencil.stencil_fail_back - : key.stencil.stencil_fail_front), + ? key.stencil.stencil_fail_back.Value() + : key.stencil.stencil_fail_front.Value()), .passOp = LiverpoolToVK::StencilOp(key.depth.backface_enable - ? key.stencil.stencil_zpass_back - : key.stencil.stencil_zpass_front), + ? key.stencil.stencil_zpass_back.Value() + : key.stencil.stencil_zpass_front.Value()), .depthFailOp = LiverpoolToVK::StencilOp(key.depth.backface_enable - ? key.stencil.stencil_zfail_back - : key.stencil.stencil_zfail_front), - .compareOp = LiverpoolToVK::CompareOp( - key.depth.backface_enable ? key.depth.stencil_bf_func : key.depth.stencil_ref_func), + ? key.stencil.stencil_zfail_back.Value() + : key.stencil.stencil_zfail_front.Value()), + .compareOp = LiverpoolToVK::CompareOp(key.depth.backface_enable + ? key.depth.stencil_bf_func.Value() + : key.depth.stencil_ref_func.Value()), .compareMask = key.stencil_ref_back.stencil_mask, .writeMask = key.stencil_ref_back.stencil_write_mask, .reference = key.stencil_ref_back.stencil_test_val,