VideoCommon: Compile a few extra pipelines

This commit is contained in:
TellowKrinkle 2022-06-18 02:50:48 -05:00
parent d3dae1cd7e
commit d289e9c51c
1 changed files with 63 additions and 25 deletions

View File

@ -1235,32 +1235,32 @@ void ShaderCache::QueueUberShaderPipelines()
dummy_vertex_decl.stride = sizeof(float) * 4; dummy_vertex_decl.stride = sizeof(float) * 4;
NativeVertexFormat* dummy_vertex_format = NativeVertexFormat* dummy_vertex_format =
VertexLoaderManager::GetUberVertexFormat(dummy_vertex_decl); VertexLoaderManager::GetUberVertexFormat(dummy_vertex_decl);
auto QueueDummyPipeline = [&](const UberShader::VertexShaderUid& vs_uid, auto QueueDummyPipeline =
const GeometryShaderUid& gs_uid, [&](const UberShader::VertexShaderUid& vs_uid, const GeometryShaderUid& gs_uid,
const UberShader::PixelShaderUid& ps_uid) { const UberShader::PixelShaderUid& ps_uid, const BlendingState& blend) {
GXUberPipelineUid config; GXUberPipelineUid config;
config.vertex_format = dummy_vertex_format; config.vertex_format = dummy_vertex_format;
config.vs_uid = vs_uid; config.vs_uid = vs_uid;
config.gs_uid = gs_uid; config.gs_uid = gs_uid;
config.ps_uid = ps_uid; config.ps_uid = ps_uid;
config.rasterization_state = RenderState::GetCullBackFaceRasterizationState( config.rasterization_state = RenderState::GetCullBackFaceRasterizationState(
static_cast<PrimitiveType>(gs_uid.GetUidData()->primitive_type)); static_cast<PrimitiveType>(gs_uid.GetUidData()->primitive_type));
config.depth_state = RenderState::GetNoDepthTestingDepthState(); config.depth_state = RenderState::GetNoDepthTestingDepthState();
config.blending_state = RenderState::GetNoBlendingBlendState(); config.blending_state = blend;
if (ps_uid.GetUidData()->uint_output) if (ps_uid.GetUidData()->uint_output)
{ {
// uint_output is only ever enabled when logic ops are enabled. // uint_output is only ever enabled when logic ops are enabled.
config.blending_state.logicopenable = true; config.blending_state.logicopenable = true;
config.blending_state.logicmode = LogicOp::And; config.blending_state.logicmode = LogicOp::And;
} }
auto iter = m_gx_uber_pipeline_cache.find(config); auto iter = m_gx_uber_pipeline_cache.find(config);
if (iter != m_gx_uber_pipeline_cache.end()) if (iter != m_gx_uber_pipeline_cache.end())
return; return;
auto& entry = m_gx_uber_pipeline_cache[config]; auto& entry = m_gx_uber_pipeline_cache[config];
entry.second = false; entry.second = false;
}; };
// Populate the pipeline configs with empty entries, these will be compiled afterwards. // Populate the pipeline configs with empty entries, these will be compiled afterwards.
UberShader::EnumerateVertexShaderUids([&](const UberShader::VertexShaderUid& vuid) { UberShader::EnumerateVertexShaderUids([&](const UberShader::VertexShaderUid& vuid) {
@ -1277,7 +1277,45 @@ void ShaderCache::QueueUberShaderPipelines()
{ {
return; return;
} }
QueueDummyPipeline(vuid, guid, cleared_puid); BlendingState blend = RenderState::GetNoBlendingBlendState();
QueueDummyPipeline(vuid, guid, cleared_puid, blend);
if (g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader)
{
// Not all GPUs need all the pipeline state compiled into shaders, so they tend to key
// compiled shaders based on some subset of the pipeline state.
// Some test results:
// (GPUs tested: AMD Radeon Pro 5600M, Nvidia GT 750M, Intel UHD 630,
// Intel Iris Pro 5200, Apple M1)
// MacOS Metal:
// - AMD, Nvidia, Intel GPUs: Shaders are keyed on vertex layout and whether or not
// dual source blend is enabled. That's it.
// - Apple GPUs: Shaders are keyed on vertex layout and all blending settings. We use
// framebuffer fetch here, so the only blending settings used by ubershaders are the
// alphaupdate and colorupdate ones. Also keyed on primitive type, but Metal supports
// setting it to "unknown" and we do for ubershaders (but MoltenVK won't).
// Windows Vulkan:
// - AMD, Nvidia: Definitely keyed on dual source blend, but the others seem more random
// Changing a setting on one shader will require a recompile, but changing the same
// setting on another won't. Compiling a copy with alphaupdate off, colorupdate off,
// and one with DSB on seems to get pretty good coverage though.
// Windows D3D12:
// - AMD: Keyed on dual source blend and vertex layout
// - Nvidia Kepler: No recompiles for changes to vertex layout or blend
blend.alphaupdate = false;
QueueDummyPipeline(vuid, guid, cleared_puid, blend);
blend.alphaupdate = true;
blend.colorupdate = false;
QueueDummyPipeline(vuid, guid, cleared_puid, blend);
blend.colorupdate = true;
if (!cleared_puid.GetUidData()->no_dual_src && !cleared_puid.GetUidData()->uint_output)
{
blend.blendenable = true;
blend.usedualsrc = true;
blend.srcfactor = SrcBlendFactor::SrcAlpha;
blend.dstfactor = DstBlendFactor::InvSrcAlpha;
QueueDummyPipeline(vuid, guid, cleared_puid, blend);
}
}
}); });
}); });
}); });