General: Add settings for fastmem and disabling adress space check.
This commit is contained in:
parent
c4609c92ee
commit
5ba28325b2
@ -90,6 +90,13 @@ bool IsGPULevelHigh() {
|
|||||||
values.gpu_accuracy.GetValue() == GPUAccuracy::High;
|
values.gpu_accuracy.GetValue() == GPUAccuracy::High;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsFastmemEnabled() {
|
||||||
|
if (values.cpu_accuracy.GetValue() == CPUAccuracy::DebugMode) {
|
||||||
|
return values.cpuopt_fastmem;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
float Volume() {
|
float Volume() {
|
||||||
if (values.audio_muted) {
|
if (values.audio_muted) {
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
@ -115,6 +122,7 @@ void RestoreGlobalState(bool is_powered_on) {
|
|||||||
values.cpuopt_unsafe_unfuse_fma.SetGlobal(true);
|
values.cpuopt_unsafe_unfuse_fma.SetGlobal(true);
|
||||||
values.cpuopt_unsafe_reduce_fp_error.SetGlobal(true);
|
values.cpuopt_unsafe_reduce_fp_error.SetGlobal(true);
|
||||||
values.cpuopt_unsafe_inaccurate_nan.SetGlobal(true);
|
values.cpuopt_unsafe_inaccurate_nan.SetGlobal(true);
|
||||||
|
values.cpuopt_unsafe_fastmem_check.SetGlobal(true);
|
||||||
|
|
||||||
// Renderer
|
// Renderer
|
||||||
values.renderer_backend.SetGlobal(true);
|
values.renderer_backend.SetGlobal(true);
|
||||||
|
@ -125,10 +125,12 @@ struct Values {
|
|||||||
bool cpuopt_const_prop;
|
bool cpuopt_const_prop;
|
||||||
bool cpuopt_misc_ir;
|
bool cpuopt_misc_ir;
|
||||||
bool cpuopt_reduce_misalign_checks;
|
bool cpuopt_reduce_misalign_checks;
|
||||||
|
bool cpuopt_fastmem;
|
||||||
|
|
||||||
Setting<bool> cpuopt_unsafe_unfuse_fma;
|
Setting<bool> cpuopt_unsafe_unfuse_fma;
|
||||||
Setting<bool> cpuopt_unsafe_reduce_fp_error;
|
Setting<bool> cpuopt_unsafe_reduce_fp_error;
|
||||||
Setting<bool> cpuopt_unsafe_inaccurate_nan;
|
Setting<bool> cpuopt_unsafe_inaccurate_nan;
|
||||||
|
Setting<bool> cpuopt_unsafe_fastmem_check;
|
||||||
|
|
||||||
// Renderer
|
// Renderer
|
||||||
Setting<RendererBackend> renderer_backend;
|
Setting<RendererBackend> renderer_backend;
|
||||||
@ -249,6 +251,8 @@ void SetConfiguringGlobal(bool is_global);
|
|||||||
bool IsGPULevelExtreme();
|
bool IsGPULevelExtreme();
|
||||||
bool IsGPULevelHigh();
|
bool IsGPULevelHigh();
|
||||||
|
|
||||||
|
bool IsFastmemEnabled();
|
||||||
|
|
||||||
float Volume();
|
float Volume();
|
||||||
|
|
||||||
std::string GetTimeZoneString();
|
std::string GetTimeZoneString();
|
||||||
|
@ -144,7 +144,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
|
|||||||
|
|
||||||
// Code cache size
|
// Code cache size
|
||||||
config.code_cache_size = 512 * 1024 * 1024;
|
config.code_cache_size = 512 * 1024 * 1024;
|
||||||
config.far_code_offset = 256 * 1024 * 1024;
|
config.far_code_offset = 400 * 1024 * 1024;
|
||||||
|
|
||||||
// Safe optimizations
|
// Safe optimizations
|
||||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::DebugMode) {
|
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::DebugMode) {
|
||||||
@ -172,6 +172,9 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
|
|||||||
if (!Settings::values.cpuopt_reduce_misalign_checks) {
|
if (!Settings::values.cpuopt_reduce_misalign_checks) {
|
||||||
config.only_detect_misalignment_via_page_table_on_page_boundary = false;
|
config.only_detect_misalignment_via_page_table_on_page_boundary = false;
|
||||||
}
|
}
|
||||||
|
if (!Settings::values.cpuopt_fastmem) {
|
||||||
|
config.fastmem_pointer = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unsafe optimizations
|
// Unsafe optimizations
|
||||||
|
@ -185,7 +185,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
|
|||||||
|
|
||||||
// Code cache size
|
// Code cache size
|
||||||
config.code_cache_size = 512 * 1024 * 1024;
|
config.code_cache_size = 512 * 1024 * 1024;
|
||||||
config.far_code_offset = 256 * 1024 * 1024;
|
config.far_code_offset = 400 * 1024 * 1024;
|
||||||
|
|
||||||
// Safe optimizations
|
// Safe optimizations
|
||||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::DebugMode) {
|
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::DebugMode) {
|
||||||
@ -213,6 +213,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
|
|||||||
if (!Settings::values.cpuopt_reduce_misalign_checks) {
|
if (!Settings::values.cpuopt_reduce_misalign_checks) {
|
||||||
config.only_detect_misalignment_via_page_table_on_page_boundary = false;
|
config.only_detect_misalignment_via_page_table_on_page_boundary = false;
|
||||||
}
|
}
|
||||||
|
if (!Settings::values.cpuopt_fastmem) {
|
||||||
|
config.fastmem_pointer = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unsafe optimizations
|
// Unsafe optimizations
|
||||||
@ -227,6 +230,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
|
|||||||
if (Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue()) {
|
if (Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue()) {
|
||||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
|
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
|
||||||
}
|
}
|
||||||
|
if (Settings::values.cpuopt_unsafe_fastmem_check.GetValue()) {
|
||||||
|
config.fastmem_address_space_bits = 64;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_shared<Dynarmic::A64::Jit>(config);
|
return std::make_shared<Dynarmic::A64::Jit>(config);
|
||||||
|
@ -47,7 +47,9 @@ struct Memory::Impl {
|
|||||||
"Out of bounds target: {:016X}", target);
|
"Out of bounds target: {:016X}", target);
|
||||||
MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, Common::PageType::Memory);
|
MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, Common::PageType::Memory);
|
||||||
|
|
||||||
system.DeviceMemory().buffer.Map(base, target - DramMemoryMap::Base, size);
|
if (Settings::IsFastmemEnabled()) {
|
||||||
|
system.DeviceMemory().buffer.Map(base, target - DramMemoryMap::Base, size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) {
|
void UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) {
|
||||||
@ -55,7 +57,9 @@ struct Memory::Impl {
|
|||||||
ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base);
|
ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base);
|
||||||
MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, 0, Common::PageType::Unmapped);
|
MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, 0, Common::PageType::Unmapped);
|
||||||
|
|
||||||
system.DeviceMemory().buffer.Unmap(base, size);
|
if (Settings::IsFastmemEnabled()) {
|
||||||
|
system.DeviceMemory().buffer.Unmap(base, size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsValidVirtualAddress(const Kernel::KProcess& process, const VAddr vaddr) const {
|
bool IsValidVirtualAddress(const Kernel::KProcess& process, const VAddr vaddr) const {
|
||||||
@ -475,8 +479,10 @@ struct Memory::Impl {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool is_read_enable = Settings::IsGPULevelHigh() || !cached;
|
if (Settings::IsFastmemEnabled()) {
|
||||||
system.DeviceMemory().buffer.Protect(vaddr, size, is_read_enable, !cached);
|
const bool is_read_enable = Settings::IsGPULevelHigh() || !cached;
|
||||||
|
system.DeviceMemory().buffer.Protect(vaddr, size, is_read_enable, !cached);
|
||||||
|
}
|
||||||
|
|
||||||
// Iterate over a contiguous CPU address space, which corresponds to the specified GPU
|
// Iterate over a contiguous CPU address space, which corresponds to the specified GPU
|
||||||
// address space, marking the region as un/cached. The region is marked un/cached at a
|
// address space, marking the region as un/cached. The region is marked un/cached at a
|
||||||
|
@ -756,6 +756,8 @@ void Config::ReadCpuValues() {
|
|||||||
QStringLiteral("cpuopt_unsafe_reduce_fp_error"), true);
|
QStringLiteral("cpuopt_unsafe_reduce_fp_error"), true);
|
||||||
ReadSettingGlobal(Settings::values.cpuopt_unsafe_inaccurate_nan,
|
ReadSettingGlobal(Settings::values.cpuopt_unsafe_inaccurate_nan,
|
||||||
QStringLiteral("cpuopt_unsafe_inaccurate_nan"), true);
|
QStringLiteral("cpuopt_unsafe_inaccurate_nan"), true);
|
||||||
|
ReadSettingGlobal(Settings::values.cpuopt_unsafe_fastmem_check,
|
||||||
|
QStringLiteral("cpuopt_unsafe_fastmem_check"), true);
|
||||||
|
|
||||||
if (global) {
|
if (global) {
|
||||||
Settings::values.cpuopt_page_tables =
|
Settings::values.cpuopt_page_tables =
|
||||||
@ -774,6 +776,8 @@ void Config::ReadCpuValues() {
|
|||||||
ReadSetting(QStringLiteral("cpuopt_misc_ir"), true).toBool();
|
ReadSetting(QStringLiteral("cpuopt_misc_ir"), true).toBool();
|
||||||
Settings::values.cpuopt_reduce_misalign_checks =
|
Settings::values.cpuopt_reduce_misalign_checks =
|
||||||
ReadSetting(QStringLiteral("cpuopt_reduce_misalign_checks"), true).toBool();
|
ReadSetting(QStringLiteral("cpuopt_reduce_misalign_checks"), true).toBool();
|
||||||
|
Settings::values.cpuopt_fastmem =
|
||||||
|
ReadSetting(QStringLiteral("cpuopt_fastmem"), true).toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
@ -1332,6 +1336,8 @@ void Config::SaveCpuValues() {
|
|||||||
Settings::values.cpuopt_unsafe_reduce_fp_error, true);
|
Settings::values.cpuopt_unsafe_reduce_fp_error, true);
|
||||||
WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_inaccurate_nan"),
|
WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_inaccurate_nan"),
|
||||||
Settings::values.cpuopt_unsafe_inaccurate_nan, true);
|
Settings::values.cpuopt_unsafe_inaccurate_nan, true);
|
||||||
|
WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_fastmem_check"),
|
||||||
|
Settings::values.cpuopt_unsafe_fastmem_check, true);
|
||||||
|
|
||||||
if (global) {
|
if (global) {
|
||||||
WriteSetting(QStringLiteral("cpuopt_page_tables"), Settings::values.cpuopt_page_tables,
|
WriteSetting(QStringLiteral("cpuopt_page_tables"), Settings::values.cpuopt_page_tables,
|
||||||
@ -1348,6 +1354,7 @@ void Config::SaveCpuValues() {
|
|||||||
WriteSetting(QStringLiteral("cpuopt_misc_ir"), Settings::values.cpuopt_misc_ir, true);
|
WriteSetting(QStringLiteral("cpuopt_misc_ir"), Settings::values.cpuopt_misc_ir, true);
|
||||||
WriteSetting(QStringLiteral("cpuopt_reduce_misalign_checks"),
|
WriteSetting(QStringLiteral("cpuopt_reduce_misalign_checks"),
|
||||||
Settings::values.cpuopt_reduce_misalign_checks, true);
|
Settings::values.cpuopt_reduce_misalign_checks, true);
|
||||||
|
WriteSetting(QStringLiteral("cpuopt_fastmem"), Settings::values.cpuopt_fastmem, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
|
@ -35,12 +35,15 @@ void ConfigureCpu::SetConfiguration() {
|
|||||||
ui->cpuopt_unsafe_unfuse_fma->setEnabled(runtime_lock);
|
ui->cpuopt_unsafe_unfuse_fma->setEnabled(runtime_lock);
|
||||||
ui->cpuopt_unsafe_reduce_fp_error->setEnabled(runtime_lock);
|
ui->cpuopt_unsafe_reduce_fp_error->setEnabled(runtime_lock);
|
||||||
ui->cpuopt_unsafe_inaccurate_nan->setEnabled(runtime_lock);
|
ui->cpuopt_unsafe_inaccurate_nan->setEnabled(runtime_lock);
|
||||||
|
ui->cpuopt_unsafe_fastmem_check->setEnabled(runtime_lock);
|
||||||
|
|
||||||
ui->cpuopt_unsafe_unfuse_fma->setChecked(Settings::values.cpuopt_unsafe_unfuse_fma.GetValue());
|
ui->cpuopt_unsafe_unfuse_fma->setChecked(Settings::values.cpuopt_unsafe_unfuse_fma.GetValue());
|
||||||
ui->cpuopt_unsafe_reduce_fp_error->setChecked(
|
ui->cpuopt_unsafe_reduce_fp_error->setChecked(
|
||||||
Settings::values.cpuopt_unsafe_reduce_fp_error.GetValue());
|
Settings::values.cpuopt_unsafe_reduce_fp_error.GetValue());
|
||||||
ui->cpuopt_unsafe_inaccurate_nan->setChecked(
|
ui->cpuopt_unsafe_inaccurate_nan->setChecked(
|
||||||
Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue());
|
Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue());
|
||||||
|
ui->cpuopt_unsafe_fastmem_check->setChecked(
|
||||||
|
Settings::values.cpuopt_unsafe_fastmem_check.GetValue());
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
ui->accuracy->setCurrentIndex(static_cast<int>(Settings::values.cpu_accuracy.GetValue()));
|
ui->accuracy->setCurrentIndex(static_cast<int>(Settings::values.cpu_accuracy.GetValue()));
|
||||||
@ -84,6 +87,9 @@ void ConfigureCpu::ApplyConfiguration() {
|
|||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_inaccurate_nan,
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_inaccurate_nan,
|
||||||
ui->cpuopt_unsafe_inaccurate_nan,
|
ui->cpuopt_unsafe_inaccurate_nan,
|
||||||
cpuopt_unsafe_inaccurate_nan);
|
cpuopt_unsafe_inaccurate_nan);
|
||||||
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_fastmem_check,
|
||||||
|
ui->cpuopt_unsafe_fastmem_check,
|
||||||
|
cpuopt_unsafe_fastmem_check);
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
// Guard if during game and set to game-specific value
|
// Guard if during game and set to game-specific value
|
||||||
@ -134,4 +140,7 @@ void ConfigureCpu::SetupPerGameUI() {
|
|||||||
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_inaccurate_nan,
|
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_inaccurate_nan,
|
||||||
Settings::values.cpuopt_unsafe_inaccurate_nan,
|
Settings::values.cpuopt_unsafe_inaccurate_nan,
|
||||||
cpuopt_unsafe_inaccurate_nan);
|
cpuopt_unsafe_inaccurate_nan);
|
||||||
|
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_fastmem_check,
|
||||||
|
Settings::values.cpuopt_unsafe_fastmem_check,
|
||||||
|
cpuopt_unsafe_fastmem_check);
|
||||||
}
|
}
|
||||||
|
@ -41,4 +41,5 @@ private:
|
|||||||
ConfigurationShared::CheckState cpuopt_unsafe_unfuse_fma;
|
ConfigurationShared::CheckState cpuopt_unsafe_unfuse_fma;
|
||||||
ConfigurationShared::CheckState cpuopt_unsafe_reduce_fp_error;
|
ConfigurationShared::CheckState cpuopt_unsafe_reduce_fp_error;
|
||||||
ConfigurationShared::CheckState cpuopt_unsafe_inaccurate_nan;
|
ConfigurationShared::CheckState cpuopt_unsafe_inaccurate_nan;
|
||||||
|
ConfigurationShared::CheckState cpuopt_unsafe_fastmem_check;
|
||||||
};
|
};
|
||||||
|
@ -123,6 +123,18 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="cpuopt_unsafe_fastmem_check">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>
|
||||||
|
<div>This option improves speed by eliminating a safety check before every memory read/write in guest. Disabling it may allow a game to read/write the emulator's memory.</div>
|
||||||
|
</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Disable address space checks</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -39,6 +39,8 @@ void ConfigureCpuDebug::SetConfiguration() {
|
|||||||
ui->cpuopt_misc_ir->setChecked(Settings::values.cpuopt_misc_ir);
|
ui->cpuopt_misc_ir->setChecked(Settings::values.cpuopt_misc_ir);
|
||||||
ui->cpuopt_reduce_misalign_checks->setEnabled(runtime_lock);
|
ui->cpuopt_reduce_misalign_checks->setEnabled(runtime_lock);
|
||||||
ui->cpuopt_reduce_misalign_checks->setChecked(Settings::values.cpuopt_reduce_misalign_checks);
|
ui->cpuopt_reduce_misalign_checks->setChecked(Settings::values.cpuopt_reduce_misalign_checks);
|
||||||
|
ui->cpuopt_fastmem->setEnabled(runtime_lock);
|
||||||
|
ui->cpuopt_fastmem->setChecked(Settings::values.cpuopt_fastmem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureCpuDebug::ApplyConfiguration() {
|
void ConfigureCpuDebug::ApplyConfiguration() {
|
||||||
@ -50,6 +52,7 @@ void ConfigureCpuDebug::ApplyConfiguration() {
|
|||||||
Settings::values.cpuopt_const_prop = ui->cpuopt_const_prop->isChecked();
|
Settings::values.cpuopt_const_prop = ui->cpuopt_const_prop->isChecked();
|
||||||
Settings::values.cpuopt_misc_ir = ui->cpuopt_misc_ir->isChecked();
|
Settings::values.cpuopt_misc_ir = ui->cpuopt_misc_ir->isChecked();
|
||||||
Settings::values.cpuopt_reduce_misalign_checks = ui->cpuopt_reduce_misalign_checks->isChecked();
|
Settings::values.cpuopt_reduce_misalign_checks = ui->cpuopt_reduce_misalign_checks->isChecked();
|
||||||
|
Settings::values.cpuopt_fastmem = ui->cpuopt_fastmem->isChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureCpuDebug::changeEvent(QEvent* event) {
|
void ConfigureCpuDebug::changeEvent(QEvent* event) {
|
||||||
|
@ -139,6 +139,20 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="cpuopt_fastmem">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable Host MMU Emulation</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>
|
||||||
|
<div style="white-space: nowrap">This optimization speeds up memory accesses by the guest program.</div>
|
||||||
|
<div style="white-space: nowrap">Enabling it causes guest memory reads/writes to be done directly into memory and make use of Host's MMU.</div>
|
||||||
|
<div style="white-space: nowrap">Disabling this forces all memory accesses to use Software MMU Emulation.</div>
|
||||||
|
</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -150,6 +150,10 @@ cpuopt_misc_ir =
|
|||||||
# 0: Disabled, 1 (default): Enabled
|
# 0: Disabled, 1 (default): Enabled
|
||||||
cpuopt_reduce_misalign_checks =
|
cpuopt_reduce_misalign_checks =
|
||||||
|
|
||||||
|
# Enable Host MMU Emulation (faster guest memory access)
|
||||||
|
# 0: Disabled, 1 (default): Enabled
|
||||||
|
cpuopt_fastmem =
|
||||||
|
|
||||||
[Renderer]
|
[Renderer]
|
||||||
# Which backend API to use.
|
# Which backend API to use.
|
||||||
# 0 (default): OpenGL, 1: Vulkan
|
# 0 (default): OpenGL, 1: Vulkan
|
||||||
|
Loading…
Reference in New Issue
Block a user