Skip to content

Commit

Permalink
Settings: Add option to disable DSB/fbfetch
Browse files Browse the repository at this point in the history
  • Loading branch information
stenzek committed Nov 28, 2023
1 parent 7fe3bfe commit e382f2b
Show file tree
Hide file tree
Showing 19 changed files with 106 additions and 59 deletions.
4 changes: 2 additions & 2 deletions src/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ if(WIN32)
endif()

if(MSVC)
if(${CPU_ARCH} STREQUAL "x64")
if(CPU_ARCH_X64)
enable_language(ASM_MASM)
target_sources(common PRIVATE fastjmp_x86.asm)
set_source_files_properties(fastjmp_x86.asm PROPERTIES COMPILE_FLAGS "/D_M_X86_64")
elseif(${CPU_ARCH} STREQUAL "aarch32" OR ${CPU_ARCH} STREQUAL "aarch64")
elseif(CPU_ARCH_ARM32 OR CPU_ARCH_ARM64)
enable_language(ASM_MARMASM)
target_sources(common PRIVATE fastjmp_arm.asm)
endif()
Expand Down
16 changes: 11 additions & 5 deletions src/core/host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,13 +241,19 @@ bool Host::CreateGPUDevice(RenderAPI api)
Log_InfoPrintf("Trying to create a %s GPU device...", GPUDevice::RenderAPIToString(api));
g_gpu_device = GPUDevice::CreateDeviceForAPI(api);

u32 disabled_features = 0;
if (g_settings.gpu_disable_dual_source_blend)
disabled_features |= GPUDevice::FEATURE_MASK_DUAL_SOURCE_BLEND;
if (g_settings.gpu_disable_framebuffer_fetch)
disabled_features |= GPUDevice::FEATURE_MASK_FRAMEBUFFER_FETCH;

// TODO: FSUI should always use vsync..
const bool vsync = System::IsValid() ? System::ShouldUseVSync() : g_settings.video_sync_enabled;
if (!g_gpu_device || !g_gpu_device->Create(g_settings.gpu_adapter,
g_settings.gpu_disable_shader_cache ? std::string_view() :
std::string_view(EmuFolders::Cache),
SHADER_CACHE_VERSION, g_settings.gpu_use_debug_device, vsync,
g_settings.gpu_threaded_presentation))
if (!g_gpu_device || !g_gpu_device->Create(
g_settings.gpu_adapter,
g_settings.gpu_disable_shader_cache ? std::string_view() : std::string_view(EmuFolders::Cache),
SHADER_CACHE_VERSION, g_settings.gpu_use_debug_device, vsync,
g_settings.gpu_threaded_presentation, static_cast<GPUDevice::FeatureMask>(disabled_features)))
{
Log_ErrorPrintf("Failed to create GPU device.");
if (g_gpu_device)
Expand Down
4 changes: 4 additions & 0 deletions src/core/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ void Settings::Load(SettingsInterface& si)
gpu_multisamples = static_cast<u32>(si.GetIntValue("GPU", "Multisamples", 1));
gpu_use_debug_device = si.GetBoolValue("GPU", "UseDebugDevice", false);
gpu_disable_shader_cache = si.GetBoolValue("GPU", "DisableShaderCache", false);
gpu_disable_dual_source_blend = si.GetBoolValue("GPU", "DisableDualSourceBlend", false);
gpu_disable_framebuffer_fetch = si.GetBoolValue("GPU", "DisableFramebufferFetch", false);
gpu_per_sample_shading = si.GetBoolValue("GPU", "PerSampleShading", false);
gpu_use_thread = si.GetBoolValue("GPU", "UseThread", true);
gpu_use_software_renderer_for_readbacks = si.GetBoolValue("GPU", "UseSoftwareRendererForReadbacks", false);
Expand Down Expand Up @@ -437,6 +439,8 @@ void Settings::Save(SettingsInterface& si) const
si.SetIntValue("GPU", "Multisamples", static_cast<long>(gpu_multisamples));
si.SetBoolValue("GPU", "UseDebugDevice", gpu_use_debug_device);
si.SetBoolValue("GPU", "DisableShaderCache", gpu_disable_shader_cache);
si.SetBoolValue("GPU", "DisableDualSourceBlend", gpu_disable_dual_source_blend);
si.SetBoolValue("GPU", "DisableFramebufferFetch", gpu_disable_framebuffer_fetch);
si.SetBoolValue("GPU", "PerSampleShading", gpu_per_sample_shading);
si.SetBoolValue("GPU", "UseThread", gpu_use_thread);
si.SetBoolValue("GPU", "ThreadedPresentation", gpu_threaded_presentation);
Expand Down
2 changes: 2 additions & 0 deletions src/core/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ struct Settings
bool gpu_threaded_presentation = true;
bool gpu_use_debug_device = false;
bool gpu_disable_shader_cache = false;
bool gpu_disable_dual_source_blend = false;
bool gpu_disable_framebuffer_fetch = false;
bool gpu_per_sample_shading = false;
bool gpu_true_color = true;
bool gpu_scaled_dithering = true;
Expand Down
13 changes: 10 additions & 3 deletions src/core/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3525,11 +3525,18 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
{
if (IsValid() && (g_settings.gpu_renderer != old_settings.gpu_renderer ||
g_settings.gpu_use_debug_device != old_settings.gpu_use_debug_device ||
g_settings.gpu_threaded_presentation != old_settings.gpu_threaded_presentation))
g_settings.gpu_threaded_presentation != old_settings.gpu_threaded_presentation ||
g_settings.gpu_disable_shader_cache != old_settings.gpu_disable_shader_cache ||
g_settings.gpu_disable_dual_source_blend != old_settings.gpu_disable_dual_source_blend ||
g_settings.gpu_disable_framebuffer_fetch != old_settings.gpu_disable_framebuffer_fetch))
{
// if debug device/threaded presentation change, we need to recreate the whole display
const bool recreate_device = (g_settings.gpu_use_debug_device != old_settings.gpu_use_debug_device ||
g_settings.gpu_threaded_presentation != old_settings.gpu_threaded_presentation);
const bool recreate_device =
(g_settings.gpu_use_debug_device != old_settings.gpu_use_debug_device ||
g_settings.gpu_threaded_presentation != old_settings.gpu_threaded_presentation ||
g_settings.gpu_disable_shader_cache != old_settings.gpu_disable_shader_cache ||
g_settings.gpu_disable_dual_source_blend != old_settings.gpu_disable_dual_source_blend ||
g_settings.gpu_disable_framebuffer_fetch != old_settings.gpu_disable_framebuffer_fetch);

Host::AddIconOSDMessage("RendererSwitch", ICON_FA_PAINT_ROLLER,
fmt::format(TRANSLATE_FS("OSDMessage", "Switching to {}{} GPU renderer."),
Expand Down
9 changes: 9 additions & 0 deletions src/duckstation-qt/advancedsettingswidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,10 @@ void AdvancedSettingsWidget::addTweakOptions()
false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Disable Shader Cache"), "GPU", "DisableShaderCache",
false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Disable Dual-Source Blend"), "GPU",
"DisableDualSourceBlend", false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Disable Framebuffer Fetch"), "GPU",
"DisableFramebufferFetch", false);

addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Stretch Display Vertically"), "Display",
"StretchVertically", false);
Expand Down Expand Up @@ -401,6 +405,8 @@ void AdvancedSettingsWidget::onResetToDefaultClicked()
static_cast<int>(Settings::DEFAULT_GPU_MAX_RUN_AHEAD)); // GPU max run-ahead
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Use debug host GPU device
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Disable Shader Cache
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Disable Dual-Source Blend
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Disable Framebuffer Fetch
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Stretch Display Vertically
setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Increase Timer Resolution
setChoiceTweakOption(m_ui.tweakOptionTable, i++,
Expand Down Expand Up @@ -447,6 +453,9 @@ void AdvancedSettingsWidget::onResetToDefaultClicked()
sif->DeleteValue("Hacks", "GPUFIFOSize");
sif->DeleteValue("Hacks", "GPUMaxRunAhead");
sif->DeleteValue("GPU", "UseDebugDevice");
sif->DeleteValue("GPU", "DisableShaderCache");
sif->DeleteValue("GPU", "DisableDualSourceBlend");
sif->DeleteValue("GPU", "DisableFramebufferFetch");
sif->DeleteValue("Display", "StretchVertically");
sif->DeleteValue("Main", "IncreaseTimerResolution");
sif->DeleteValue("CDROM", "MechaconVersion");
Expand Down
13 changes: 7 additions & 6 deletions src/util/d3d11_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ bool D3D11Device::HasSurface() const
return static_cast<bool>(m_swap_chain);
}

bool D3D11Device::CreateDevice(const std::string_view& adapter, bool threaded_presentation)
bool D3D11Device::CreateDevice(const std::string_view& adapter, bool threaded_presentation,
FeatureMask disabled_features)
{
std::unique_lock lock(s_instance_mutex);

Expand Down Expand Up @@ -131,7 +132,7 @@ bool D3D11Device::CreateDevice(const std::string_view& adapter, bool threaded_pr
sizeof(allow_tearing_supported));
m_allow_tearing_supported = (SUCCEEDED(hr) && allow_tearing_supported == TRUE);

SetFeatures();
SetFeatures(disabled_features);

if (m_window_info.type != WindowInfo::Type::Surfaceless && !CreateSwapChain())
return false;
Expand All @@ -152,7 +153,7 @@ void D3D11Device::DestroyDevice()
m_device.Reset();
}

void D3D11Device::SetFeatures()
void D3D11Device::SetFeatures(FeatureMask disabled_features)
{
const D3D_FEATURE_LEVEL feature_level = m_device->GetFeatureLevel();

Expand All @@ -169,13 +170,13 @@ void D3D11Device::SetFeatures()
}
}

m_features.dual_source_blend = true;
m_features.dual_source_blend = !(disabled_features & FEATURE_MASK_DUAL_SOURCE_BLEND);
m_features.framebuffer_fetch = false;
m_features.per_sample_shading = (feature_level >= D3D_FEATURE_LEVEL_10_1);
m_features.noperspective_interpolation = true;
m_features.supports_texture_buffers = true;
m_features.supports_texture_buffers = !(disabled_features & FEATURE_MASK_TEXTURE_BUFFERS);
m_features.texture_buffers_emulated_with_ssbo = false;
m_features.geometry_shaders = true;
m_features.geometry_shaders = !(disabled_features & FEATURE_MASK_GEOMETRY_SHADERS);
m_features.partial_msaa_resolve = false;
m_features.gpu_timing = true;
m_features.shader_cache = true;
Expand Down
4 changes: 2 additions & 2 deletions src/util/d3d11_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class D3D11Device final : public GPUDevice
static AdapterAndModeList StaticGetAdapterAndModeList();

protected:
bool CreateDevice(const std::string_view& adapter, bool threaded_presentation) override;
bool CreateDevice(const std::string_view& adapter, bool threaded_presentation, FeatureMask disabled_features) override;
void DestroyDevice() override;

private:
Expand All @@ -129,7 +129,7 @@ class D3D11Device final : public GPUDevice

static void GetAdapterAndModeList(AdapterAndModeList* ret, IDXGIFactory5* factory);

void SetFeatures();
void SetFeatures(FeatureMask disabled_features);

bool CheckStagingBufferSize(u32 width, u32 height, DXGI_FORMAT format);
void DestroyStagingBuffer();
Expand Down
14 changes: 7 additions & 7 deletions src/util/d3d12_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ D3D12Device::ComPtr<ID3D12RootSignature> D3D12Device::CreateRootSignature(const
return rs;
}

bool D3D12Device::CreateDevice(const std::string_view& adapter, bool threaded_presentation)
bool D3D12Device::CreateDevice(const std::string_view& adapter, bool threaded_presentation, FeatureMask disabled_features)
{
std::unique_lock lock(s_instance_mutex);

Expand Down Expand Up @@ -223,7 +223,7 @@ bool D3D12Device::CreateDevice(const std::string_view& adapter, bool threaded_pr
return false;
}

SetFeatures();
SetFeatures(disabled_features);

if (!CreateCommandLists() || !CreateDescriptorHeaps())
return false;
Expand Down Expand Up @@ -1156,7 +1156,7 @@ void D3D12Device::InsertDebugMessage(const char* msg)
#endif
}

void D3D12Device::SetFeatures()
void D3D12Device::SetFeatures(FeatureMask disabled_features)
{
m_max_texture_size = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION;
m_max_multisamples = 1;
Expand All @@ -1172,13 +1172,13 @@ void D3D12Device::SetFeatures()
}
}

m_features.dual_source_blend = true;
m_features.dual_source_blend = !(disabled_features & FEATURE_MASK_DUAL_SOURCE_BLEND);
m_features.framebuffer_fetch = false;
m_features.noperspective_interpolation = true;
m_features.per_sample_shading = true;
m_features.supports_texture_buffers = true;
m_features.noperspective_interpolation = true;
m_features.supports_texture_buffers = !(disabled_features & FEATURE_MASK_TEXTURE_BUFFERS);
m_features.texture_buffers_emulated_with_ssbo = false;
m_features.geometry_shaders = true;
m_features.geometry_shaders = !(disabled_features & FEATURE_MASK_GEOMETRY_SHADERS);
m_features.partial_msaa_resolve = true;
m_features.gpu_timing = true;
m_features.shader_cache = true;
Expand Down
5 changes: 3 additions & 2 deletions src/util/d3d12_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ class D3D12Device final : public GPUDevice
void UnbindTextureBuffer(D3D12TextureBuffer* buf);

protected:
bool CreateDevice(const std::string_view& adapter, bool threaded_presentation) override;
bool CreateDevice(const std::string_view& adapter, bool threaded_presentation,
FeatureMask disabled_features) override;
void DestroyDevice() override;

bool ReadPipelineCache(const std::string& filename) override;
Expand Down Expand Up @@ -215,7 +216,7 @@ class D3D12Device final : public GPUDevice

static void GetAdapterAndModeList(AdapterAndModeList* ret, IDXGIFactory5* factory);

void SetFeatures();
void SetFeatures(FeatureMask disabled_features);

bool CreateSwapChain();
bool CreateSwapChainRTV();
Expand Down
5 changes: 3 additions & 2 deletions src/util/gpu_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ bool GPUDevice::IsSameRenderAPI(RenderAPI lhs, RenderAPI rhs)
}

bool GPUDevice::Create(const std::string_view& adapter, const std::string_view& shader_cache_path,
u32 shader_cache_version, bool debug_device, bool vsync, bool threaded_presentation)
u32 shader_cache_version, bool debug_device, bool vsync, bool threaded_presentation,
FeatureMask disabled_features)
{
m_vsync_enabled = vsync;
m_debug_device = debug_device;
Expand All @@ -234,7 +235,7 @@ bool GPUDevice::Create(const std::string_view& adapter, const std::string_view&
return false;
}

if (!CreateDevice(adapter, threaded_presentation))
if (!CreateDevice(adapter, threaded_presentation, disabled_features))
{
Log_ErrorPrintf("Failed to create device.");
return false;
Expand Down
12 changes: 10 additions & 2 deletions src/util/gpu_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,14 @@ class GPUDevice
// TODO: gpu crash handling on present
using DrawIndex = u16;

enum FeatureMask : u32
{
FEATURE_MASK_DUAL_SOURCE_BLEND = (1 << 0),
FEATURE_MASK_FRAMEBUFFER_FETCH = (1 << 1),
FEATURE_MASK_TEXTURE_BUFFERS = (1 << 2),
FEATURE_MASK_GEOMETRY_SHADERS = (1 << 3),
};

struct Features
{
bool dual_source_blend : 1;
Expand Down Expand Up @@ -531,7 +539,7 @@ class GPUDevice
virtual RenderAPI GetRenderAPI() const = 0;

bool Create(const std::string_view& adapter, const std::string_view& shader_cache_path, u32 shader_cache_version,
bool debug_device, bool vsync, bool threaded_presentation);
bool debug_device, bool vsync, bool threaded_presentation, FeatureMask disabled_features);
void Destroy();

virtual bool HasSurface() const = 0;
Expand Down Expand Up @@ -636,7 +644,7 @@ class GPUDevice
virtual float GetAndResetAccumulatedGPUTime();

protected:
virtual bool CreateDevice(const std::string_view& adapter, bool threaded_presentation) = 0;
virtual bool CreateDevice(const std::string_view& adapter, bool threaded_presentation, FeatureMask disabled_features) = 0;
virtual void DestroyDevice() = 0;

std::string GetShaderCacheBaseName(const std::string_view& type) const;
Expand Down
4 changes: 2 additions & 2 deletions src/util/metal_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ class MetalDevice final : public GPUDevice
static AdapterAndModeList StaticGetAdapterAndModeList();

protected:
bool CreateDevice(const std::string_view& adapter, bool threaded_presentation) override;
bool CreateDevice(const std::string_view& adapter, bool threaded_presentation, FeatureMask disabled_features) override;
void DestroyDevice() override;

private:
Expand All @@ -298,7 +298,7 @@ class MetalDevice final : public GPUDevice

ALWAYS_INLINE NSView* GetWindowView() const { return (__bridge NSView*)m_window_info.window_handle; }

void SetFeatures();
void SetFeatures(FeatureMask disabled_features);
bool LoadShaders();

id<MTLFunction> GetFunctionFromLibrary(id<MTLLibrary> library, NSString* name);
Expand Down
12 changes: 6 additions & 6 deletions src/util/metal_device.mm
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ static void RunOnMainThread(F&& f)
[m_layer setDisplaySyncEnabled:enabled];
}

bool MetalDevice::CreateDevice(const std::string_view& adapter, bool threaded_presentation)
bool MetalDevice::CreateDevice(const std::string_view& adapter, bool threaded_presentation, FeatureMask disabled_features)
{
@autoreleasepool
{
Expand Down Expand Up @@ -166,7 +166,7 @@ static void RunOnMainThread(F&& f)
m_queue = [queue retain];
Log_InfoPrintf("Metal Device: %s", [[m_device name] UTF8String]);

SetFeatures();
SetFeatures(disabled_features);

if (m_window_info.type != WindowInfo::Type::Surfaceless && !CreateLayer())
return false;
Expand All @@ -190,7 +190,7 @@ static void RunOnMainThread(F&& f)
}
}

void MetalDevice::SetFeatures()
void MetalDevice::SetFeatures(FeatureMask disabled_features)
{
// https://gist.github.com/kylehowells/63d0723abc9588eb734cade4b7df660d
if ([m_device supportsFamily:MTLGPUFamilyMacCatalyst1] || [m_device supportsFamily:MTLGPUFamilyMac1] ||
Expand All @@ -211,11 +211,11 @@ static void RunOnMainThread(F&& f)
m_max_multisamples = multisamples;
}

m_features.dual_source_blend = true;
m_features.framebuffer_fetch = false; // TODO
m_features.dual_source_blend = !(disabled_features & FEATURE_MASK_DUAL_SOURCE_BLEND);
m_features.framebuffer_fetch = !(disabled_features & FEATURE_MASK_FRAMEBUFFER_FETCH) && false; // TODO
m_features.per_sample_shading = true;
m_features.noperspective_interpolation = true;
m_features.supports_texture_buffers = true;
m_features.supports_texture_buffers = !(disabled_features & FEATURE_MASK_TEXTURE_BUFFERS);
m_features.texture_buffers_emulated_with_ssbo = true;
m_features.geometry_shaders = false;
m_features.partial_msaa_resolve = false;
Expand Down
Loading

0 comments on commit e382f2b

Please sign in to comment.