diff --git a/src/core/file_sys/fs.cpp b/src/core/file_sys/fs.cpp index 3177770b0..2bcff191c 100644 --- a/src/core/file_sys/fs.cpp +++ b/src/core/file_sys/fs.cpp @@ -70,7 +70,7 @@ std::filesystem::path MntPoints::GetHostPath(const std::string& guest_directory) // exist in filesystem but in different case. auto guest_path = current_path; while (!path_parts.empty()) { - const auto& part = path_parts.back(); + const auto part = path_parts.back(); const auto add_match = [&](const auto& host_part) { current_path /= host_part; guest_path /= part; diff --git a/src/core/libraries/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index 4a42b0d6f..f83863479 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -472,6 +472,28 @@ s64 PS4_SYSV_ABI sceKernelPwrite(int d, void* buf, size_t nbytes, s64 offset) { return file->f.WriteRaw(buf, nbytes); } +s32 PS4_SYSV_ABI sceKernelRename(const char* from, const char* to) { + auto* mnt = Common::Singleton::Instance(); + const auto src_path = mnt->GetHostPath(from); + if (!std::filesystem::exists(src_path)) { + return ORBIS_KERNEL_ERROR_ENOENT; + } + const auto dst_path = mnt->GetHostPath(to); + const bool src_is_dir = std::filesystem::is_directory(src_path); + const bool dst_is_dir = std::filesystem::is_directory(dst_path); + if (src_is_dir && !dst_is_dir) { + return ORBIS_KERNEL_ERROR_ENOTDIR; + } + if (!src_is_dir && dst_is_dir) { + return ORBIS_KERNEL_ERROR_EISDIR; + } + if (dst_is_dir && !std::filesystem::is_empty(dst_path)) { + return ORBIS_KERNEL_ERROR_ENOTEMPTY; + } + std::filesystem::copy(src_path, dst_path, std::filesystem::copy_options::overwrite_existing); + return ORBIS_OK; +} + void fileSystemSymbolsRegister(Core::Loader::SymbolsResolver* sym) { std::srand(std::time(nullptr)); LIB_FUNCTION("1G3lF1Gg1k8", "libkernel", 1, "libkernel", 1, 1, sceKernelOpen); @@ -493,6 +515,7 @@ void fileSystemSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("kBwCPsYX-m4", "libkernel", 1, "libkernel", 1, 1, sceKernelFStat); LIB_FUNCTION("mqQMh1zPPT8", "libScePosix", 1, "libkernel", 1, 1, posix_fstat); LIB_FUNCTION("VW3TVZiM4-E", "libkernel", 1, "libkernel", 1, 1, sceKernelFtruncate); + LIB_FUNCTION("52NcYU9+lEo", "libkernel", 1, "libkernel", 1, 1, sceKernelRename); LIB_FUNCTION("E6ao34wPw+U", "libScePosix", 1, "libkernel", 1, 1, posix_stat); LIB_FUNCTION("+r3rMFwItV4", "libkernel", 1, "libkernel", 1, 1, sceKernelPread); diff --git a/src/core/libraries/kernel/thread_management.cpp b/src/core/libraries/kernel/thread_management.cpp index d5e2adead..eeaa1db97 100644 --- a/src/core/libraries/kernel/thread_management.cpp +++ b/src/core/libraries/kernel/thread_management.cpp @@ -555,14 +555,16 @@ int PS4_SYSV_ABI scePthreadMutexLock(ScePthreadMutex* mutex) { return SCE_KERNEL_ERROR_EINVAL; } - (*mutex)->tracy_lock->BeforeLock(); + if (mutex) { + (*mutex)->tracy_lock->BeforeLock(); + } int result = pthread_mutex_lock(&(*mutex)->pth_mutex); if (result != 0) { LOG_TRACE(Kernel_Pthread, "Locked name={}, result={}", (*mutex)->name, result); } - (*mutex)->tracy_lock->AfterLock(); + //(*mutex)->tracy_lock->AfterLock(); switch (result) { case 0: @@ -589,7 +591,7 @@ int PS4_SYSV_ABI scePthreadMutexUnlock(ScePthreadMutex* mutex) { LOG_TRACE(Kernel_Pthread, "Unlocking name={}, result={}", (*mutex)->name, result); } - (*mutex)->tracy_lock->AfterUnlock(); + //(*mutex)->tracy_lock->AfterUnlock(); switch (result) { case 0: diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index b499ed3f9..c70427635 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp @@ -205,8 +205,8 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) { } else { ctx.AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft); } + ctx.AddCapability(spv::Capability::GroupNonUniform); if (info.uses_group_quad) { - ctx.AddCapability(spv::Capability::GroupNonUniform); ctx.AddCapability(spv::Capability::GroupNonUniformQuad); } if (info.has_discard) { 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 d7f972ec1..02480303f 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 @@ -120,6 +120,7 @@ void EmitGetGotoVariable(EmitContext&) { } Id EmitReadConst(EmitContext& ctx) { + return ctx.u32_zero_value; UNREACHABLE_MSG("Unreachable instruction"); } diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index 28da6ed56..030d39485 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp @@ -70,7 +70,6 @@ Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id o const u32 comp = inst->Flags().gather_comp.Value(); ImageOperands operands; operands.Add(spv::ImageOperandsMask::Offset, offset); - operands.Add(spv::ImageOperandsMask::Lod, ctx.ConstF32(0.f)); return ctx.OpImageGather(ctx.F32[4], sampled_image, coords, ctx.ConstU32(comp), operands.mask, operands.operands); } diff --git a/src/shader_recompiler/frontend/translate/translate.cpp b/src/shader_recompiler/frontend/translate/translate.cpp index 25cc55863..9698aed82 100644 --- a/src/shader_recompiler/frontend/translate/translate.cpp +++ b/src/shader_recompiler/frontend/translate/translate.cpp @@ -94,29 +94,29 @@ IR::U32F32 Translator::GetSrc(const InstOperand& operand, bool force_flt) { } break; case OperandField::ConstZero: - if (force_flt) { + if (is_float) { value = ir.Imm32(0.f); } else { value = ir.Imm32(0U); } break; case OperandField::SignedConstIntPos: - ASSERT(!force_flt); + ASSERT(!is_float); value = ir.Imm32(operand.code - SignedConstIntPosMin + 1); break; case OperandField::SignedConstIntNeg: - ASSERT(!force_flt); + ASSERT(!is_float); value = ir.Imm32(-s32(operand.code) + SignedConstIntNegMin - 1); break; case OperandField::LiteralConst: - if (force_flt) { + if (is_float) { value = ir.Imm32(std::bit_cast(operand.code)); } else { value = ir.Imm32(operand.code); } break; case OperandField::ConstFloatPos_1_0: - if (force_flt) { + if (is_float) { value = ir.Imm32(1.f); } else { value = ir.Imm32(std::bit_cast(1.f)); @@ -135,7 +135,11 @@ IR::U32F32 Translator::GetSrc(const InstOperand& operand, bool force_flt) { value = ir.Imm32(-0.5f); break; case OperandField::ConstFloatNeg_1_0: - value = ir.Imm32(-1.0f); + if (is_float) { + value = ir.Imm32(-1.0f); + } else { + value = ir.Imm32(std::bit_cast(-1.0f)); + } break; case OperandField::ConstFloatNeg_2_0: value = ir.Imm32(-2.0f); @@ -157,6 +161,8 @@ IR::U32F32 Translator::GetSrc(const InstOperand& operand, bool force_flt) { value = ir.GetVccHi(); } break; + case OperandField::M0: + return m0_value; default: UNREACHABLE(); } @@ -333,6 +339,7 @@ void Translator::SetDst(const InstOperand& operand, const IR::U32F32& value) { case OperandField::VccHi: return ir.SetVccHi(result); case OperandField::M0: + m0_value = result; break; default: UNREACHABLE(); diff --git a/src/shader_recompiler/frontend/translate/translate.h b/src/shader_recompiler/frontend/translate/translate.h index 87f376d29..4897321d1 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -222,6 +222,7 @@ private: IR::IREmitter ir; Info& info; const Profile& profile; + IR::U32 m0_value; bool opcode_missing = false; }; diff --git a/src/shader_recompiler/frontend/translate/vector_memory.cpp b/src/shader_recompiler/frontend/translate/vector_memory.cpp index 1403fc8b2..dd4912331 100644 --- a/src/shader_recompiler/frontend/translate/vector_memory.cpp +++ b/src/shader_recompiler/frontend/translate/vector_memory.cpp @@ -244,7 +244,7 @@ void Translator::IMAGE_GATHER(const GcnInst& inst) { info.has_bias.Assign(flags.test(MimgModifier::LodBias)); info.has_lod_clamp.Assign(flags.test(MimgModifier::LodClamp)); info.force_level0.Assign(flags.test(MimgModifier::Level0)); - info.explicit_lod.Assign(explicit_lod); + //info.explicit_lod.Assign(explicit_lod); info.gather_comp.Assign(std::bit_width(mimg.dmask) - 1); // Issue IR instruction, leaving unknown fields blank to patch later.