summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorSilent <zdanio95@gmail.com>2019-07-21 17:10:51 +0200
committerSilent <zdanio95@gmail.com>2019-07-29 16:47:39 +0200
commitff00873610a3cd55e76245ef0aae892026fedd9b (patch)
tree0a76d85f6d6a6302ce40b889443cbf6f58f6973b /Source/Core
parenta6b8e8b9c35ceedfa64758c1de3b1d4f64a98061 (diff)
D3D11: Query for output merger logic op support and use logic op code only if supported
Previously code assumed that if DX11.1 runtime is supported, logic ops will, but Windows 7 SP1 with a Platform Update supports DX11.1 runtime without logic ops. This created pretty jarring visual artifacts, which now should be gone OR replaced with much less jarring errors.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/VideoBackends/D3D/D3DBase.cpp66
-rw-r--r--Source/Core/VideoBackends/D3D/D3DBase.h3
-rw-r--r--Source/Core/VideoBackends/D3D/D3DState.cpp2
-rw-r--r--Source/Core/VideoBackends/D3D/DXTexture.cpp5
-rw-r--r--Source/Core/VideoBackends/D3D/main.cpp4
5 files changed, 64 insertions, 16 deletions
diff --git a/Source/Core/VideoBackends/D3D/D3DBase.cpp b/Source/Core/VideoBackends/D3D/D3DBase.cpp
index 358841ecbc..81220dcfc3 100644
--- a/Source/Core/VideoBackends/D3D/D3DBase.cpp
+++ b/Source/Core/VideoBackends/D3D/D3DBase.cpp
@@ -64,7 +64,7 @@ bool Create(u32 adapter_index, bool enable_debug_layer)
}
ComPtr<IDXGIAdapter> adapter;
- HRESULT hr = dxgi_factory->EnumAdapters(adapter_index, &adapter);
+ HRESULT hr = dxgi_factory->EnumAdapters(adapter_index, adapter.GetAddressOf());
if (FAILED(hr))
{
WARN_LOG(VIDEO, "Adapter %u not found, using default", adapter_index);
@@ -75,10 +75,10 @@ bool Create(u32 adapter_index, bool enable_debug_layer)
// version of the DirectX SDK. If it does, simply fallback to a non-debug device.
if (enable_debug_layer)
{
- hr = d3d11_create_device(adapter.Get(), D3D_DRIVER_TYPE_UNKNOWN, nullptr,
- D3D11_CREATE_DEVICE_DEBUG, s_supported_feature_levels.data(),
- static_cast<UINT>(s_supported_feature_levels.size()),
- D3D11_SDK_VERSION, &device, &feature_level, &context);
+ hr = d3d11_create_device(
+ adapter.Get(), D3D_DRIVER_TYPE_UNKNOWN, nullptr, D3D11_CREATE_DEVICE_DEBUG,
+ s_supported_feature_levels.data(), static_cast<UINT>(s_supported_feature_levels.size()),
+ D3D11_SDK_VERSION, device.GetAddressOf(), &feature_level, context.GetAddressOf());
// Debugbreak on D3D error
if (SUCCEEDED(hr) && SUCCEEDED(device.As(&s_debug)))
@@ -105,10 +105,10 @@ bool Create(u32 adapter_index, bool enable_debug_layer)
if (!enable_debug_layer || FAILED(hr))
{
- hr = d3d11_create_device(adapter.Get(), D3D_DRIVER_TYPE_UNKNOWN, nullptr, 0,
- s_supported_feature_levels.data(),
- static_cast<UINT>(s_supported_feature_levels.size()),
- D3D11_SDK_VERSION, &device, &feature_level, &context);
+ hr = d3d11_create_device(
+ adapter.Get(), D3D_DRIVER_TYPE_UNKNOWN, nullptr, 0, s_supported_feature_levels.data(),
+ static_cast<UINT>(s_supported_feature_levels.size()), D3D11_SDK_VERSION,
+ device.GetAddressOf(), &feature_level, context.GetAddressOf());
}
if (FAILED(hr))
@@ -125,7 +125,6 @@ bool Create(u32 adapter_index, bool enable_debug_layer)
if (FAILED(hr))
{
WARN_LOG(VIDEO, "Missing Direct3D 11.1 support. Logical operations will not be supported.");
- g_Config.backend_info.bSupportsLogicOp = false;
}
stateman = std::make_unique<StateManager>();
@@ -225,6 +224,53 @@ bool SupportsTextureFormat(DXGI_FORMAT format)
return (support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
}
+bool SupportsLogicOp(u32 adapter_index)
+{
+ // Use temporary device if we don't have one already.
+ Common::DynamicLibrary temp_lib;
+ ComPtr<ID3D11Device1> temp_device1 = device1;
+ if (!device)
+ {
+ ComPtr<ID3D11Device> temp_device;
+
+ ComPtr<IDXGIFactory> temp_dxgi_factory = D3DCommon::CreateDXGIFactory(false);
+ if (!temp_dxgi_factory)
+ return false;
+
+ ComPtr<IDXGIAdapter> adapter;
+ temp_dxgi_factory->EnumAdapters(adapter_index, adapter.GetAddressOf());
+
+ PFN_D3D11_CREATE_DEVICE d3d11_create_device;
+ if (!temp_lib.Open("d3d11.dll") ||
+ !temp_lib.GetSymbol("D3D11CreateDevice", &d3d11_create_device))
+ {
+ return false;
+ }
+
+ HRESULT hr = d3d11_create_device(
+ adapter.Get(), D3D_DRIVER_TYPE_UNKNOWN, nullptr, 0, s_supported_feature_levels.data(),
+ static_cast<UINT>(s_supported_feature_levels.size()), D3D11_SDK_VERSION,
+ temp_device.GetAddressOf(), nullptr, nullptr);
+ if (FAILED(hr))
+ return false;
+
+ if (FAILED(temp_device.As(&temp_device1)))
+ return false;
+ }
+
+ if (!temp_device1)
+ return false;
+
+ D3D11_FEATURE_DATA_D3D11_OPTIONS options{};
+ if (FAILED(temp_device1->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &options,
+ sizeof(options))))
+ {
+ return false;
+ }
+
+ return options.OutputMergerLogicOp != FALSE;
+}
+
} // namespace D3D
} // namespace DX11
diff --git a/Source/Core/VideoBackends/D3D/D3DBase.h b/Source/Core/VideoBackends/D3D/D3DBase.h
index 090a0b4f4d..7fed1bb2c3 100644
--- a/Source/Core/VideoBackends/D3D/D3DBase.h
+++ b/Source/Core/VideoBackends/D3D/D3DBase.h
@@ -43,6 +43,9 @@ std::vector<u32> GetAAModes(u32 adapter_index);
// Checks for support of the given texture format.
bool SupportsTextureFormat(DXGI_FORMAT format);
+// Checks for logic op support.
+bool SupportsLogicOp(u32 adapter_index);
+
} // namespace D3D
} // namespace DX11
diff --git a/Source/Core/VideoBackends/D3D/D3DState.cpp b/Source/Core/VideoBackends/D3D/D3DState.cpp
index a7b56145da..a9727937ac 100644
--- a/Source/Core/VideoBackends/D3D/D3DState.cpp
+++ b/Source/Core/VideoBackends/D3D/D3DState.cpp
@@ -359,7 +359,7 @@ ID3D11BlendState* StateCache::Get(BlendingState state)
if (it != m_blend.end())
return it->second.Get();
- if (state.logicopenable && D3D::device1)
+ if (state.logicopenable && g_ActiveConfig.backend_info.bSupportsLogicOp)
{
D3D11_BLEND_DESC1 desc = {};
D3D11_RENDER_TARGET_BLEND_DESC1& tdesc = desc.RenderTarget[0];
diff --git a/Source/Core/VideoBackends/D3D/DXTexture.cpp b/Source/Core/VideoBackends/D3D/DXTexture.cpp
index 6ab445868e..e2e818d637 100644
--- a/Source/Core/VideoBackends/D3D/DXTexture.cpp
+++ b/Source/Core/VideoBackends/D3D/DXTexture.cpp
@@ -12,6 +12,7 @@
#include "VideoBackends/D3D/D3DState.h"
#include "VideoBackends/D3D/DXTexture.h"
#include "VideoBackends/D3DCommon/Common.h"
+#include "VideoCommon/VideoConfig.h"
namespace DX11
{
@@ -360,10 +361,10 @@ std::unique_ptr<DXFramebuffer> DXFramebuffer::Create(DXTexture* color_attachment
if (FAILED(hr))
return nullptr;
- // Only create the integer RTV on Win8+.
+ // Only create the integer RTV when logic ops are supported (Win8+).
DXGI_FORMAT integer_format =
D3DCommon::GetRTVFormatForAbstractFormat(color_attachment->GetFormat(), true);
- if (D3D::device1 && integer_format != desc.Format)
+ if (g_ActiveConfig.backend_info.bSupportsLogicOp && integer_format != desc.Format)
{
desc.Format = integer_format;
hr = D3D::device->CreateRenderTargetView(color_attachment->GetD3DTexture(), &desc,
diff --git a/Source/Core/VideoBackends/D3D/main.cpp b/Source/Core/VideoBackends/D3D/main.cpp
index d87965deff..6c4bf20dd1 100644
--- a/Source/Core/VideoBackends/D3D/main.cpp
+++ b/Source/Core/VideoBackends/D3D/main.cpp
@@ -63,16 +63,13 @@ void VideoBackend::FillBackendInfo()
g_Config.backend_info.bSupportsClipControl = true;
g_Config.backend_info.bSupportsDepthClamp = true;
g_Config.backend_info.bSupportsReversedDepthRange = false;
- g_Config.backend_info.bSupportsLogicOp = true;
g_Config.backend_info.bSupportsMultithreading = false;
g_Config.backend_info.bSupportsGPUTextureDecoding = true;
- g_Config.backend_info.bSupportsST3CTextures = false;
g_Config.backend_info.bSupportsCopyToVram = true;
g_Config.backend_info.bSupportsLargePoints = false;
g_Config.backend_info.bSupportsPartialDepthCopies = false;
g_Config.backend_info.bSupportsBitfield = false;
g_Config.backend_info.bSupportsDynamicSamplerIndexing = false;
- g_Config.backend_info.bSupportsBPTCTextures = false;
g_Config.backend_info.bSupportsFramebufferFetch = false;
g_Config.backend_info.bSupportsBackgroundCompiling = true;
g_Config.backend_info.bSupportsST3CTextures = true;
@@ -84,6 +81,7 @@ void VideoBackend::FillBackendInfo()
g_Config.backend_info.bSupportsSSAA = true;
g_Config.backend_info.bSupportsShaderBinaries = true;
g_Config.backend_info.bSupportsPipelineCacheData = false;
+ g_Config.backend_info.bSupportsLogicOp = D3D::SupportsLogicOp(g_Config.iAdapter);
g_Config.backend_info.Adapters = D3DCommon::GetAdapterNames();
g_Config.backend_info.AAModes = D3D::GetAAModes(g_Config.iAdapter);