early-access version 4040

This commit is contained in:
pineappleEA 2023-12-30 23:15:57 +01:00
parent 28e97ec962
commit 05d9419e78
16 changed files with 204 additions and 25 deletions

View File

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

View File

@ -18,7 +18,8 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
RENDERER_ANTI_ALIASING("anti_aliasing"), RENDERER_ANTI_ALIASING("anti_aliasing"),
RENDERER_SCREEN_LAYOUT("screen_layout"), RENDERER_SCREEN_LAYOUT("screen_layout"),
RENDERER_ASPECT_RATIO("aspect_ratio"), RENDERER_ASPECT_RATIO("aspect_ratio"),
AUDIO_OUTPUT_ENGINE("output_engine"); AUDIO_OUTPUT_ENGINE("output_engine"),
MAX_ANISOTROPY("max_anisotropy");
override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal) override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal)

View File

@ -243,6 +243,15 @@ abstract class SettingsItem(
R.string.renderer_reactive_flushing_description R.string.renderer_reactive_flushing_description
) )
) )
put(
SingleChoiceSetting(
IntSetting.MAX_ANISOTROPY,
R.string.anisotropic_filtering,
R.string.anisotropic_filtering_description,
R.array.anisoEntries,
R.array.anisoValues
)
)
put( put(
SingleChoiceSetting( SingleChoiceSetting(
IntSetting.AUDIO_OUTPUT_ENGINE, IntSetting.AUDIO_OUTPUT_ENGINE,
@ -298,6 +307,7 @@ abstract class SettingsItem(
override val key: String = FASTMEM_COMBINED override val key: String = FASTMEM_COMBINED
override val isRuntimeModifiable: Boolean = false override val isRuntimeModifiable: Boolean = false
override val pairedSettingKey = BooleanSetting.CPU_DEBUG_MODE.key
override val defaultValue: Boolean = true override val defaultValue: Boolean = true
override val isSwitchable: Boolean = true override val isSwitchable: Boolean = true
override var global: Boolean override var global: Boolean

View File

@ -149,6 +149,7 @@ class SettingsFragmentPresenter(
add(IntSetting.RENDERER_VSYNC.key) add(IntSetting.RENDERER_VSYNC.key)
add(IntSetting.RENDERER_SCALING_FILTER.key) add(IntSetting.RENDERER_SCALING_FILTER.key)
add(IntSetting.RENDERER_ANTI_ALIASING.key) add(IntSetting.RENDERER_ANTI_ALIASING.key)
add(IntSetting.MAX_ANISOTROPY.key)
add(IntSetting.RENDERER_SCREEN_LAYOUT.key) add(IntSetting.RENDERER_SCREEN_LAYOUT.key)
add(IntSetting.RENDERER_ASPECT_RATIO.key) add(IntSetting.RENDERER_ASPECT_RATIO.key)
add(BooleanSetting.PICTURE_IN_PICTURE.key) add(BooleanSetting.PICTURE_IN_PICTURE.key)

View File

@ -24,7 +24,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="24dp" android:layout_marginEnd="24dp"
android:gravity="center_vertical" android:layout_gravity="center_vertical"
android:orientation="vertical" android:orientation="vertical"
android:layout_weight="1"> android:layout_weight="1">

View File

@ -267,4 +267,21 @@
<item>3</item> <item>3</item>
</integer-array> </integer-array>
<string-array name="anisoEntries">
<item>@string/auto</item>
<item>@string/slider_default</item>
<item>@string/multiplier_two</item>
<item>@string/multiplier_four</item>
<item>@string/multiplier_eight</item>
<item>@string/multiplier_sixteen</item>
</string-array>
<integer-array name="anisoValues">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
</integer-array>
</resources> </resources>

View File

@ -225,6 +225,8 @@
<string name="renderer_reactive_flushing_description">Improves rendering accuracy in some games at the cost of performance.</string> <string name="renderer_reactive_flushing_description">Improves rendering accuracy in some games at the cost of performance.</string>
<string name="use_disk_shader_cache">Disk shader cache</string> <string name="use_disk_shader_cache">Disk shader cache</string>
<string name="use_disk_shader_cache_description">Reduces stuttering by locally storing and loading generated shaders.</string> <string name="use_disk_shader_cache_description">Reduces stuttering by locally storing and loading generated shaders.</string>
<string name="anisotropic_filtering">Anisotropic filtering</string>
<string name="anisotropic_filtering_description">Improves the quality of textures when viewed at oblique angles</string>
<!-- Debug settings strings --> <!-- Debug settings strings -->
<string name="cpu">CPU</string> <string name="cpu">CPU</string>
@ -506,6 +508,12 @@
<string name="oboe">oboe</string> <string name="oboe">oboe</string>
<string name="cubeb">cubeb</string> <string name="cubeb">cubeb</string>
<!-- Anisotropic filtering options -->
<string name="multiplier_two">2x</string>
<string name="multiplier_four">4x</string>
<string name="multiplier_eight">8x</string>
<string name="multiplier_sixteen">16x</string>
<!-- Black backgrounds theme --> <!-- Black backgrounds theme -->
<string name="use_black_backgrounds">Black backgrounds</string> <string name="use_black_backgrounds">Black backgrounds</string>
<string name="use_black_backgrounds_description">When using the dark theme, apply black backgrounds.</string> <string name="use_black_backgrounds_description">When using the dark theme, apply black backgrounds.</string>

View File

@ -988,6 +988,8 @@ if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
arm/dynarmic/dynarmic_cp15.h arm/dynarmic/dynarmic_cp15.h
arm/dynarmic/dynarmic_exclusive_monitor.cpp arm/dynarmic/dynarmic_exclusive_monitor.cpp
arm/dynarmic/dynarmic_exclusive_monitor.h arm/dynarmic/dynarmic_exclusive_monitor.h
hle/service/jit/jit_code_memory.cpp
hle/service/jit/jit_code_memory.h
hle/service/jit/jit_context.cpp hle/service/jit/jit_context.cpp
hle/service/jit/jit_context.h hle/service/jit/jit_context.h
hle/service/jit/jit.cpp hle/service/jit/jit.cpp

View File

@ -73,6 +73,9 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
return nullptr; return nullptr;
auto in_data = in->ReadAllBytes(); auto in_data = in->ReadAllBytes();
if (in_data.size() == 0) {
return nullptr;
}
std::vector<u8> temp(type == IPSFileType::IPS ? 3 : 4); std::vector<u8> temp(type == IPSFileType::IPS ? 3 : 4);
u64 offset = 5; // After header u64 offset = 5; // After header
@ -88,6 +91,10 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
else else
real_offset = (temp[0] << 16) | (temp[1] << 8) | temp[2]; real_offset = (temp[0] << 16) | (temp[1] << 8) | temp[2];
if (real_offset > in_data.size()) {
return nullptr;
}
u16 data_size{}; u16 data_size{};
if (ips->ReadObject(&data_size, offset) != sizeof(u16)) if (ips->ReadObject(&data_size, offset) != sizeof(u16))
return nullptr; return nullptr;

View File

@ -185,6 +185,10 @@ Result KCapabilities::ProcessMapRegionCapability(const u32 cap, F f) {
case RegionType::NoMapping: case RegionType::NoMapping:
break; break;
case RegionType::KernelTraceBuffer: case RegionType::KernelTraceBuffer:
if constexpr (!IsKTraceEnabled) {
break;
}
[[fallthrough]];
case RegionType::OnMemoryBootImage: case RegionType::OnMemoryBootImage:
case RegionType::DTB: case RegionType::DTB:
R_TRY(f(MemoryRegions[static_cast<u32>(type)], perm)); R_TRY(f(MemoryRegions[static_cast<u32>(type)], perm));
@ -330,8 +334,6 @@ Result KCapabilities::SetCapabilities(std::span<const u32> caps, KProcessPageTab
// Map the range. // Map the range.
R_TRY(this->MapRange_(cap, size_cap, page_table)); R_TRY(this->MapRange_(cap, size_cap, page_table));
} else if (GetCapabilityType(cap) == CapabilityType::MapRegion && !IsKTraceEnabled) {
continue;
} else { } else {
R_TRY(this->SetCapability(cap, set_flags, set_svc, page_table)); R_TRY(this->SetCapability(cap, set_flags, set_svc, page_table));
} }

View File

@ -4,11 +4,11 @@
#include "core/arm/debug.h" #include "core/arm/debug.h"
#include "core/arm/symbols.h" #include "core/arm/symbols.h"
#include "core/core.h" #include "core/core.h"
#include "core/hle/kernel/k_code_memory.h"
#include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/result.h" #include "core/hle/result.h"
#include "core/hle/service/ipc_helpers.h" #include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/jit/jit.h" #include "core/hle/service/jit/jit.h"
#include "core/hle/service/jit/jit_code_memory.h"
#include "core/hle/service/jit/jit_context.h" #include "core/hle/service/jit/jit_context.h"
#include "core/hle/service/server_manager.h" #include "core/hle/service/server_manager.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
@ -23,10 +23,12 @@ struct CodeRange {
class IJitEnvironment final : public ServiceFramework<IJitEnvironment> { class IJitEnvironment final : public ServiceFramework<IJitEnvironment> {
public: public:
explicit IJitEnvironment(Core::System& system_, Kernel::KProcess& process_, CodeRange user_rx, explicit IJitEnvironment(Core::System& system_,
CodeRange user_ro) Kernel::KScopedAutoObject<Kernel::KProcess>&& process_,
: ServiceFramework{system_, "IJitEnvironment"}, process{&process_}, CodeMemory&& user_rx_, CodeMemory&& user_ro_)
context{process->GetMemory()} { : ServiceFramework{system_, "IJitEnvironment"}, process{std::move(process_)},
user_rx{std::move(user_rx_)}, user_ro{std::move(user_ro_)},
context{system_.ApplicationMemory()} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IJitEnvironment::GenerateCode, "GenerateCode"}, {0, &IJitEnvironment::GenerateCode, "GenerateCode"},
@ -39,10 +41,13 @@ public:
RegisterHandlers(functions); RegisterHandlers(functions);
// Identity map user code range into sysmodule context // Identity map user code range into sysmodule context
configuration.user_ro_memory = user_ro; configuration.user_rx_memory.size = user_rx.GetSize();
configuration.user_rx_memory = user_rx; configuration.user_rx_memory.offset = user_rx.GetAddress();
configuration.sys_ro_memory = user_ro; configuration.user_ro_memory.size = user_ro.GetSize();
configuration.sys_rx_memory = user_rx; configuration.user_ro_memory.offset = user_ro.GetAddress();
configuration.sys_rx_memory = configuration.user_rx_memory;
configuration.sys_ro_memory = configuration.user_ro_memory;
} }
void GenerateCode(HLERequestContext& ctx) { void GenerateCode(HLERequestContext& ctx) {
@ -318,6 +323,8 @@ private:
} }
Kernel::KScopedAutoObject<Kernel::KProcess> process; Kernel::KScopedAutoObject<Kernel::KProcess> process;
CodeMemory user_rx;
CodeMemory user_ro;
GuestCallbacks callbacks; GuestCallbacks callbacks;
JITConfiguration configuration; JITConfiguration configuration;
JITContext context; JITContext context;
@ -335,6 +342,7 @@ public:
RegisterHandlers(functions); RegisterHandlers(functions);
} }
private:
void CreateJitEnvironment(HLERequestContext& ctx) { void CreateJitEnvironment(HLERequestContext& ctx) {
LOG_DEBUG(Service_JIT, "called"); LOG_DEBUG(Service_JIT, "called");
@ -380,20 +388,35 @@ public:
return; return;
} }
const CodeRange user_rx{ CodeMemory rx, ro;
.offset = GetInteger(rx_mem->GetSourceAddress()), Result res;
.size = parameters.rx_size,
};
const CodeRange user_ro{ res = rx.Initialize(*process, *rx_mem, parameters.rx_size,
.offset = GetInteger(ro_mem->GetSourceAddress()), Kernel::Svc::MemoryPermission::ReadExecute, generate_random);
.size = parameters.ro_size, if (R_FAILED(res)) {
}; LOG_ERROR(Service_JIT, "rx_mem could not be mapped for handle=0x{:08X}", rx_mem_handle);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(res);
return;
}
res = ro.Initialize(*process, *ro_mem, parameters.ro_size,
Kernel::Svc::MemoryPermission::Read, generate_random);
if (R_FAILED(res)) {
LOG_ERROR(Service_JIT, "ro_mem could not be mapped for handle=0x{:08X}", ro_mem_handle);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(res);
return;
}
IPC::ResponseBuilder rb{ctx, 2, 0, 1}; IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
rb.PushIpcInterface<IJitEnvironment>(system, *process, user_rx, user_ro); rb.PushIpcInterface<IJitEnvironment>(system, std::move(process), std::move(rx),
std::move(ro));
} }
private:
std::mt19937_64 generate_random{};
}; };
void LoopProcess(Core::System& system) { void LoopProcess(Core::System& system) {

View File

@ -0,0 +1,54 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/jit/jit_code_memory.h"
namespace Service::JIT {
Result CodeMemory::Initialize(Kernel::KProcess& process, Kernel::KCodeMemory& code_memory,
size_t size, Kernel::Svc::MemoryPermission perm,
std::mt19937_64& generate_random) {
auto& page_table = process.GetPageTable();
const u64 alias_code_start =
GetInteger(page_table.GetAliasCodeRegionStart()) / Kernel::PageSize;
const u64 alias_code_size = page_table.GetAliasCodeRegionSize() / Kernel::PageSize;
// NOTE: This will retry indefinitely until mapping the code memory succeeds.
while (true) {
// Generate a new trial address.
const u64 mapped_address =
(alias_code_start + (generate_random() % alias_code_size)) * Kernel::PageSize;
// Try to map the address
R_TRY_CATCH(code_memory.MapToOwner(mapped_address, size, perm)) {
R_CATCH(Kernel::ResultInvalidMemoryRegion) {
// If we could not map here, retry.
continue;
}
}
R_END_TRY_CATCH;
// Set members.
m_code_memory = std::addressof(code_memory);
m_size = size;
m_address = mapped_address;
m_perm = perm;
// Open a new reference to the code memory.
m_code_memory->Open();
// We succeeded.
R_SUCCEED();
}
}
void CodeMemory::Finalize() {
if (m_code_memory) {
R_ASSERT(m_code_memory->UnmapFromOwner(m_address, m_size));
m_code_memory->Close();
}
m_code_memory = nullptr;
}
} // namespace Service::JIT

View File

@ -0,0 +1,49 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <random>
#include "core/hle/kernel/k_code_memory.h"
namespace Service::JIT {
class CodeMemory {
public:
YUZU_NON_COPYABLE(CodeMemory);
explicit CodeMemory() = default;
CodeMemory(CodeMemory&& rhs) {
std::swap(m_code_memory, rhs.m_code_memory);
std::swap(m_size, rhs.m_size);
std::swap(m_address, rhs.m_address);
std::swap(m_perm, rhs.m_perm);
}
~CodeMemory() {
this->Finalize();
}
public:
Result Initialize(Kernel::KProcess& process, Kernel::KCodeMemory& code_memory, size_t size,
Kernel::Svc::MemoryPermission perm, std::mt19937_64& generate_random);
void Finalize();
size_t GetSize() const {
return m_size;
}
u64 GetAddress() const {
return m_address;
}
private:
Kernel::KCodeMemory* m_code_memory{};
size_t m_size{};
u64 m_address{};
Kernel::Svc::MemoryPermission m_perm{};
};
} // namespace Service::JIT

View File

@ -5342,6 +5342,10 @@ int main(int argc, char* argv[]) {
if (QString::fromLocal8Bit(qgetenv("DISPLAY")).isEmpty()) { if (QString::fromLocal8Bit(qgetenv("DISPLAY")).isEmpty()) {
qputenv("DISPLAY", ":0"); qputenv("DISPLAY", ":0");
} }
// Fix the Wayland appId. This needs to match the name of the .desktop file without the .desktop
// suffix.
QGuiApplication::setDesktopFileName(QStringLiteral("org.yuzu_emu.yuzu"));
#endif #endif
SetHighDPIAttributes(); SetHighDPIAttributes();

View File

@ -20,7 +20,7 @@ EmuWindow_SDL2::EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem_, Co
: input_subsystem{input_subsystem_}, system{system_} { : input_subsystem{input_subsystem_}, system{system_} {
input_subsystem->Initialize(); input_subsystem->Initialize();
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0) { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0) {
LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting..."); LOG_CRITICAL(Frontend, "Failed to initialize SDL2: {}, Exiting...", SDL_GetError());
exit(1); exit(1);
} }
SDL_SetMainReady(); SDL_SetMainReady();

View File

@ -28,7 +28,8 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsyste
SDL_SysWMinfo wm; SDL_SysWMinfo wm;
SDL_VERSION(&wm.version); SDL_VERSION(&wm.version);
if (SDL_GetWindowWMInfo(render_window, &wm) == SDL_FALSE) { if (SDL_GetWindowWMInfo(render_window, &wm) == SDL_FALSE) {
LOG_CRITICAL(Frontend, "Failed to get information from the window manager"); LOG_CRITICAL(Frontend, "Failed to get information from the window manager: {}",
SDL_GetError());
std::exit(EXIT_FAILURE); std::exit(EXIT_FAILURE);
} }