From 61a656570e2afc7a474c44de5795f5d564043c6c Mon Sep 17 00:00:00 2001 From: Stenzek Date: Mon, 15 Apr 2019 21:55:26 +1000 Subject: [PATCH] AbstractPipeline: Support returning "cache data" "Cache data" can be used to assist a driver with creating pipelines by using previously-compiled shader ISA. --- Source/Core/VideoBackends/D3D/Render.cpp | 4 +++- Source/Core/VideoBackends/D3D/Render.h | 4 +++- Source/Core/VideoBackends/D3D/main.cpp | 2 ++ Source/Core/VideoBackends/D3D12/Renderer.cpp | 4 +++- Source/Core/VideoBackends/D3D12/Renderer.h | 4 +++- Source/Core/VideoBackends/D3D12/VideoBackend.cpp | 2 ++ Source/Core/VideoBackends/D3DCommon/Shader.cpp | 5 ----- Source/Core/VideoBackends/D3DCommon/Shader.h | 1 - Source/Core/VideoBackends/Null/NullBackend.cpp | 2 ++ Source/Core/VideoBackends/Null/Render.cpp | 7 +++---- Source/Core/VideoBackends/Null/Render.h | 4 +++- Source/Core/VideoBackends/OGL/OGLShader.cpp | 11 ----------- Source/Core/VideoBackends/OGL/OGLShader.h | 2 -- Source/Core/VideoBackends/OGL/Render.cpp | 4 +++- Source/Core/VideoBackends/OGL/Render.h | 4 +++- Source/Core/VideoBackends/OGL/main.cpp | 2 ++ Source/Core/VideoBackends/Software/SWRenderer.cpp | 5 +++-- Source/Core/VideoBackends/Software/SWRenderer.h | 4 +++- Source/Core/VideoBackends/Software/SWmain.cpp | 2 ++ Source/Core/VideoBackends/Vulkan/Renderer.cpp | 4 +++- Source/Core/VideoBackends/Vulkan/Renderer.h | 4 +++- Source/Core/VideoBackends/Vulkan/VKShader.cpp | 6 ------ Source/Core/VideoBackends/Vulkan/VKShader.h | 1 - Source/Core/VideoBackends/Vulkan/VulkanContext.cpp | 2 ++ Source/Core/VideoCommon/AbstractPipeline.h | 6 ++++++ Source/Core/VideoCommon/AbstractShader.h | 6 ++++-- Source/Core/VideoCommon/RenderBase.h | 5 +++-- Source/Core/VideoCommon/ShaderCache.cpp | 10 +++++----- Source/Core/VideoCommon/VideoConfig.h | 2 ++ 29 files changed, 68 insertions(+), 51 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index a132efadf3..9e6c20e314 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -127,7 +127,9 @@ std::unique_ptr Renderer::CreateShaderFromBinary(ShaderStage sta return DXShader::CreateFromBytecode(stage, DXShader::CreateByteCode(data, length)); } -std::unique_ptr Renderer::CreatePipeline(const AbstractPipelineConfig& config) +std::unique_ptr Renderer::CreatePipeline(const AbstractPipelineConfig& config, + const void* cache_data, + size_t cache_data_length) { return DXPipeline::Create(config); } diff --git a/Source/Core/VideoBackends/D3D/Render.h b/Source/Core/VideoBackends/D3D/Render.h index 551295a9d5..e6b658ae9e 100644 --- a/Source/Core/VideoBackends/D3D/Render.h +++ b/Source/Core/VideoBackends/D3D/Render.h @@ -34,7 +34,9 @@ public: size_t length) override; std::unique_ptr CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) override; - std::unique_ptr CreatePipeline(const AbstractPipelineConfig& config) override; + std::unique_ptr CreatePipeline(const AbstractPipelineConfig& config, + const void* cache_data = nullptr, + size_t cache_data_length = 0) override; std::unique_ptr CreateFramebuffer(AbstractTexture* color_attachment, AbstractTexture* depth_attachment) override; diff --git a/Source/Core/VideoBackends/D3D/main.cpp b/Source/Core/VideoBackends/D3D/main.cpp index a3c56dbc7e..d22b34c99a 100644 --- a/Source/Core/VideoBackends/D3D/main.cpp +++ b/Source/Core/VideoBackends/D3D/main.cpp @@ -82,6 +82,8 @@ void VideoBackend::FillBackendInfo() g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true; g_Config.backend_info.bSupportsGSInstancing = true; g_Config.backend_info.bSupportsSSAA = true; + g_Config.backend_info.bSupportsShaderBinaries = true; + g_Config.backend_info.bSupportsPipelineCacheData = false; g_Config.backend_info.Adapters = D3DCommon::GetAdapterNames(); g_Config.backend_info.AAModes = D3D::GetAAModes(g_Config.iAdapter); diff --git a/Source/Core/VideoBackends/D3D12/Renderer.cpp b/Source/Core/VideoBackends/D3D12/Renderer.cpp index 49de5344e6..bc7d121bfc 100644 --- a/Source/Core/VideoBackends/D3D12/Renderer.cpp +++ b/Source/Core/VideoBackends/D3D12/Renderer.cpp @@ -99,7 +99,9 @@ Renderer::CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) return std::make_unique(vtx_decl); } -std::unique_ptr Renderer::CreatePipeline(const AbstractPipelineConfig& config) +std::unique_ptr Renderer::CreatePipeline(const AbstractPipelineConfig& config, + const void* cache_data, + size_t cache_data_length) { return DXPipeline::Create(config); } diff --git a/Source/Core/VideoBackends/D3D12/Renderer.h b/Source/Core/VideoBackends/D3D12/Renderer.h index 1979833048..992e12aa8a 100644 --- a/Source/Core/VideoBackends/D3D12/Renderer.h +++ b/Source/Core/VideoBackends/D3D12/Renderer.h @@ -41,7 +41,9 @@ public: size_t length) override; std::unique_ptr CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) override; - std::unique_ptr CreatePipeline(const AbstractPipelineConfig& config) override; + std::unique_ptr CreatePipeline(const AbstractPipelineConfig& config, + const void* cache_data = nullptr, + size_t cache_data_length = 0) override; u16 BBoxRead(int index) override; void BBoxWrite(int index, u16 value) override; diff --git a/Source/Core/VideoBackends/D3D12/VideoBackend.cpp b/Source/Core/VideoBackends/D3D12/VideoBackend.cpp index 0ba778471b..8bfc68a5e3 100644 --- a/Source/Core/VideoBackends/D3D12/VideoBackend.cpp +++ b/Source/Core/VideoBackends/D3D12/VideoBackend.cpp @@ -80,6 +80,8 @@ void VideoBackend::FillBackendInfo() g_Config.backend_info.bSupportsPartialDepthCopies = false; g_Config.backend_info.Adapters = D3DCommon::GetAdapterNames(); g_Config.backend_info.AAModes = DXContext::GetAAModes(g_Config.iAdapter); + g_Config.backend_info.bSupportsShaderBinaries = true; + g_Config.backend_info.bSupportsPipelineCacheData = true; // We can only check texture support once we have a device. if (g_dx_context) diff --git a/Source/Core/VideoBackends/D3DCommon/Shader.cpp b/Source/Core/VideoBackends/D3DCommon/Shader.cpp index d53c5ab2e4..12091806e1 100644 --- a/Source/Core/VideoBackends/D3DCommon/Shader.cpp +++ b/Source/Core/VideoBackends/D3DCommon/Shader.cpp @@ -23,11 +23,6 @@ Shader::Shader(ShaderStage stage, BinaryData bytecode) Shader::~Shader() = default; -bool Shader::HasBinary() const -{ - return true; -} - AbstractShader::BinaryData Shader::GetBinary() const { return m_bytecode; diff --git a/Source/Core/VideoBackends/D3DCommon/Shader.h b/Source/Core/VideoBackends/D3DCommon/Shader.h index 6513cd11fe..c3dd94b279 100644 --- a/Source/Core/VideoBackends/D3DCommon/Shader.h +++ b/Source/Core/VideoBackends/D3DCommon/Shader.h @@ -16,7 +16,6 @@ public: const BinaryData& GetByteCode() const { return m_bytecode; } - bool HasBinary() const override; BinaryData GetBinary() const override; static bool CompileShader(D3D_FEATURE_LEVEL feature_level, BinaryData* out_bytecode, diff --git a/Source/Core/VideoBackends/Null/NullBackend.cpp b/Source/Core/VideoBackends/Null/NullBackend.cpp index 6959c820ed..2f353d1fe3 100644 --- a/Source/Core/VideoBackends/Null/NullBackend.cpp +++ b/Source/Core/VideoBackends/Null/NullBackend.cpp @@ -52,6 +52,8 @@ void VideoBackend::InitBackendInfo() g_Config.backend_info.bSupportsLogicOp = false; g_Config.backend_info.bSupportsLargePoints = false; g_Config.backend_info.bSupportsPartialDepthCopies = false; + g_Config.backend_info.bSupportsShaderBinaries = false; + g_Config.backend_info.bSupportsPipelineCacheData = false; // aamodes: We only support 1 sample, so no MSAA g_Config.backend_info.Adapters.clear(); diff --git a/Source/Core/VideoBackends/Null/Render.cpp b/Source/Core/VideoBackends/Null/Render.cpp index ca57a0bdeb..6be3ee4753 100644 --- a/Source/Core/VideoBackends/Null/Render.cpp +++ b/Source/Core/VideoBackends/Null/Render.cpp @@ -46,9 +46,6 @@ class NullShader final : public AbstractShader public: explicit NullShader(ShaderStage stage) : AbstractShader(stage) {} ~NullShader() = default; - - bool HasBinary() const override { return false; } - BinaryData GetBinary() const override { return {}; } }; std::unique_ptr Renderer::CreateShaderFromSource(ShaderStage stage, @@ -70,7 +67,9 @@ public: ~NullPipeline() override = default; }; -std::unique_ptr Renderer::CreatePipeline(const AbstractPipelineConfig& config) +std::unique_ptr Renderer::CreatePipeline(const AbstractPipelineConfig& config, + const void* cache_data, + size_t cache_data_length) { return std::make_unique(); } diff --git a/Source/Core/VideoBackends/Null/Render.h b/Source/Core/VideoBackends/Null/Render.h index 5ad4d8028e..339e21d637 100644 --- a/Source/Core/VideoBackends/Null/Render.h +++ b/Source/Core/VideoBackends/Null/Render.h @@ -28,7 +28,9 @@ public: size_t length) override; std::unique_ptr CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) override; - std::unique_ptr CreatePipeline(const AbstractPipelineConfig& config) override; + std::unique_ptr CreatePipeline(const AbstractPipelineConfig& config, + const void* cache_data = nullptr, + size_t cache_data_length = 0) override; u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override { return 0; } void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override {} diff --git a/Source/Core/VideoBackends/OGL/OGLShader.cpp b/Source/Core/VideoBackends/OGL/OGLShader.cpp index 340d79f244..fc13b5b975 100644 --- a/Source/Core/VideoBackends/OGL/OGLShader.cpp +++ b/Source/Core/VideoBackends/OGL/OGLShader.cpp @@ -44,17 +44,6 @@ OGLShader::~OGLShader() glDeleteProgram(m_gl_compute_program_id); } -bool OGLShader::HasBinary() const -{ - // NOTE: GL shaders do not have binaries, programs do. - return false; -} - -AbstractShader::BinaryData OGLShader::GetBinary() const -{ - return {}; -} - std::unique_ptr OGLShader::CreateFromSource(ShaderStage stage, const char* source, size_t length) { diff --git a/Source/Core/VideoBackends/OGL/OGLShader.h b/Source/Core/VideoBackends/OGL/OGLShader.h index a703d60696..ad0432ada4 100644 --- a/Source/Core/VideoBackends/OGL/OGLShader.h +++ b/Source/Core/VideoBackends/OGL/OGLShader.h @@ -24,8 +24,6 @@ public: GLenum GetGLShaderType() const { return m_type; } GLuint GetGLShaderID() const { return m_gl_id; } GLuint GetGLComputeProgramID() const { return m_gl_compute_program_id; } - bool HasBinary() const override; - BinaryData GetBinary() const override; static std::unique_ptr CreateFromSource(ShaderStage stage, const char* source, size_t length); diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 06e5135191..8e13aa9ff2 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -828,7 +828,9 @@ std::unique_ptr Renderer::CreateShaderFromBinary(ShaderStage sta return nullptr; } -std::unique_ptr Renderer::CreatePipeline(const AbstractPipelineConfig& config) +std::unique_ptr Renderer::CreatePipeline(const AbstractPipelineConfig& config, + const void* cache_data, + size_t cache_data_length) { return OGLPipeline::Create(config); } diff --git a/Source/Core/VideoBackends/OGL/Render.h b/Source/Core/VideoBackends/OGL/Render.h index 0fb6c4e93e..f45bebbec1 100644 --- a/Source/Core/VideoBackends/OGL/Render.h +++ b/Source/Core/VideoBackends/OGL/Render.h @@ -102,7 +102,9 @@ public: size_t length) override; std::unique_ptr CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) override; - std::unique_ptr CreatePipeline(const AbstractPipelineConfig& config) override; + std::unique_ptr CreatePipeline(const AbstractPipelineConfig& config, + const void* cache_data = nullptr, + size_t cache_data_length = 0) override; std::unique_ptr CreateFramebuffer(AbstractTexture* color_attachment, AbstractTexture* depth_attachment) override; diff --git a/Source/Core/VideoBackends/OGL/main.cpp b/Source/Core/VideoBackends/OGL/main.cpp index 5157f015e4..c2cf0af192 100644 --- a/Source/Core/VideoBackends/OGL/main.cpp +++ b/Source/Core/VideoBackends/OGL/main.cpp @@ -90,6 +90,8 @@ void VideoBackend::InitBackendInfo() g_Config.backend_info.bSupportsCopyToVram = true; g_Config.backend_info.bSupportsLargePoints = true; g_Config.backend_info.bSupportsPartialDepthCopies = true; + g_Config.backend_info.bSupportsShaderBinaries = false; + g_Config.backend_info.bSupportsPipelineCacheData = false; // TODO: There is a bug here, if texel buffers or SSBOs/atomics are not supported the graphics // options will show the option when it is not supported. The only way around this would be diff --git a/Source/Core/VideoBackends/Software/SWRenderer.cpp b/Source/Core/VideoBackends/Software/SWRenderer.cpp index 4b57b9b551..3893320c26 100644 --- a/Source/Core/VideoBackends/Software/SWRenderer.cpp +++ b/Source/Core/VideoBackends/Software/SWRenderer.cpp @@ -64,7 +64,6 @@ public: explicit SWShader(ShaderStage stage) : AbstractShader(stage) {} ~SWShader() = default; - bool HasBinary() const override { return false; } BinaryData GetBinary() const override { return {}; } }; @@ -87,7 +86,9 @@ public: ~SWPipeline() override = default; }; -std::unique_ptr SWRenderer::CreatePipeline(const AbstractPipelineConfig& config) +std::unique_ptr SWRenderer::CreatePipeline(const AbstractPipelineConfig& config, + const void* cache_data, + size_t cache_data_length) { return std::make_unique(); } diff --git a/Source/Core/VideoBackends/Software/SWRenderer.h b/Source/Core/VideoBackends/Software/SWRenderer.h index a06ccaecd2..21ebf2dea7 100644 --- a/Source/Core/VideoBackends/Software/SWRenderer.h +++ b/Source/Core/VideoBackends/Software/SWRenderer.h @@ -33,7 +33,9 @@ public: size_t length) override; std::unique_ptr CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) override; - std::unique_ptr CreatePipeline(const AbstractPipelineConfig& config) override; + std::unique_ptr CreatePipeline(const AbstractPipelineConfig& config, + const void* cache_data = nullptr, + size_t cache_data_length = 0) override; u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override; void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override {} diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp index b1c465c4a2..1d02660cf7 100644 --- a/Source/Core/VideoBackends/Software/SWmain.cpp +++ b/Source/Core/VideoBackends/Software/SWmain.cpp @@ -74,6 +74,8 @@ void VideoSoftware::InitBackendInfo() g_Config.backend_info.bSupportsFramebufferFetch = false; g_Config.backend_info.bSupportsBackgroundCompiling = false; g_Config.backend_info.bSupportsLogicOp = true; + g_Config.backend_info.bSupportsShaderBinaries = false; + g_Config.backend_info.bSupportsPipelineCacheData = false; // aamodes g_Config.backend_info.AAModes = {1}; diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index fc07c4ce41..5d918eda96 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -112,7 +112,9 @@ Renderer::CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) return std::make_unique(vtx_decl); } -std::unique_ptr Renderer::CreatePipeline(const AbstractPipelineConfig& config) +std::unique_ptr Renderer::CreatePipeline(const AbstractPipelineConfig& config, + const void* cache_data, + size_t cache_data_length) { return VKPipeline::Create(config); } diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.h b/Source/Core/VideoBackends/Vulkan/Renderer.h index 2b3390b263..f28b4f94c1 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.h +++ b/Source/Core/VideoBackends/Vulkan/Renderer.h @@ -48,7 +48,9 @@ public: size_t length) override; std::unique_ptr CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) override; - std::unique_ptr CreatePipeline(const AbstractPipelineConfig& config) override; + std::unique_ptr CreatePipeline(const AbstractPipelineConfig& config, + const void* cache_data = nullptr, + size_t cache_data_length = 0) override; SwapChain* GetSwapChain() const { return m_swap_chain.get(); } BoundingBox* GetBoundingBox() const { return m_bounding_box.get(); } diff --git a/Source/Core/VideoBackends/Vulkan/VKShader.cpp b/Source/Core/VideoBackends/Vulkan/VKShader.cpp index 1a95a9c1f8..4308660ae6 100644 --- a/Source/Core/VideoBackends/Vulkan/VKShader.cpp +++ b/Source/Core/VideoBackends/Vulkan/VKShader.cpp @@ -32,12 +32,6 @@ VKShader::~VKShader() vkDestroyPipeline(g_vulkan_context->GetDevice(), m_compute_pipeline, nullptr); } -bool VKShader::HasBinary() const -{ - ASSERT(!m_spv.empty()); - return true; -} - AbstractShader::BinaryData VKShader::GetBinary() const { BinaryData ret(sizeof(u32) * m_spv.size()); diff --git a/Source/Core/VideoBackends/Vulkan/VKShader.h b/Source/Core/VideoBackends/Vulkan/VKShader.h index a97007adda..21194127a7 100644 --- a/Source/Core/VideoBackends/Vulkan/VKShader.h +++ b/Source/Core/VideoBackends/Vulkan/VKShader.h @@ -23,7 +23,6 @@ public: VkShaderModule GetShaderModule() const { return m_module; } VkPipeline GetComputePipeline() const { return m_compute_pipeline; } - bool HasBinary() const override; BinaryData GetBinary() const override; static std::unique_ptr CreateFromSource(ShaderStage stage, const char* source, diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp index 72f3cf79b0..1f0955c921 100644 --- a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp +++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp @@ -266,6 +266,8 @@ void VulkanContext::PopulateBackendInfo(VideoConfig* config) config->backend_info.bSupportsGPUTextureDecoding = true; // Assumed support. config->backend_info.bSupportsBitfield = true; // Assumed support. config->backend_info.bSupportsPartialDepthCopies = true; // Assumed support. + config->backend_info.bSupportsShaderBinaries = true; // Assumed support. + config->backend_info.bSupportsPipelineCacheData = false; // Handled via pipeline caches. config->backend_info.bSupportsDynamicSamplerIndexing = true; // Assumed support. config->backend_info.bSupportsPostProcessing = true; // Assumed support. config->backend_info.bSupportsBackgroundCompiling = true; // Assumed support. diff --git a/Source/Core/VideoCommon/AbstractPipeline.h b/Source/Core/VideoCommon/AbstractPipeline.h index 8c7d7482de..8375eda557 100644 --- a/Source/Core/VideoCommon/AbstractPipeline.h +++ b/Source/Core/VideoCommon/AbstractPipeline.h @@ -75,4 +75,10 @@ class AbstractPipeline public: AbstractPipeline() = default; virtual ~AbstractPipeline() = default; + + // "Cache data" can be used to assist a driver with creating pipelines by using previously + // compiled shader ISA. The abstract shaders and creation struct are still required to create + // pipeline objects, the cache is optionally used by the driver to speed up compilation. + using CacheData = std::vector; + virtual CacheData GetCacheData() const { return {}; } }; diff --git a/Source/Core/VideoCommon/AbstractShader.h b/Source/Core/VideoCommon/AbstractShader.h index 4e765d60d9..52855fd76e 100644 --- a/Source/Core/VideoCommon/AbstractShader.h +++ b/Source/Core/VideoCommon/AbstractShader.h @@ -25,9 +25,11 @@ public: virtual ~AbstractShader() = default; ShaderStage GetStage() const { return m_stage; } + + // Shader binaries represent the input source code in a lower-level form. e.g. SPIR-V or DXBC. + // The shader source code is not required to create a shader object from the binary. using BinaryData = std::vector; - virtual bool HasBinary() const = 0; - virtual BinaryData GetBinary() const = 0; + virtual BinaryData GetBinary() const { return {}; } protected: ShaderStage m_stage; diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index af9c1a8972..31a0e2c15b 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -130,8 +130,9 @@ public: CreateShaderFromBinary(ShaderStage stage, const void* data, size_t length) = 0; virtual std::unique_ptr CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) = 0; - virtual std::unique_ptr - CreatePipeline(const AbstractPipelineConfig& config) = 0; + virtual std::unique_ptr CreatePipeline(const AbstractPipelineConfig& config, + const void* cache_data = nullptr, + size_t cache_data_length = 0) = 0; std::unique_ptr CreateShaderFromSource(ShaderStage stage, const std::string& source); diff --git a/Source/Core/VideoCommon/ShaderCache.cpp b/Source/Core/VideoCommon/ShaderCache.cpp index 8f9c99d39d..10bec245ef 100644 --- a/Source/Core/VideoCommon/ShaderCache.cpp +++ b/Source/Core/VideoCommon/ShaderCache.cpp @@ -334,7 +334,7 @@ const AbstractShader* ShaderCache::InsertVertexShader(const VertexShaderUid& uid if (shader && !entry.shader) { - if (g_ActiveConfig.bShaderCache && shader->HasBinary()) + if (g_ActiveConfig.bShaderCache && g_ActiveConfig.backend_info.bSupportsShaderBinaries) { auto binary = shader->GetBinary(); if (!binary.empty()) @@ -356,7 +356,7 @@ const AbstractShader* ShaderCache::InsertVertexUberShader(const UberShader::Vert if (shader && !entry.shader) { - if (g_ActiveConfig.bShaderCache && shader->HasBinary()) + if (g_ActiveConfig.bShaderCache && g_ActiveConfig.backend_info.bSupportsShaderBinaries) { auto binary = shader->GetBinary(); if (!binary.empty()) @@ -378,7 +378,7 @@ const AbstractShader* ShaderCache::InsertPixelShader(const PixelShaderUid& uid, if (shader && !entry.shader) { - if (g_ActiveConfig.bShaderCache && shader->HasBinary()) + if (g_ActiveConfig.bShaderCache && g_ActiveConfig.backend_info.bSupportsShaderBinaries) { auto binary = shader->GetBinary(); if (!binary.empty()) @@ -400,7 +400,7 @@ const AbstractShader* ShaderCache::InsertPixelUberShader(const UberShader::Pixel if (shader && !entry.shader) { - if (g_ActiveConfig.bShaderCache && shader->HasBinary()) + if (g_ActiveConfig.bShaderCache && g_ActiveConfig.backend_info.bSupportsShaderBinaries) { auto binary = shader->GetBinary(); if (!binary.empty()) @@ -425,7 +425,7 @@ const AbstractShader* ShaderCache::CreateGeometryShader(const GeometryShaderUid& if (shader && !entry.shader) { - if (g_ActiveConfig.bShaderCache && shader->HasBinary()) + if (g_ActiveConfig.bShaderCache && g_ActiveConfig.backend_info.bSupportsShaderBinaries) { auto binary = shader->GetBinary(); if (!binary.empty()) diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h index 5be2a06639..b77ee1c584 100644 --- a/Source/Core/VideoCommon/VideoConfig.h +++ b/Source/Core/VideoCommon/VideoConfig.h @@ -219,6 +219,8 @@ struct VideoConfig final bool bSupportsBackgroundCompiling; bool bSupportsLargePoints; bool bSupportsPartialDepthCopies; + bool bSupportsShaderBinaries; + bool bSupportsPipelineCacheData; } backend_info; // Utility