Merge pull request #300 from shadps4-emu/regression-fix
code: Fixup some regressions
This commit is contained in:
commit
384ea359ed
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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); };
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue