Settings: Add option to disable DSB/fbfetch
This commit is contained in:
@ -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 = {{
|
||||
|
||||
Reference in New Issue
Block a user