Skip to content
Permalink
Browse files

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.
  • Loading branch information...
CookiePLMonster committed Jul 21, 2019
1 parent a6b8e8b commit ff00873610a3cd55e76245ef0aae892026fedd9b
@@ -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
@@ -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
@@ -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];
@@ -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,
@@ -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);

0 comments on commit ff00873

Please sign in to comment.
You can’t perform that action at this time.