Merge pull request #300 from shadps4-emu/regression-fix

code: Fixup some regressions
This commit is contained in:
georgemoralis 2024-07-17 20:40:23 +03:00 committed by GitHub
commit 384ea359ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 94 additions and 48 deletions

View File

@ -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) {

View File

@ -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;
}

View File

@ -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();

View File

@ -346,7 +346,8 @@ 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;
// 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;
kernel_event.event.udata = udata;
@ -649,6 +650,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 +706,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;
}

View File

@ -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();
}

View File

@ -50,13 +50,16 @@ 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;
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 +77,16 @@ 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;
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,

View File

@ -148,39 +148,35 @@ void Emulator::Run(const std::filesystem::path& file) {
}
void Emulator::LoadSystemModules(const std::filesystem::path& file) {
constexpr std::array<SysModules, 6> ModulesToLoad{
constexpr std::array<SysModules, 8> 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},
{"libSceJpegEnc.sprx", nullptr},
{"libSceJson2.sprx", nullptr}}};
{"libSceJson2.sprx", nullptr}},
};
std::vector<std::filesystem::path> 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);
}
}
}

View File

@ -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<spv::ImageOperandsMask>(static_cast<u32>(mask) |
static_cast<u32>(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,29 @@ 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<IR::TextureInstInfo>().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,

View File

@ -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, const IR::Value& index, Id coords,
const IR::Value& offset, const IR::Value& offset2);
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);
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);

View File

@ -456,6 +456,8 @@ void Translate(IR::Block* block, u32 block_base, std::span<const GcnInst> 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:

View File

@ -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 {

View File

@ -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); };

View File

@ -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 {

View File

@ -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;
}
@ -441,6 +445,13 @@ 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;
}
UNREACHABLE_MSG("Unknown data_format={} and num_format={}", u32(data_format), u32(num_format));
}

View File

@ -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);
}