From 815ce11d2b679627283e1d37c48b10d019b1b051 Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Wed, 17 Jul 2024 14:46:37 +0300 Subject: [PATCH 01/12] fs: Defeat games with double slashes --- src/core/file_sys/fs.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/file_sys/fs.cpp b/src/core/file_sys/fs.cpp index c6bdf7ad..2f57c9f3 100644 --- a/src/core/file_sys/fs.cpp +++ b/src/core/file_sys/fs.cpp @@ -37,7 +37,11 @@ std::filesystem::path MntPoints::GetHostPath(const std::string& guest_directory) } // Remove device (e.g /app0) from path to retrieve relative path. - const u32 pos = mount->mount.size() + 1; + u32 pos = mount->mount.size() + 1; + // Evil games like Turok2 pass double slashes e.g /app0//game.kpf + if (guest_directory[pos] == '/') { + pos++; + } const auto rel_path = std::string_view(guest_directory).substr(pos); const auto host_path = mount->host_path / rel_path; if (!NeedsCaseInsensiveSearch) { From c64694c6734a5158faacda4e2c49669383aee611 Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Wed, 17 Jul 2024 14:48:30 +0300 Subject: [PATCH 02/12] gnmdriver: Fix incorrect trailing nop insertion in indirect draws --- src/core/libraries/gnmdriver/gnmdriver.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index 26b71eb4..37403d13 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -649,6 +649,7 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexIndirect(u32* cmdbuf, u32 size, u32 data_offset, cmdbuf[2] = instance_vgpr_offset == 0 ? 0 : (instance_vgpr_offset & 0xffffu) + sgpr_offset; cmdbuf[3] = 0; + cmdbuf += 4; WriteTrailingNop<3>(cmdbuf); return ORBIS_OK; } @@ -704,6 +705,7 @@ s32 PS4_SYSV_ABI sceGnmDrawIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 cmdbuf[2] = instance_vgpr_offset == 0 ? 0 : (instance_vgpr_offset & 0xffffu) + sgpr_offset; cmdbuf[3] = 2; // auto index + cmdbuf += 4; WriteTrailingNop<3>(cmdbuf); return ORBIS_OK; } From b6f011c8f68c2919725ed992d3cd6219c483746b Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Wed, 17 Jul 2024 14:50:26 +0300 Subject: [PATCH 03/12] event_queue: Add clear flag to events and don't return error --- src/core/libraries/gnmdriver/gnmdriver.cpp | 2 +- src/core/libraries/kernel/event_queue.cpp | 2 +- src/core/libraries/videoout/video_out.cpp | 8 ++++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index 37403d13..77a13800 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -346,7 +346,7 @@ s32 PS4_SYSV_ABI sceGnmAddEqEvent(SceKernelEqueue eq, u64 id, void* udata) { EqueueEvent kernel_event{}; kernel_event.event.ident = id; kernel_event.event.filter = SceKernelEvent::Filter::GraphicsCore; - kernel_event.event.flags = SceKernelEvent::Flags::Add; + kernel_event.event.flags = SceKernelEvent::Flags::Clear; kernel_event.event.fflags = 0; kernel_event.event.data = id; kernel_event.event.udata = udata; diff --git a/src/core/libraries/kernel/event_queue.cpp b/src/core/libraries/kernel/event_queue.cpp index 18561d6b..7d5163cf 100644 --- a/src/core/libraries/kernel/event_queue.cpp +++ b/src/core/libraries/kernel/event_queue.cpp @@ -94,7 +94,7 @@ int EqueueInternal::GetTriggeredEvents(SceKernelEvent* ev, int num) { for (auto& event : m_events) { if (event.IsTriggered()) { - if (ev->flags & SceKernelEvent::Flags::Clear) { + if (event.event.flags & SceKernelEvent::Flags::Clear) { event.Reset(); } diff --git a/src/core/libraries/videoout/video_out.cpp b/src/core/libraries/videoout/video_out.cpp index 51cfcf4c..826b2247 100644 --- a/src/core/libraries/videoout/video_out.cpp +++ b/src/core/libraries/videoout/video_out.cpp @@ -50,13 +50,15 @@ s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(Kernel::SceKernelEqueue eq, s32 handle, Kernel::EqueueEvent event{}; event.event.ident = SCE_VIDEO_OUT_EVENT_FLIP; event.event.filter = Kernel::SceKernelEvent::Filter::VideoOut; + event.event.flags = Kernel::SceKernelEvent::Flags::Clear; event.event.udata = udata; event.event.fflags = 0; event.event.data = 0; event.data = port; + eq->AddEvent(event); port->flip_events.push_back(eq); - return eq->AddEvent(event); + return ORBIS_OK; } s32 PS4_SYSV_ABI sceVideoOutAddVblankEvent(Kernel::SceKernelEqueue eq, s32 handle, void* udata) { @@ -74,13 +76,15 @@ s32 PS4_SYSV_ABI sceVideoOutAddVblankEvent(Kernel::SceKernelEqueue eq, s32 handl Kernel::EqueueEvent event{}; event.event.ident = SCE_VIDEO_OUT_EVENT_VBLANK; event.event.filter = Kernel::SceKernelEvent::Filter::VideoOut; + event.event.flags = Kernel::SceKernelEvent::Flags::Clear; event.event.udata = udata; event.event.fflags = 0; event.event.data = 0; event.data = port; + eq->AddEvent(event); port->vblank_events.push_back(eq); - return eq->AddEvent(event); + return ORBIS_OK; } s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* const* addresses, From 0408d8596def4f6a2feea5b7f90ab94d768fdbb2 Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Wed, 17 Jul 2024 15:37:32 +0300 Subject: [PATCH 04/12] emulator: Add libSceFiber and simplify logic --- src/emulator.cpp | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/src/emulator.cpp b/src/emulator.cpp index a60aea1b..3f674cf6 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -148,39 +148,35 @@ void Emulator::Run(const std::filesystem::path& file) { } void Emulator::LoadSystemModules(const std::filesystem::path& file) { - constexpr std::array ModulesToLoad{ + constexpr std::array ModulesToLoad{ {{"libSceNgs2.sprx", nullptr}, + {"libSceFiber.sprx", nullptr}, {"libSceLibcInternal.sprx", &Libraries::LibcInternal::RegisterlibSceLibcInternal}, {"libSceDiscMap.sprx", &Libraries::DiscMap::RegisterlibSceDiscMap}, {"libSceRtc.sprx", &Libraries::Rtc::RegisterlibSceRtc}, {"libSceJpegEnc.sprx", nullptr}, - {"libSceJson2.sprx", nullptr}}}; + {"libSceJson2.sprx", nullptr}}, + }; std::vector found_modules; const auto& sys_module_path = Common::FS::GetUserPath(Common::FS::PathType::SysModuleDir); for (const auto& entry : std::filesystem::directory_iterator(sys_module_path)) { found_modules.push_back(entry.path()); } - for (auto it : ModulesToLoad) { - bool found = false; - std::filesystem::path foundpath; - for (auto f : found_modules) { - if (f.filename().string() == it.module_name) { - found = true; - foundpath = f; - break; - } + for (const auto& [module_name, init_func] : ModulesToLoad) { + const auto it = std::ranges::find_if(found_modules, [&](const auto& path) { + return path.filename() == module_name; + }); + if (it != found_modules.end()) { + LOG_INFO(Loader, "Loading {}", it->string()); + linker->LoadModule(*it); + continue; } - if (found) { - LOG_INFO(Loader, "Loading {}", foundpath.string().c_str()); - linker->LoadModule(foundpath); + if (init_func) { + LOG_INFO(Loader, "Can't Load {} switching to HLE", module_name); + init_func(&linker->GetHLESymbols()); } else { - if (it.callback != nullptr) { - LOG_INFO(Loader, "Can't Load {} switching to HLE", it.module_name); - it.callback(&linker->GetHLESymbols()); - } else { - LOG_INFO(Loader, "No HLE available for {} module", it.module_name); - } + LOG_INFO(Loader, "No HLE available for {} module", module_name); } } } From b89941fbd9b0045888c32f9bf0260c1d6357ab0e Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Wed, 17 Jul 2024 15:44:20 +0300 Subject: [PATCH 05/12] emulator: Add libSceUlt too --- src/emulator.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/emulator.cpp b/src/emulator.cpp index 3f674cf6..9eafe7a6 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -148,9 +148,10 @@ void Emulator::Run(const std::filesystem::path& file) { } void Emulator::LoadSystemModules(const std::filesystem::path& file) { - constexpr std::array ModulesToLoad{ + constexpr std::array ModulesToLoad{ {{"libSceNgs2.sprx", nullptr}, {"libSceFiber.sprx", nullptr}, + {"libSceUlt.sprx", nullptr}, {"libSceLibcInternal.sprx", &Libraries::LibcInternal::RegisterlibSceLibcInternal}, {"libSceDiscMap.sprx", &Libraries::DiscMap::RegisterlibSceDiscMap}, {"libSceRtc.sprx", &Libraries::Rtc::RegisterlibSceRtc}, From 01dc7f5bfca2550cd69cd04f0be21fca253f9ba9 Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Wed, 17 Jul 2024 15:52:40 +0300 Subject: [PATCH 06/12] Add comments --- src/core/libraries/gnmdriver/gnmdriver.cpp | 1 + src/core/libraries/videoout/video_out.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index 77a13800..ead4ff23 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -346,6 +346,7 @@ s32 PS4_SYSV_ABI sceGnmAddEqEvent(SceKernelEqueue eq, u64 id, void* udata) { EqueueEvent kernel_event{}; kernel_event.event.ident = id; kernel_event.event.filter = SceKernelEvent::Filter::GraphicsCore; + // The library only sets EV_ADD but it is suspected the kernel driver forces EV_CLEAR kernel_event.event.flags = SceKernelEvent::Flags::Clear; kernel_event.event.fflags = 0; kernel_event.event.data = id; diff --git a/src/core/libraries/videoout/video_out.cpp b/src/core/libraries/videoout/video_out.cpp index 826b2247..8fbd69c4 100644 --- a/src/core/libraries/videoout/video_out.cpp +++ b/src/core/libraries/videoout/video_out.cpp @@ -50,6 +50,7 @@ s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(Kernel::SceKernelEqueue eq, s32 handle, Kernel::EqueueEvent event{}; event.event.ident = SCE_VIDEO_OUT_EVENT_FLIP; event.event.filter = Kernel::SceKernelEvent::Filter::VideoOut; + // The library only sets EV_ADD but kernel driver forces EV_CLEAR event.event.flags = Kernel::SceKernelEvent::Flags::Clear; event.event.udata = udata; event.event.fflags = 0; @@ -76,6 +77,7 @@ s32 PS4_SYSV_ABI sceVideoOutAddVblankEvent(Kernel::SceKernelEqueue eq, s32 handl Kernel::EqueueEvent event{}; event.event.ident = SCE_VIDEO_OUT_EVENT_VBLANK; event.event.filter = Kernel::SceKernelEvent::Filter::VideoOut; + // The library only sets EV_ADD but kernel driver forces EV_CLEAR event.event.flags = Kernel::SceKernelEvent::Flags::Clear; event.event.udata = udata; event.event.fflags = 0; From fcbaec51df8d75b7ba23f30534235768956777ce Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Wed, 17 Jul 2024 16:19:08 +0300 Subject: [PATCH 07/12] liverpool_to_vk: Add more surface formats --- src/video_core/renderer_vulkan/liverpool_to_vk.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp index 4280e6e6..0cbe0de8 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp @@ -441,6 +441,18 @@ vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat nu num_format == AmdGpu::NumberFormat::Unorm) { return vk::Format::eR16G16B16A16Unorm; } + if (data_format == AmdGpu::DataFormat::Format8 && + num_format == AmdGpu::NumberFormat::Uint) { + return vk::Format::eR8Uint; + } + if (data_format == AmdGpu::DataFormat::Format16_16_16_16 && + num_format == AmdGpu::NumberFormat::SnormNz) { + return vk::Format::eR16G16B16A16Snorm; + } + if (data_format == AmdGpu::DataFormat::FormatBc6 && + num_format == AmdGpu::NumberFormat::Unorm) { + return vk::Format::eBc6HUfloatBlock; + } UNREACHABLE_MSG("Unknown data_format={} and num_format={}", u32(data_format), u32(num_format)); } From 53fb73e95fbbe5376208f556161cbe5b6cdc5de2 Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Wed, 17 Jul 2024 16:22:04 +0300 Subject: [PATCH 08/12] rasterizer: Bump staging to 1GB * Less chances of crashing --- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index d0944fcc..fff9bc33 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -23,7 +23,7 @@ Rasterizer::Rasterizer(const Instance& instance_, Scheduler& scheduler_, : instance{instance_}, scheduler{scheduler_}, texture_cache{texture_cache_}, liverpool{liverpool_}, memory{Core::Memory::Instance()}, pipeline_cache{instance, scheduler, liverpool}, - vertex_index_buffer{instance, scheduler, VertexIndexFlags, 512_MB, BufferType::Upload} { + vertex_index_buffer{instance, scheduler, VertexIndexFlags, 1_GB, BufferType::Upload} { if (!Config::nullGpu()) { liverpool->BindRasterizer(this); } From cd009cfec6719b3edf5616736b0efd85225ecff5 Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Wed, 17 Jul 2024 16:49:45 +0300 Subject: [PATCH 09/12] shader_recompiler: Normal gathers --- .../backend/spirv/emit_spirv_image.cpp | 35 +++++++++++++------ .../backend/spirv/emit_spirv_instructions.h | 6 ++-- .../frontend/translate/translate.cpp | 2 ++ .../frontend/translate/vector_memory.cpp | 1 + .../ir/passes/resource_tracking_pass.cpp | 4 ++- src/shader_recompiler/ir/reg.h | 1 + .../renderer_vulkan/liverpool_to_vk.cpp | 4 +++ 7 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index 2d35b97c..b7249100 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp @@ -9,6 +9,9 @@ namespace Shader::Backend::SPIRV { struct ImageOperands { void Add(spv::ImageOperandsMask new_mask, Id value) { + if (!Sirit::ValidId(value)) { + return; + } mask = static_cast(static_cast(mask) | static_cast(new_mask)); operands.push_back(value); @@ -25,9 +28,7 @@ Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id c const Id sampler = ctx.OpLoad(ctx.sampler_type, ctx.samplers[handle >> 16]); const Id sampled_image = ctx.OpSampledImage(texture.sampled_type, image, sampler); ImageOperands operands; - if (Sirit::ValidId(offset)) { - operands.Add(spv::ImageOperandsMask::ConstOffset, offset); - } + operands.Add(spv::ImageOperandsMask::Offset, offset); return ctx.OpImageSampleImplicitLod(ctx.F32[4], sampled_image, coords, operands.mask, operands.operands); } @@ -61,18 +62,30 @@ Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, spv::ImageOperandsMask::Lod, ctx.ConstF32(0.f)); } -Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, - const IR::Value& offset, const IR::Value& offset2) { - UNREACHABLE_MSG("SPIR-V Instruction"); -} - -Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, - const IR::Value& offset, const IR::Value& offset2, Id dref) { +Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, + Id offset, Id offset2) { const auto& texture = ctx.images[handle & 0xFFFF]; const Id image = ctx.OpLoad(texture.image_type, texture.id); const Id sampler = ctx.OpLoad(ctx.sampler_type, ctx.samplers[handle >> 16]); const Id sampled_image = ctx.OpSampledImage(texture.sampled_type, image, sampler); - return ctx.OpImageDrefGather(ctx.F32[4], sampled_image, coords, dref); + 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); +} + +Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, + Id offset, Id offset2, Id dref) { + const auto& texture = ctx.images[handle & 0xFFFF]; + const Id image = ctx.OpLoad(texture.image_type, texture.id); + const Id sampler = ctx.OpLoad(ctx.sampler_type, ctx.samplers[handle >> 16]); + const Id sampled_image = ctx.OpSampledImage(texture.sampled_type, image, sampler); + ImageOperands operands; + operands.Add(spv::ImageOperandsMask::Offset, offset); + return ctx.OpImageDrefGather(ctx.F32[4], sampled_image, coords, dref, + operands.mask, operands.operands); } Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id offset, Id lod, diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h index f43ea3b3..1432041c 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h @@ -358,10 +358,10 @@ Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id bias_lc, const IR::Value& offset); Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id dref, Id bias_lc, Id offset); -Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, - const IR::Value& offset, const IR::Value& offset2); +Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, + Id offset, Id offset2); Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, - const IR::Value& offset, const IR::Value& offset2, Id dref); + Id offset, Id offset2, Id dref); Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id offset, Id lod, Id ms); Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod, bool skip_mips); diff --git a/src/shader_recompiler/frontend/translate/translate.cpp b/src/shader_recompiler/frontend/translate/translate.cpp index bc2e0bf2..6e5f7f8b 100644 --- a/src/shader_recompiler/frontend/translate/translate.cpp +++ b/src/shader_recompiler/frontend/translate/translate.cpp @@ -456,6 +456,8 @@ void Translate(IR::Block* block, u32 block_base, std::span inst_l translator.IMAGE_GET_LOD(inst); break; case Opcode::IMAGE_GATHER4_C: + case Opcode::IMAGE_GATHER4_LZ: + case Opcode::IMAGE_GATHER4_LZ_O: translator.IMAGE_GATHER(inst); break; case Opcode::IMAGE_STORE: diff --git a/src/shader_recompiler/frontend/translate/vector_memory.cpp b/src/shader_recompiler/frontend/translate/vector_memory.cpp index 1ddee523..f4383c61 100644 --- a/src/shader_recompiler/frontend/translate/vector_memory.cpp +++ b/src/shader_recompiler/frontend/translate/vector_memory.cpp @@ -158,6 +158,7 @@ void Translator::IMAGE_GATHER(const GcnInst& inst) { info.has_lod_clamp.Assign(flags.test(MimgModifier::LodClamp)); info.force_level0.Assign(flags.test(MimgModifier::Level0)); 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. const IR::Value texel = [&]() -> IR::Value { diff --git a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp index f58b4d96..6526ece6 100644 --- a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp +++ b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp @@ -543,7 +543,9 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip if (inst_info.has_offset) { // The offsets are six-bit signed integers: X=[5:0], Y=[13:8], and Z=[21:16]. - const u32 arg_pos = inst_info.is_depth ? 4 : 3; + const bool is_gather = inst.GetOpcode() == IR::Opcode::ImageGather || + inst.GetOpcode() == IR::Opcode::ImageGatherDref; + const u32 arg_pos = is_gather ? 2 : (inst_info.is_depth ? 4 : 3); const IR::Value arg = inst.Arg(arg_pos); ASSERT_MSG(arg.Type() == IR::Type::U32, "Unexpected offset type"); const auto sign_ext = [&](u32 value) { return ir.Imm32(s32(value << 24) >> 24); }; diff --git a/src/shader_recompiler/ir/reg.h b/src/shader_recompiler/ir/reg.h index ae38ecf3..d9e9b030 100644 --- a/src/shader_recompiler/ir/reg.h +++ b/src/shader_recompiler/ir/reg.h @@ -39,6 +39,7 @@ union TextureInstInfo { BitField<3, 1, u32> force_level0; BitField<4, 1, u32> explicit_lod; BitField<5, 1, u32> has_offset; + BitField<6, 2, u32> gather_comp; }; union BufferInstInfo { diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp index 0cbe0de8..d9ca8b1f 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp @@ -420,6 +420,10 @@ vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat nu num_format == AmdGpu::NumberFormat::Uint) { return vk::Format::eR32G32B32A32Uint; } + if (data_format == AmdGpu::DataFormat::Format32_32_32_32 && + num_format == AmdGpu::NumberFormat::Sint) { + return vk::Format::eR32G32B32A32Sint; + } if (data_format == AmdGpu::DataFormat::Format8 && num_format == AmdGpu::NumberFormat::Sint) { return vk::Format::eR8Sint; } From 1208661d649df194f5af3a429b42626ff975d65c Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Wed, 17 Jul 2024 17:06:09 +0300 Subject: [PATCH 10/12] Remove bc6 --- src/video_core/renderer_vulkan/liverpool_to_vk.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp index d9ca8b1f..bf520874 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp @@ -453,10 +453,6 @@ vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat nu num_format == AmdGpu::NumberFormat::SnormNz) { return vk::Format::eR16G16B16A16Snorm; } - if (data_format == AmdGpu::DataFormat::FormatBc6 && - num_format == AmdGpu::NumberFormat::Unorm) { - return vk::Format::eBc6HUfloatBlock; - } UNREACHABLE_MSG("Unknown data_format={} and num_format={}", u32(data_format), u32(num_format)); } From 439c0be9a6af818358801a298a23a356ead6688c Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Wed, 17 Jul 2024 17:57:54 +0300 Subject: [PATCH 11/12] clang format fix --- src/emulator.cpp | 5 ++--- .../backend/spirv/emit_spirv_image.cpp | 15 +++++++-------- .../backend/spirv/emit_spirv_instructions.h | 7 +++---- .../renderer_vulkan/liverpool_to_vk.cpp | 3 +-- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/emulator.cpp b/src/emulator.cpp index 9eafe7a6..91d92cd6 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -165,9 +165,8 @@ void Emulator::LoadSystemModules(const std::filesystem::path& file) { found_modules.push_back(entry.path()); } for (const auto& [module_name, init_func] : ModulesToLoad) { - const auto it = std::ranges::find_if(found_modules, [&](const auto& path) { - return path.filename() == module_name; - }); + const auto it = std::ranges::find_if( + found_modules, [&](const auto& path) { return path.filename() == module_name; }); if (it != found_modules.end()) { LOG_INFO(Loader, "Loading {}", it->string()); linker->LoadModule(*it); diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index b7249100..17def57a 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp @@ -62,8 +62,7 @@ Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, spv::ImageOperandsMask::Lod, ctx.ConstF32(0.f)); } -Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, - Id offset, Id offset2) { +Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id offset, Id offset2) { const auto& texture = ctx.images[handle & 0xFFFF]; const Id image = ctx.OpLoad(texture.image_type, texture.id); const Id sampler = ctx.OpLoad(ctx.sampler_type, ctx.samplers[handle >> 16]); @@ -72,20 +71,20 @@ Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, 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); + return ctx.OpImageGather(ctx.F32[4], sampled_image, coords, ctx.ConstU32(comp), operands.mask, + operands.operands); } -Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, - Id offset, Id offset2, Id dref) { +Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id offset, + Id offset2, Id dref) { const auto& texture = ctx.images[handle & 0xFFFF]; const Id image = ctx.OpLoad(texture.image_type, texture.id); const Id sampler = ctx.OpLoad(ctx.sampler_type, ctx.samplers[handle >> 16]); const Id sampled_image = ctx.OpSampledImage(texture.sampled_type, image, sampler); ImageOperands operands; operands.Add(spv::ImageOperandsMask::Offset, offset); - return ctx.OpImageDrefGather(ctx.F32[4], sampled_image, coords, dref, - operands.mask, operands.operands); + return ctx.OpImageDrefGather(ctx.F32[4], sampled_image, coords, dref, operands.mask, + operands.operands); } Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id offset, Id lod, diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h index 1432041c..e2b411e4 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h @@ -358,10 +358,9 @@ Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id bias_lc, const IR::Value& offset); Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id dref, Id bias_lc, Id offset); -Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, - Id offset, Id offset2); -Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, - Id offset, Id offset2, Id dref); +Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id offset, Id offset2); +Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id offset, + Id offset2, Id dref); Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id offset, Id lod, Id ms); Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod, bool skip_mips); diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp index bf520874..f361fcad 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp @@ -445,8 +445,7 @@ vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat nu num_format == AmdGpu::NumberFormat::Unorm) { return vk::Format::eR16G16B16A16Unorm; } - if (data_format == AmdGpu::DataFormat::Format8 && - num_format == AmdGpu::NumberFormat::Uint) { + if (data_format == AmdGpu::DataFormat::Format8 && num_format == AmdGpu::NumberFormat::Uint) { return vk::Format::eR8Uint; } if (data_format == AmdGpu::DataFormat::Format16_16_16_16 && From 0ed9ea5b859a76f72623ecf64d79e9449fb06c44 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Wed, 17 Jul 2024 20:32:14 +0300 Subject: [PATCH 12/12] force imedialog to input "shadps4" as name . That way we can pass games that want username . temp solution till imgui dialog prepared --- src/core/libraries/dialogs/ime_dialog.cpp | 18 ++++++++++++++---- src/core/libraries/dialogs/ime_dialog.h | 3 +-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/core/libraries/dialogs/ime_dialog.cpp b/src/core/libraries/dialogs/ime_dialog.cpp index 89136a03..3fa35c2c 100644 --- a/src/core/libraries/dialogs/ime_dialog.cpp +++ b/src/core/libraries/dialogs/ime_dialog.cpp @@ -9,6 +9,8 @@ namespace Libraries::ImeDialog { +static OrbisImeDialogStatus g_ime_dlg_status = OrbisImeDialogStatus::ORBIS_IME_DIALOG_STATUS_NONE; + int PS4_SYSV_ABI sceImeDialogAbort() { LOG_ERROR(Lib_ImeDialog, "(STUBBED) called"); return ORBIS_OK; @@ -45,18 +47,25 @@ int PS4_SYSV_ABI sceImeDialogGetPanelSizeExtended() { } int PS4_SYSV_ABI sceImeDialogGetResult(OrbisImeDialogResult* result) { + result->endstatus = OrbisImeDialogEndStatus::ORBIS_IME_DIALOG_END_STATUS_OK; LOG_ERROR(Lib_ImeDialog, "(STUBBED) called"); return ORBIS_OK; } int PS4_SYSV_ABI sceImeDialogGetStatus() { - LOG_ERROR(Lib_ImeDialog, "(STUBBED) called"); - return ORBIS_OK; + if (g_ime_dlg_status == OrbisImeDialogStatus::ORBIS_IME_DIALOG_STATUS_RUNNING) { + return OrbisImeDialogStatus::ORBIS_IME_DIALOG_STATUS_FINISHED; + } + + return g_ime_dlg_status; } -int PS4_SYSV_ABI sceImeDialogInit(const OrbisImeDialogParam* param, - const OrbisImeParamExtended* extended) { +int PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExtended* extended) { LOG_ERROR(Lib_ImeDialog, "(STUBBED) called"); + const std::wstring_view text = L"shadPS4"; + param->maxTextLength = text.size(); + std::memcpy(param->inputTextBuffer, text.data(), text.size() * sizeof(wchar_t)); + g_ime_dlg_status = OrbisImeDialogStatus::ORBIS_IME_DIALOG_STATUS_RUNNING; return ORBIS_OK; } @@ -82,6 +91,7 @@ int PS4_SYSV_ABI sceImeDialogSetPanelPosition() { int PS4_SYSV_ABI sceImeDialogTerm() { LOG_ERROR(Lib_ImeDialog, "(STUBBED) called"); + g_ime_dlg_status = OrbisImeDialogStatus::ORBIS_IME_DIALOG_STATUS_NONE; return ORBIS_OK; } diff --git a/src/core/libraries/dialogs/ime_dialog.h b/src/core/libraries/dialogs/ime_dialog.h index 08c980a4..ffe42b31 100644 --- a/src/core/libraries/dialogs/ime_dialog.h +++ b/src/core/libraries/dialogs/ime_dialog.h @@ -174,8 +174,7 @@ int PS4_SYSV_ABI sceImeDialogGetPanelSize(); int PS4_SYSV_ABI sceImeDialogGetPanelSizeExtended(); int PS4_SYSV_ABI sceImeDialogGetResult(OrbisImeDialogResult* result); /*OrbisImeDialogStatus*/ int PS4_SYSV_ABI sceImeDialogGetStatus(); -int PS4_SYSV_ABI sceImeDialogInit(const OrbisImeDialogParam* param, - const OrbisImeParamExtended* extended); +int PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExtended* extended); int PS4_SYSV_ABI sceImeDialogInitInternal(); int PS4_SYSV_ABI sceImeDialogInitInternal2(); int PS4_SYSV_ABI sceImeDialogInitInternal3();