Permalink
Browse files

Merge pull request #6965 from stenzek/d3d-feature-level-10

D3D: Don't emit uint outputs when logic op is unsupported
  • Loading branch information...
degasus committed May 28, 2018
2 parents 9e102e1 + 57976c9 commit cddc2d52c22b42773bbb65a9255cceb90982f531
@@ -414,7 +414,10 @@ HRESULT Create(HWND wnd)
hr = device->QueryInterface<ID3D11Device1>(&device1);
if (FAILED(hr))
{
WARN_LOG(VIDEO, "Missing Direct3D 11.1 support. Logical operations will not be supported.");
g_Config.backend_info.bSupportsLogicOp = false;
}
// BGRA textures are easier to deal with in TextureCache, but might not be supported
UINT format_support;
@@ -62,6 +62,7 @@ void VideoBackend::InitBackendInfo()
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 = false;
g_Config.backend_info.bSupportsST3CTextures = false;
@@ -47,6 +47,7 @@ void VideoBackend::InitBackendInfo()
g_Config.backend_info.bSupportsBPTCTextures = false;
g_Config.backend_info.bSupportsFramebufferFetch = false;
g_Config.backend_info.bSupportsBackgroundCompiling = false;
g_Config.backend_info.bSupportsLogicOp = false;
// aamodes: We only support 1 sample, so no MSAA
g_Config.backend_info.Adapters.clear();
@@ -521,6 +521,9 @@ Renderer::Renderer()
// depth clamping.
g_Config.backend_info.bSupportsDepthClamp = false;
// GLES does not support logic op.
g_Config.backend_info.bSupportsLogicOp = false;
if (GLExtensions::Supports("GL_EXT_shader_framebuffer_fetch"))
{
g_ogl_config.SupportedFramebufferFetch = EsFbFetchType::FbFetchExt;
@@ -83,6 +83,7 @@ void VideoBackend::InitBackendInfo()
g_Config.backend_info.bSupportsPostProcessing = true;
g_Config.backend_info.bSupportsSSAA = true;
g_Config.backend_info.bSupportsReversedDepthRange = true;
g_Config.backend_info.bSupportsLogicOp = true;
g_Config.backend_info.bSupportsMultithreading = false;
g_Config.backend_info.bSupportsCopyToVram = true;
@@ -71,6 +71,7 @@ void VideoSoftware::InitBackendInfo()
g_Config.backend_info.bSupportsCopyToVram = false;
g_Config.backend_info.bSupportsFramebufferFetch = false;
g_Config.backend_info.bSupportsBackgroundCompiling = false;
g_Config.backend_info.bSupportsLogicOp = true;
// aamodes
g_Config.backend_info.AAModes = {1};
@@ -246,6 +246,7 @@ void VulkanContext::PopulateBackendInfo(VideoConfig* config)
config->backend_info.bSupportsST3CTextures = false; // Dependent on features.
config->backend_info.bSupportsBPTCTextures = false; // Dependent on features.
config->backend_info.bSupportsReversedDepthRange = false; // No support yet due to driver bugs.
config->backend_info.bSupportsLogicOp = false; // Dependent on features.
config->backend_info.bSupportsCopyToVram = true; // Assumed support.
config->backend_info.bSupportsFramebufferFetch = false;
}
@@ -272,6 +273,7 @@ void VulkanContext::PopulateBackendInfoFeatures(VideoConfig* config, VkPhysicalD
config->backend_info.bSupportsBBox = config->backend_info.bSupportsFragmentStoresAndAtomics =
(features.fragmentStoresAndAtomics == VK_TRUE);
config->backend_info.bSupportsSSAA = (features.sampleRateShading == VK_TRUE);
config->backend_info.bSupportsLogicOp = (features.logicOp == VK_TRUE);
// Disable geometry shader when shaderTessellationAndGeometryPointSize is not supported.
// Seems this is needed for gl_Layer.
@@ -338,13 +338,15 @@ PixelShaderUid GetPixelShaderUid()
return out;
}
void ClearUnusedPixelShaderUidBits(APIType ApiType, PixelShaderUid* uid)
void ClearUnusedPixelShaderUidBits(APIType ApiType, const ShaderHostConfig& host_config,
PixelShaderUid* uid)
{
pixel_shader_uid_data* uid_data = uid->GetUidData<pixel_shader_uid_data>();
// OpenGL and Vulkan convert implicitly normalized color outputs to their uint representation.
// Therefore, it is not necessary to use a uint output on these backends.
if (ApiType != APIType::D3D)
// Therefore, it is not necessary to use a uint output on these backends. We also disable the
// uint output when logic op is not supported (i.e. driver/device does not support D3D11.1).
if (ApiType != APIType::D3D || !host_config.backend_logic_op)
uid_data->uint_output = 0;
}
@@ -168,5 +168,6 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host
const pixel_shader_uid_data* uid_data);
void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, u32 num_texgens,
bool per_pixel_lighting, bool bounding_box);
void ClearUnusedPixelShaderUidBits(APIType ApiType, PixelShaderUid* uid);
void ClearUnusedPixelShaderUidBits(APIType ApiType, const ShaderHostConfig& host_config,
PixelShaderUid* uid);
PixelShaderUid GetPixelShaderUid();
@@ -456,12 +456,15 @@ std::optional<AbstractPipelineConfig> ShaderCache::GetGXPipelineConfig(const GXP
else
vs = InsertVertexShader(config.vs_uid, CompileVertexShader(config.vs_uid));
PixelShaderUid ps_uid = config.ps_uid;
ClearUnusedPixelShaderUidBits(m_api_type, m_host_config, &ps_uid);
const AbstractShader* ps;
auto ps_iter = m_ps_cache.shader_map.find(config.ps_uid);
auto ps_iter = m_ps_cache.shader_map.find(ps_uid);
if (ps_iter != m_ps_cache.shader_map.end() && !ps_iter->second.pending)
ps = ps_iter->second.shader.get();
else
ps = InsertPixelShader(config.ps_uid, CompilePixelShader(config.ps_uid));
ps = InsertPixelShader(ps_uid, CompilePixelShader(ps_uid));
if (!vs || !ps)
return {};
@@ -492,12 +495,15 @@ ShaderCache::GetGXUberPipelineConfig(const GXUberPipelineUid& config)
else
vs = InsertVertexUberShader(config.vs_uid, CompileVertexUberShader(config.vs_uid));
UberShader::PixelShaderUid ps_uid = config.ps_uid;
UberShader::ClearUnusedPixelShaderUidBits(m_api_type, m_host_config, &ps_uid);
const AbstractShader* ps;
auto ps_iter = m_uber_ps_cache.shader_map.find(config.ps_uid);
auto ps_iter = m_uber_ps_cache.shader_map.find(ps_uid);
if (ps_iter != m_uber_ps_cache.shader_map.end() && !ps_iter->second.pending)
ps = ps_iter->second.shader.get();
else
ps = InsertPixelUberShader(config.ps_uid, CompilePixelUberShader(config.ps_uid));
ps = InsertPixelUberShader(ps_uid, CompilePixelUberShader(ps_uid));
if (!vs || !ps)
return {};
@@ -802,10 +808,13 @@ void ShaderCache::QueuePipelineCompile(const GXPipelineUid& uid, u32 priority)
if (vs_it == shader_cache->m_vs_cache.shader_map.end())
shader_cache->QueueVertexShaderCompile(uid.vs_uid, priority);
auto ps_it = shader_cache->m_ps_cache.shader_map.find(uid.ps_uid);
PixelShaderUid ps_uid = uid.ps_uid;
ClearUnusedPixelShaderUidBits(shader_cache->m_api_type, shader_cache->m_host_config, &ps_uid);
auto ps_it = shader_cache->m_ps_cache.shader_map.find(ps_uid);
stages_ready &= ps_it != shader_cache->m_ps_cache.shader_map.end() && !ps_it->second.pending;
if (ps_it == shader_cache->m_ps_cache.shader_map.end())
shader_cache->QueuePixelShaderCompile(uid.ps_uid, priority);
shader_cache->QueuePixelShaderCompile(ps_uid, priority);
return stages_ready;
}
@@ -870,11 +879,15 @@ void ShaderCache::QueueUberPipelineCompile(const GXUberPipelineUid& uid, u32 pri
if (vs_it == shader_cache->m_uber_vs_cache.shader_map.end())
shader_cache->QueueVertexUberShaderCompile(uid.vs_uid, priority);
auto ps_it = shader_cache->m_uber_ps_cache.shader_map.find(uid.ps_uid);
UberShader::PixelShaderUid ps_uid = uid.ps_uid;
UberShader::ClearUnusedPixelShaderUidBits(shader_cache->m_api_type,
shader_cache->m_host_config, &ps_uid);
auto ps_it = shader_cache->m_uber_ps_cache.shader_map.find(ps_uid);
stages_ready &=
ps_it != shader_cache->m_uber_ps_cache.shader_map.end() && !ps_it->second.pending;
if (ps_it == shader_cache->m_uber_ps_cache.shader_map.end())
shader_cache->QueuePixelUberShaderCompile(uid.ps_uid, priority);
shader_cache->QueuePixelUberShaderCompile(ps_uid, priority);
return stages_ready;
}
@@ -33,6 +33,7 @@ ShaderHostConfig ShaderHostConfig::GetCurrent()
bits.backend_dynamic_sampler_indexing =
g_ActiveConfig.backend_info.bSupportsDynamicSamplerIndexing;
bits.backend_shader_framebuffer_fetch = g_ActiveConfig.backend_info.bSupportsFramebufferFetch;
bits.backend_logic_op = g_ActiveConfig.backend_info.bSupportsLogicOp;
return bits;
}
@@ -180,7 +180,8 @@ union ShaderHostConfig
u32 backend_bitfield : 1;
u32 backend_dynamic_sampler_indexing : 1;
u32 backend_shader_framebuffer_fetch : 1;
u32 pad : 11;
u32 backend_logic_op : 1;
u32 pad : 10;
};
static ShaderHostConfig GetCurrent();
@@ -29,13 +29,15 @@ PixelShaderUid GetPixelShaderUid()
return out;
}
void ClearUnusedPixelShaderUidBits(APIType ApiType, PixelShaderUid* uid)
void ClearUnusedPixelShaderUidBits(APIType ApiType, const ShaderHostConfig& host_config,
PixelShaderUid* uid)
{
pixel_ubershader_uid_data* uid_data = uid->GetUidData<pixel_ubershader_uid_data>();
// OpenGL and Vulkan convert implicitly normalized color outputs to their uint representation.
// Therefore, it is not necessary to use a uint output on these backends.
if (ApiType != APIType::D3D)
// Therefore, it is not necessary to use a uint output on these backends. We also disable the
// uint output when logic op is not supported (i.e. driver/device does not support D3D11.1).
if (ApiType != APIType::D3D || !host_config.backend_logic_op)
uid_data->uint_output = 0;
}
@@ -29,5 +29,6 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
const pixel_ubershader_uid_data* uid_data);
void EnumeratePixelShaderUids(const std::function<void(const PixelShaderUid&)>& callback);
void ClearUnusedPixelShaderUidBits(APIType ApiType, PixelShaderUid* uid);
void ClearUnusedPixelShaderUidBits(APIType ApiType, const ShaderHostConfig& host_config,
PixelShaderUid* uid);
}
@@ -201,6 +201,7 @@ struct VideoConfig final
bool bSupportsFragmentStoresAndAtomics; // a.k.a. OpenGL SSBOs a.k.a. Direct3D UAVs
bool bSupportsDepthClamp; // Needed by VertexShaderGen, so must stay in VideoCommon
bool bSupportsReversedDepthRange;
bool bSupportsLogicOp;
bool bSupportsMultithreading;
bool bSupportsGPUTextureDecoding;
bool bSupportsST3CTextures;

0 comments on commit cddc2d5

Please sign in to comment.