early-access version 2637

main
pineappleEA 2022-04-02 22:34:58 +02:00
parent 0d49569ca5
commit 0397c1ff98
10 changed files with 84 additions and 26 deletions

View File

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 2636. This is the source code for early-access 2637.
## Legal Notice ## Legal Notice

View File

@ -75,6 +75,14 @@ void AxxEmitX64::EmitMemoryRead(AxxEmitContext& ctx, IR::Inst* inst) {
return; return;
} }
if (ordered && bitsize == 128) {
// Required for atomic 128-bit loads/stores
ctx.reg_alloc.ScratchGpr(HostLoc::RAX);
ctx.reg_alloc.ScratchGpr(HostLoc::RBX);
ctx.reg_alloc.ScratchGpr(HostLoc::RCX);
ctx.reg_alloc.ScratchGpr(HostLoc::RDX);
}
const Xbyak::Reg64 vaddr = ctx.reg_alloc.UseGpr(args[0]); const Xbyak::Reg64 vaddr = ctx.reg_alloc.UseGpr(args[0]);
const int value_idx = bitsize == 128 ? ctx.reg_alloc.ScratchXmm().getIdx() : ctx.reg_alloc.ScratchGpr().getIdx(); const int value_idx = bitsize == 128 ? ctx.reg_alloc.ScratchXmm().getIdx() : ctx.reg_alloc.ScratchGpr().getIdx();
@ -145,6 +153,14 @@ void AxxEmitX64::EmitMemoryWrite(AxxEmitContext& ctx, IR::Inst* inst) {
return; return;
} }
if (ordered && bitsize == 128) {
// Required for atomic 128-bit loads/stores
ctx.reg_alloc.ScratchGpr(HostLoc::RAX);
ctx.reg_alloc.ScratchGpr(HostLoc::RBX);
ctx.reg_alloc.ScratchGpr(HostLoc::RCX);
ctx.reg_alloc.ScratchGpr(HostLoc::RDX);
}
const Xbyak::Reg64 vaddr = ctx.reg_alloc.UseGpr(args[0]); const Xbyak::Reg64 vaddr = ctx.reg_alloc.UseGpr(args[0]);
const int value_idx = bitsize == 128 const int value_idx = bitsize == 128
? ctx.reg_alloc.UseXmm(args[1]).getIdx() ? ctx.reg_alloc.UseXmm(args[1]).getIdx()
@ -303,7 +319,15 @@ void AxxEmitX64::EmitExclusiveReadMemoryInline(AxxEmitContext& ctx, IR::Inst* in
} }
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const bool ordered = IsOrdered(args[1].GetImmediateAccType()); const bool ordered = true;
if (ordered && bitsize == 128) {
// Required for atomic 128-bit loads/stores
ctx.reg_alloc.ScratchGpr(HostLoc::RAX);
ctx.reg_alloc.ScratchGpr(HostLoc::RBX);
ctx.reg_alloc.ScratchGpr(HostLoc::RCX);
ctx.reg_alloc.ScratchGpr(HostLoc::RDX);
}
const Xbyak::Reg64 vaddr = ctx.reg_alloc.UseGpr(args[0]); const Xbyak::Reg64 vaddr = ctx.reg_alloc.UseGpr(args[0]);
const int value_idx = bitsize == 128 ? ctx.reg_alloc.ScratchXmm().getIdx() : ctx.reg_alloc.ScratchGpr().getIdx(); const int value_idx = bitsize == 128 ? ctx.reg_alloc.ScratchXmm().getIdx() : ctx.reg_alloc.ScratchGpr().getIdx();
@ -370,7 +394,7 @@ void AxxEmitX64::EmitExclusiveWriteMemoryInline(AxxEmitContext& ctx, IR::Inst* i
} }
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const bool ordered = IsOrdered(args[2].GetImmediateAccType()); const bool ordered = true;
const auto value = [&] { const auto value = [&] {
if constexpr (bitsize == 128) { if constexpr (bitsize == 128) {

View File

@ -201,10 +201,13 @@ template<>
template<std::size_t bitsize> template<std::size_t bitsize>
const void* EmitReadMemoryMov(BlockOfCode& code, int value_idx, const Xbyak::RegExp& addr, bool ordered) { const void* EmitReadMemoryMov(BlockOfCode& code, int value_idx, const Xbyak::RegExp& addr, bool ordered) {
if (ordered) { if (ordered) {
if constexpr (bitsize == 128) { if constexpr (bitsize != 128) {
code.mfence();
} else {
code.xor_(Xbyak::Reg32{value_idx}, Xbyak::Reg32{value_idx}); code.xor_(Xbyak::Reg32{value_idx}, Xbyak::Reg32{value_idx});
} else {
code.xor_(eax, eax);
code.xor_(ebx, ebx);
code.xor_(ecx, ecx);
code.xor_(edx, edx);
} }
const void* fastmem_location = code.getCurr(); const void* fastmem_location = code.getCurr();
@ -215,7 +218,7 @@ const void* EmitReadMemoryMov(BlockOfCode& code, int value_idx, const Xbyak::Reg
break; break;
case 16: case 16:
code.lock(); code.lock();
code.xadd(word[addr], Xbyak::Reg32{value_idx}); code.xadd(word[addr], Xbyak::Reg16{value_idx});
break; break;
case 32: case 32:
code.lock(); code.lock();
@ -226,8 +229,16 @@ const void* EmitReadMemoryMov(BlockOfCode& code, int value_idx, const Xbyak::Reg
code.xadd(qword[addr], Xbyak::Reg64{value_idx}); code.xadd(qword[addr], Xbyak::Reg64{value_idx});
break; break;
case 128: case 128:
// TODO (HACK): Detect CPUs where this load is not atomic code.lock();
code.movaps(Xbyak::Xmm{value_idx}, xword[addr]); code.cmpxchg16b(xword[addr]);
if (code.HasHostFeature(HostFeature::SSE41)) {
code.movq(Xbyak::Xmm{value_idx}, rax);
code.pinsrq(Xbyak::Xmm{value_idx}, rdx, 1);
} else {
code.movq(Xbyak::Xmm{value_idx}, rax);
code.movq(xmm0, rdx);
code.punpcklqdq(Xbyak::Xmm{value_idx}, xmm0);
}
break; break;
default: default:
ASSERT_FALSE("Invalid bitsize"); ASSERT_FALSE("Invalid bitsize");
@ -261,6 +272,20 @@ const void* EmitReadMemoryMov(BlockOfCode& code, int value_idx, const Xbyak::Reg
template<std::size_t bitsize> template<std::size_t bitsize>
const void* EmitWriteMemoryMov(BlockOfCode& code, const Xbyak::RegExp& addr, int value_idx, bool ordered) { const void* EmitWriteMemoryMov(BlockOfCode& code, const Xbyak::RegExp& addr, int value_idx, bool ordered) {
if (ordered) { if (ordered) {
if constexpr (bitsize == 128) {
code.xor_(eax, eax);
code.xor_(edx, edx);
if (code.HasHostFeature(HostFeature::SSE41)) {
code.movq(rbx, Xbyak::Xmm{value_idx});
code.pextrq(rcx, Xbyak::Xmm{value_idx}, 1);
} else {
code.movaps(xmm0, Xbyak::Xmm{value_idx});
code.movq(rbx, xmm0);
code.punpckhqdq(xmm0, xmm0);
code.movq(rcx, xmm0);
}
}
const void* fastmem_location = code.getCurr(); const void* fastmem_location = code.getCurr();
switch (bitsize) { switch (bitsize) {
case 8: case 8:
@ -275,10 +300,14 @@ const void* EmitWriteMemoryMov(BlockOfCode& code, const Xbyak::RegExp& addr, int
case 64: case 64:
code.xchg(qword[addr], Xbyak::Reg64{value_idx}); code.xchg(qword[addr], Xbyak::Reg64{value_idx});
break; break;
case 128: case 128: {
code.movaps(xword[addr], Xbyak::Xmm{value_idx}); Xbyak::Label loop;
code.mfence(); code.L(loop);
code.lock();
code.cmpxchg16b(xword[addr]);
code.jnz(loop);
break; break;
}
default: default:
ASSERT_FALSE("Invalid bitsize"); ASSERT_FALSE("Invalid bitsize");
} }

View File

@ -174,7 +174,7 @@ ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_,
ASSERT_MSG(dest != nullptr, "Newly created file with success cannot be found."); ASSERT_MSG(dest != nullptr, "Newly created file with success cannot be found.");
ASSERT_MSG(dest->WriteBytes(src->ReadAllBytes()) == src->GetSize(), ASSERT_MSG(dest->WriteBytes(src->ReadAllBytes()) == src->GetSize(),
"Could not write all of the bytes but everything else has succeded."); "Could not write all of the bytes but everything else has succeeded.");
if (!src->GetContainingDirectory()->DeleteFile(Common::FS::GetFilename(src_path))) { if (!src->GetContainingDirectory()->DeleteFile(Common::FS::GetFilename(src_path))) {
// TODO(DarkLordZach): Find a better error code for this // TODO(DarkLordZach): Find a better error code for this

View File

@ -26,7 +26,7 @@ void NVDRV::Open(Kernel::HLERequestContext& ctx) {
rb.Push<DeviceFD>(0); rb.Push<DeviceFD>(0);
rb.PushEnum(NvResult::NotInitialized); rb.PushEnum(NvResult::NotInitialized);
LOG_ERROR(Service_NVDRV, "NvServices is not initalized!"); LOG_ERROR(Service_NVDRV, "NvServices is not initialized!");
return; return;
} }
@ -61,7 +61,7 @@ void NVDRV::Ioctl1(Kernel::HLERequestContext& ctx) {
if (!is_initialized) { if (!is_initialized) {
ServiceError(ctx, NvResult::NotInitialized); ServiceError(ctx, NvResult::NotInitialized);
LOG_ERROR(Service_NVDRV, "NvServices is not initalized!"); LOG_ERROR(Service_NVDRV, "NvServices is not initialized!");
return; return;
} }
@ -87,7 +87,7 @@ void NVDRV::Ioctl2(Kernel::HLERequestContext& ctx) {
if (!is_initialized) { if (!is_initialized) {
ServiceError(ctx, NvResult::NotInitialized); ServiceError(ctx, NvResult::NotInitialized);
LOG_ERROR(Service_NVDRV, "NvServices is not initalized!"); LOG_ERROR(Service_NVDRV, "NvServices is not initialized!");
return; return;
} }
@ -114,7 +114,7 @@ void NVDRV::Ioctl3(Kernel::HLERequestContext& ctx) {
if (!is_initialized) { if (!is_initialized) {
ServiceError(ctx, NvResult::NotInitialized); ServiceError(ctx, NvResult::NotInitialized);
LOG_ERROR(Service_NVDRV, "NvServices is not initalized!"); LOG_ERROR(Service_NVDRV, "NvServices is not initialized!");
return; return;
} }
@ -139,7 +139,7 @@ void NVDRV::Close(Kernel::HLERequestContext& ctx) {
if (!is_initialized) { if (!is_initialized) {
ServiceError(ctx, NvResult::NotInitialized); ServiceError(ctx, NvResult::NotInitialized);
LOG_ERROR(Service_NVDRV, "NvServices is not initalized!"); LOG_ERROR(Service_NVDRV, "NvServices is not initialized!");
return; return;
} }
@ -170,7 +170,7 @@ void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) {
if (!is_initialized) { if (!is_initialized) {
ServiceError(ctx, NvResult::NotInitialized); ServiceError(ctx, NvResult::NotInitialized);
LOG_ERROR(Service_NVDRV, "NvServices is not initalized!"); LOG_ERROR(Service_NVDRV, "NvServices is not initialized!");
return; return;
} }

View File

@ -132,7 +132,7 @@ void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) {
multisample = v.X(meta_reg++); multisample = v.X(meta_reg++);
} }
if (tld.clamp != 0) { if (tld.clamp != 0) {
throw NotImplementedException("TLD.CL - CLAMP is not implmented"); throw NotImplementedException("TLD.CL - CLAMP is not implemented");
} }
IR::TextureInstInfo info{}; IR::TextureInstInfo info{};
info.type.Assign(GetType(tld.type)); info.type.Assign(GetType(tld.type));

View File

@ -81,7 +81,7 @@ void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) {
} const tmml{insn}; } const tmml{insn};
if ((tmml.mask & 0b1100) != 0) { if ((tmml.mask & 0b1100) != 0) {
throw NotImplementedException("TMML BA results are not implmented"); throw NotImplementedException("TMML BA results are not implemented");
} }
const IR::Value coords{MakeCoords(v, tmml.coord_reg, tmml.type)}; const IR::Value coords{MakeCoords(v, tmml.coord_reg, tmml.type)};

View File

@ -736,7 +736,7 @@ VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags
} }
void Device::ReportLoss() const { void Device::ReportLoss() const {
LOG_CRITICAL(Render_Vulkan, "Device loss occured!"); LOG_CRITICAL(Render_Vulkan, "Device loss occurred!");
// Wait for the log to flush and for Nsight Aftermath to dump the results // Wait for the log to flush and for Nsight Aftermath to dump the results
std::this_thread::sleep_for(std::chrono::seconds{15}); std::this_thread::sleep_for(std::chrono::seconds{15});

View File

@ -35,8 +35,9 @@ ConfigureHotkeys::ConfigureHotkeys(Core::HID::HIDCore& hid_core, QWidget* parent
ui->hotkey_list->setContextMenuPolicy(Qt::CustomContextMenu); ui->hotkey_list->setContextMenuPolicy(Qt::CustomContextMenu);
ui->hotkey_list->setModel(model); ui->hotkey_list->setModel(model);
ui->hotkey_list->setColumnWidth(name_column, 200); ui->hotkey_list->header()->setStretchLastSection(false);
ui->hotkey_list->resizeColumnToContents(hotkey_column); ui->hotkey_list->header()->setSectionResizeMode(name_column, QHeaderView::ResizeMode::Stretch);
ui->hotkey_list->header()->setMinimumSectionSize(150);
connect(ui->button_restore_defaults, &QPushButton::clicked, this, connect(ui->button_restore_defaults, &QPushButton::clicked, this,
&ConfigureHotkeys::RestoreDefaults); &ConfigureHotkeys::RestoreDefaults);
@ -76,8 +77,8 @@ void ConfigureHotkeys::Populate(const HotkeyRegistry& registry) {
} }
ui->hotkey_list->expandAll(); ui->hotkey_list->expandAll();
ui->hotkey_list->resizeColumnToContents(name_column);
ui->hotkey_list->resizeColumnToContents(hotkey_column); ui->hotkey_list->resizeColumnToContents(hotkey_column);
ui->hotkey_list->resizeColumnToContents(controller_column);
} }
void ConfigureHotkeys::changeEvent(QEvent* event) { void ConfigureHotkeys::changeEvent(QEvent* event) {

View File

@ -47,6 +47,10 @@ ConfigurePerGameAddons::ConfigurePerGameAddons(Core::System& system_, QWidget* p
item_model->setHeaderData(0, Qt::Horizontal, tr("Patch Name")); item_model->setHeaderData(0, Qt::Horizontal, tr("Patch Name"));
item_model->setHeaderData(1, Qt::Horizontal, tr("Version")); item_model->setHeaderData(1, Qt::Horizontal, tr("Version"));
tree_view->header()->setStretchLastSection(false);
tree_view->header()->setSectionResizeMode(0, QHeaderView::ResizeMode::Stretch);
tree_view->header()->setMinimumSectionSize(150);
// We must register all custom types with the Qt Automoc system so that we are able to use it // We must register all custom types with the Qt Automoc system so that we are able to use it
// with signals/slots. In this case, QList falls under the umbrella of custom types. // with signals/slots. In this case, QList falls under the umbrella of custom types.
qRegisterMetaType<QList<QStandardItem*>>("QList<QStandardItem*>"); qRegisterMetaType<QList<QStandardItem*>>("QList<QStandardItem*>");
@ -138,5 +142,5 @@ void ConfigurePerGameAddons::LoadConfiguration() {
item_model->appendRow(list_items.back()); item_model->appendRow(list_items.back());
} }
tree_view->setColumnWidth(0, 5 * tree_view->width() / 16); tree_view->resizeColumnToContents(1);
} }