diff --git a/Source/Core/VideoBackends/D3D12/DXPipeline.cpp b/Source/Core/VideoBackends/D3D12/DXPipeline.cpp index 0c896bb425..c32739f803 100644 --- a/Source/Core/VideoBackends/D3D12/DXPipeline.cpp +++ b/Source/Core/VideoBackends/D3D12/DXPipeline.cpp @@ -156,7 +156,8 @@ static void GetD3DBlendDesc(D3D12_BLEND_DESC* desc, const BlendingState& state) } } -std::unique_ptr DXPipeline::Create(const AbstractPipelineConfig& config) +std::unique_ptr DXPipeline::Create(const AbstractPipelineConfig& config, + const void* cache_data, size_t cache_data_size) { DEBUG_ASSERT(config.vertex_shader && config.pixel_shader); @@ -202,16 +203,36 @@ std::unique_ptr DXPipeline::Create(const AbstractPipelineConfig& con D3DCommon::GetDSVFormatForAbstractFormat(config.framebuffer_state.depth_texture_format); desc.SampleDesc.Count = config.framebuffer_state.samples; desc.NodeMask = 1; + desc.CachedPSO.pCachedBlob = cache_data; + desc.CachedPSO.CachedBlobSizeInBytes = cache_data_size; ID3D12PipelineState* pso; HRESULT hr = g_dx_context->GetDevice()->CreateGraphicsPipelineState(&desc, IID_PPV_ARGS(&pso)); - CHECK(SUCCEEDED(hr), "Create PSO"); if (FAILED(hr)) + { + WARN_LOG(VIDEO, "CreateGraphicsPipelineState() %sfailed with HRESULT %08X", + cache_data ? "with cache data " : "", hr); return nullptr; + } const bool use_integer_rtv = !config.blending_state.blendenable && config.blending_state.logicopenable; return std::make_unique(pso, desc.pRootSignature, config.usage, GetD3DTopology(config.rasterization_state), use_integer_rtv); } + +AbstractPipeline::CacheData DXPipeline::GetCacheData() const +{ + ComPtr blob; + HRESULT hr = m_pipeline->GetCachedBlob(&blob); + if (FAILED(hr)) + { + WARN_LOG(VIDEO, "ID3D12Pipeline::GetCachedBlob() failed with HRESULT %08X", hr); + return {}; + } + + CacheData data(blob->GetBufferSize()); + std::memcpy(data.data(), blob->GetBufferPointer(), blob->GetBufferSize()); + return data; +} } // namespace DX12 diff --git a/Source/Core/VideoBackends/D3D12/DXPipeline.h b/Source/Core/VideoBackends/D3D12/DXPipeline.h index 04608cae1f..d0327a0c0e 100644 --- a/Source/Core/VideoBackends/D3D12/DXPipeline.h +++ b/Source/Core/VideoBackends/D3D12/DXPipeline.h @@ -19,7 +19,8 @@ public: bool use_integer_rtv); ~DXPipeline() override; - static std::unique_ptr Create(const AbstractPipelineConfig& config); + static std::unique_ptr Create(const AbstractPipelineConfig& config, + const void* cache_data, size_t cache_data_size); ID3D12PipelineState* GetPipeline() const { return m_pipeline; } ID3D12RootSignature* GetRootSignature() const { return m_root_signature; } @@ -27,6 +28,8 @@ public: D3D12_PRIMITIVE_TOPOLOGY GetPrimitiveTopology() const { return m_primitive_topology; } bool UseIntegerRTV() const { return m_use_integer_rtv; } + CacheData GetCacheData() const override; + private: ID3D12PipelineState* m_pipeline; ID3D12RootSignature* m_root_signature; diff --git a/Source/Core/VideoBackends/D3D12/Renderer.cpp b/Source/Core/VideoBackends/D3D12/Renderer.cpp index bc7d121bfc..b834ba33e1 100644 --- a/Source/Core/VideoBackends/D3D12/Renderer.cpp +++ b/Source/Core/VideoBackends/D3D12/Renderer.cpp @@ -103,7 +103,7 @@ std::unique_ptr Renderer::CreatePipeline(const AbstractPipelin const void* cache_data, size_t cache_data_length) { - return DXPipeline::Create(config); + return DXPipeline::Create(config, cache_data, cache_data_length); } u16 Renderer::BBoxRead(int index)