Settings: Add option to disable DSB/fbfetch
This commit is contained in:
parent
7fe3bfece0
commit
e382f2b64a
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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."),
|
||||
|
|
|
@ -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);
|
||||
|
@ -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++,
|
||||
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -111,7 +111,7 @@ public:
|
|||
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:
|
||||
|
@ -129,7 +129,7 @@ private:
|
|||
|
||||
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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -179,7 +179,8 @@ public:
|
|||
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;
|
||||
|
@ -215,7 +216,7 @@ private:
|
|||
|
||||
static void GetAdapterAndModeList(AdapterAndModeList* ret, IDXGIFactory5* factory);
|
||||
|
||||
void SetFeatures();
|
||||
void SetFeatures(FeatureMask disabled_features);
|
||||
|
||||
bool CreateSwapChain();
|
||||
bool CreateSwapChainRTV();
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -443,6 +443,14 @@ public:
|
|||
// 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;
|
||||
|
@ -531,7 +539,7 @@ public:
|
|||
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;
|
||||
|
@ -636,7 +644,7 @@ public:
|
|||
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;
|
||||
|
|
|
@ -283,7 +283,7 @@ public:
|
|||
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:
|
||||
|
@ -298,7 +298,7 @@ private:
|
|||
|
||||
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);
|
||||
|
|
|
@ -123,7 +123,7 @@ void MetalDevice::SetVSync(bool enabled)
|
|||
[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
|
||||
{
|
||||
|
@ -166,7 +166,7 @@ bool MetalDevice::CreateDevice(const std::string_view& adapter, bool threaded_pr
|
|||
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;
|
||||
|
@ -190,7 +190,7 @@ bool MetalDevice::CreateDevice(const std::string_view& adapter, bool threaded_pr
|
|||
}
|
||||
}
|
||||
|
||||
void MetalDevice::SetFeatures()
|
||||
void MetalDevice::SetFeatures(FeatureMask disabled_features)
|
||||
{
|
||||
// https://gist.github.com/kylehowells/63d0723abc9588eb734cade4b7df660d
|
||||
if ([m_device supportsFamily:MTLGPUFamilyMacCatalyst1] || [m_device supportsFamily:MTLGPUFamilyMac1] ||
|
||||
|
@ -211,11 +211,11 @@ void MetalDevice::SetFeatures()
|
|||
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;
|
||||
|
|
|
@ -299,7 +299,8 @@ bool OpenGLDevice::HasSurface() const
|
|||
return m_window_info.type != WindowInfo::Type::Surfaceless;
|
||||
}
|
||||
|
||||
bool OpenGLDevice::CreateDevice(const std::string_view& adapter, bool threaded_presentation)
|
||||
bool OpenGLDevice::CreateDevice(const std::string_view& adapter, bool threaded_presentation,
|
||||
FeatureMask disabled_features)
|
||||
{
|
||||
m_gl_context = GL::Context::Create(m_window_info);
|
||||
if (!m_gl_context)
|
||||
|
@ -348,7 +349,7 @@ bool OpenGLDevice::CreateDevice(const std::string_view& adapter, bool threaded_p
|
|||
}
|
||||
|
||||
bool buggy_pbo;
|
||||
if (!CheckFeatures(&buggy_pbo))
|
||||
if (!CheckFeatures(&buggy_pbo, disabled_features))
|
||||
return false;
|
||||
|
||||
if (!CreateBuffers(buggy_pbo))
|
||||
|
@ -360,7 +361,7 @@ bool OpenGLDevice::CreateDevice(const std::string_view& adapter, bool threaded_p
|
|||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLDevice::CheckFeatures(bool* buggy_pbo)
|
||||
bool OpenGLDevice::CheckFeatures(bool* buggy_pbo, FeatureMask disabled_features)
|
||||
{
|
||||
const bool is_gles = m_gl_context->IsGLES();
|
||||
|
||||
|
@ -427,16 +428,18 @@ bool OpenGLDevice::CheckFeatures(bool* buggy_pbo)
|
|||
GLint max_dual_source_draw_buffers = 0;
|
||||
glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, &max_dual_source_draw_buffers);
|
||||
m_features.dual_source_blend =
|
||||
(max_dual_source_draw_buffers > 0) &&
|
||||
!(disabled_features & FEATURE_MASK_DUAL_SOURCE_BLEND) && (max_dual_source_draw_buffers > 0) &&
|
||||
(GLAD_GL_VERSION_3_3 || GLAD_GL_ARB_blend_func_extended || GLAD_GL_EXT_blend_func_extended);
|
||||
|
||||
m_features.framebuffer_fetch = (GLAD_GL_EXT_shader_framebuffer_fetch || GLAD_GL_ARM_shader_framebuffer_fetch);
|
||||
m_features.framebuffer_fetch = !(disabled_features & FEATURE_MASK_FRAMEBUFFER_FETCH) &&
|
||||
(GLAD_GL_EXT_shader_framebuffer_fetch || GLAD_GL_ARM_shader_framebuffer_fetch);
|
||||
|
||||
#ifdef __APPLE__
|
||||
// Partial texture buffer uploads appear to be broken in macOS's OpenGL driver.
|
||||
m_features.supports_texture_buffers = false;
|
||||
#else
|
||||
m_features.supports_texture_buffers = (GLAD_GL_VERSION_3_1 || GLAD_GL_ES_VERSION_3_2);
|
||||
m_features.supports_texture_buffers =
|
||||
!(disabled_features & FEATURE_MASK_TEXTURE_BUFFERS) && (GLAD_GL_VERSION_3_1 || GLAD_GL_ES_VERSION_3_2);
|
||||
|
||||
// And Samsung's ANGLE/GLES driver?
|
||||
if (std::strstr(reinterpret_cast<const char*>(glGetString(GL_RENDERER)), "ANGLE"))
|
||||
|
@ -493,7 +496,8 @@ bool OpenGLDevice::CheckFeatures(bool* buggy_pbo)
|
|||
// noperspective is not supported in GLSL ES.
|
||||
m_features.noperspective_interpolation = !is_gles;
|
||||
|
||||
m_features.geometry_shaders = GLAD_GL_VERSION_3_2 || GLAD_GL_ES_VERSION_3_2;
|
||||
m_features.geometry_shaders =
|
||||
!(disabled_features & FEATURE_MASK_GEOMETRY_SHADERS) && (GLAD_GL_VERSION_3_2 || GLAD_GL_ES_VERSION_3_2);
|
||||
|
||||
m_features.gpu_timing = !(m_gl_context->IsGLES() &&
|
||||
(!GLAD_GL_EXT_disjoint_timer_query || !glGetQueryObjectivEXT || !glGetQueryObjectui64vEXT));
|
||||
|
|
|
@ -122,7 +122,7 @@ public:
|
|||
void UnbindPipeline(const OpenGLPipeline* pl);
|
||||
|
||||
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;
|
||||
|
@ -138,7 +138,7 @@ private:
|
|||
static constexpr u32 UNIFORM_BUFFER_SIZE = 2 * 1024 * 1024;
|
||||
static constexpr u32 TEXTURE_STREAM_BUFFER_SIZE = 16 * 1024 * 1024;
|
||||
|
||||
bool CheckFeatures(bool* buggy_pbo);
|
||||
bool CheckFeatures(bool* buggy_pbo, FeatureMask disabled_features);
|
||||
bool CreateBuffers(bool buggy_pbo);
|
||||
void DestroyBuffers();
|
||||
|
||||
|
|
|
@ -1601,7 +1601,8 @@ bool VulkanDevice::HasSurface() const
|
|||
return static_cast<bool>(m_swap_chain);
|
||||
}
|
||||
|
||||
bool VulkanDevice::CreateDevice(const std::string_view& adapter, bool threaded_presentation)
|
||||
bool VulkanDevice::CreateDevice(const std::string_view& adapter, bool threaded_presentation,
|
||||
FeatureMask disabled_features)
|
||||
{
|
||||
std::unique_lock lock(s_instance_mutex);
|
||||
bool enable_debug_utils = m_debug_device;
|
||||
|
@ -1704,7 +1705,7 @@ bool VulkanDevice::CreateDevice(const std::string_view& adapter, bool threaded_p
|
|||
if (!CreateDevice(surface, enable_validation_layer))
|
||||
return false;
|
||||
|
||||
if (!CheckFeatures())
|
||||
if (!CheckFeatures(disabled_features))
|
||||
{
|
||||
Host::ReportErrorAsync("Error", "Your GPU does not support the required Vulkan features.");
|
||||
return false;
|
||||
|
@ -2163,7 +2164,7 @@ void VulkanDevice::InsertDebugMessage(const char* msg)
|
|||
#endif
|
||||
}
|
||||
|
||||
bool VulkanDevice::CheckFeatures()
|
||||
bool VulkanDevice::CheckFeatures(FeatureMask disabled_features)
|
||||
{
|
||||
m_max_texture_size = m_device_properties.limits.maxImageDimension2D;
|
||||
|
||||
|
@ -2193,15 +2194,16 @@ bool VulkanDevice::CheckFeatures()
|
|||
else
|
||||
m_max_multisamples = 1;
|
||||
|
||||
m_features.dual_source_blend = m_device_features.dualSrcBlend; // TODO: Option to disable
|
||||
m_features.framebuffer_fetch = false; // TODO: Option to disable
|
||||
m_features.dual_source_blend =
|
||||
!(disabled_features & FEATURE_MASK_DUAL_SOURCE_BLEND) && m_device_features.dualSrcBlend;
|
||||
m_features.framebuffer_fetch = /*!(disabled_features & FEATURE_MASK_FRAMEBUFFER_FETCH) && */false;
|
||||
|
||||
if (!m_features.dual_source_blend)
|
||||
Log_WarningPrintf("Vulkan driver is missing dual-source blending. This will have an impact on performance.");
|
||||
|
||||
m_features.noperspective_interpolation = true;
|
||||
m_features.per_sample_shading = m_device_features.sampleRateShading;
|
||||
m_features.supports_texture_buffers = true;
|
||||
m_features.supports_texture_buffers = !(disabled_features & FEATURE_MASK_TEXTURE_BUFFERS);
|
||||
|
||||
#ifdef __APPLE__
|
||||
// Partial texture buffer uploads appear to be broken in macOS/MoltenVK.
|
||||
|
@ -2218,7 +2220,8 @@ bool VulkanDevice::CheckFeatures()
|
|||
if (m_features.texture_buffers_emulated_with_ssbo)
|
||||
Log_WarningPrintf("Emulating texture buffers with SSBOs.");
|
||||
|
||||
m_features.geometry_shaders = m_device_features.geometryShader;
|
||||
m_features.geometry_shaders =
|
||||
!(disabled_features & FEATURE_MASK_GEOMETRY_SHADERS) && m_device_features.geometryShader;
|
||||
|
||||
m_features.partial_msaa_resolve = true;
|
||||
m_features.shader_cache = true;
|
||||
|
|
|
@ -220,7 +220,8 @@ public:
|
|||
void UnbindTextureBuffer(VulkanTextureBuffer* 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;
|
||||
|
@ -305,7 +306,7 @@ private:
|
|||
bool CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer);
|
||||
void ProcessDeviceExtensions();
|
||||
|
||||
bool CheckFeatures();
|
||||
bool CheckFeatures(FeatureMask disabled_features);
|
||||
|
||||
bool CreateAllocator();
|
||||
void DestroyAllocator();
|
||||
|
|
|
@ -139,8 +139,8 @@ std::unique_ptr<GPUPipeline> VulkanDevice::CreatePipeline(const GPUPipeline::Gra
|
|||
VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, // InvSrcAlpha1
|
||||
VK_BLEND_FACTOR_DST_ALPHA, // DstAlpha
|
||||
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, // InvDstAlpha
|
||||
VK_BLEND_FACTOR_CONSTANT_ALPHA, // ConstantAlpha
|
||||
VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, // InvConstantAlpha
|
||||
VK_BLEND_FACTOR_CONSTANT_COLOR, // ConstantAlpha
|
||||
VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, // InvConstantAlpha
|
||||
}};
|
||||
|
||||
static constexpr std::array<VkBlendOp, static_cast<u32>(GPUPipeline::BlendOp::MaxCount)> op_mapping = {{
|
||||
|
|
Loading…
Reference in New Issue