From 0c2058e8c4b39267be1ef520064eae5d4f656eb3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 14 Feb 2018 17:54:35 +0100 Subject: [PATCH] [dxvk] Introduced DxvkComputePipelineStateInfo Will be used to re-compile compute pipelines against the current state, just like graphics pipelines. May fix GPU lockups etc. --- src/dxvk/dxvk_compute.cpp | 19 +++++++++++++++++++ src/dxvk/dxvk_compute.h | 25 +++++++++++++++++++------ src/dxvk/dxvk_context.cpp | 24 ++++++++++++++++-------- src/dxvk/dxvk_context.h | 1 + src/dxvk/dxvk_context_state.h | 17 +++++++++-------- 5 files changed, 64 insertions(+), 22 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 5713b929e..9e0b6e18d 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -1,8 +1,20 @@ +#include + #include "dxvk_compute.h" #include "dxvk_device.h" namespace dxvk { + bool DxvkComputePipelineStateInfo::operator == (const DxvkComputePipelineStateInfo& other) const { + return std::memcmp(this, &other, sizeof(DxvkComputePipelineStateInfo)) == 0; + } + + + bool DxvkComputePipelineStateInfo::operator != (const DxvkComputePipelineStateInfo& other) const { + return std::memcmp(this, &other, sizeof(DxvkComputePipelineStateInfo)) != 0; + } + + DxvkComputePipeline::DxvkComputePipeline( const DxvkDevice* device, const Rc& cache, @@ -28,6 +40,13 @@ namespace dxvk { } + VkPipeline DxvkComputePipeline::getPipelineHandle( + const DxvkComputePipelineStateInfo& state) const { + // TODO take pipeine state into account + return m_pipeline; + } + + void DxvkComputePipeline::compilePipeline() { std::vector bindings; diff --git a/src/dxvk/dxvk_compute.h b/src/dxvk/dxvk_compute.h index e1c605fd2..f63dbc82f 100644 --- a/src/dxvk/dxvk_compute.h +++ b/src/dxvk/dxvk_compute.h @@ -1,5 +1,6 @@ #pragma once +#include "dxvk_binding.h" #include "dxvk_pipecache.h" #include "dxvk_pipelayout.h" #include "dxvk_resource.h" @@ -9,6 +10,17 @@ namespace dxvk { class DxvkDevice; + /** + * \brief Compute pipeline state info + */ + struct DxvkComputePipelineStateInfo { + bool operator == (const DxvkComputePipelineStateInfo& other) const; + bool operator != (const DxvkComputePipelineStateInfo& other) const; + + DxvkBindingState bsBindingState; + }; + + /** * \brief Compute pipeline * @@ -41,20 +53,21 @@ namespace dxvk { /** * \brief Pipeline handle + * + * \param [in] state Pipeline state * \returns Pipeline handle */ - VkPipeline getPipelineHandle() const { - return m_pipeline; - } + VkPipeline getPipelineHandle( + const DxvkComputePipelineStateInfo& state) const; private: const DxvkDevice* const m_device; const Rc m_vkd; - Rc m_cache; - Rc m_layout; - Rc m_cs; + Rc m_cache; + Rc m_layout; + Rc m_cs; VkPipeline m_pipeline = VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index cb2ab67a6..a5d95c789 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1238,15 +1238,23 @@ namespace dxvk { if (m_flags.test(DxvkContextFlag::CpDirtyPipeline)) { m_flags.clr(DxvkContextFlag::CpDirtyPipeline); + m_state.cp.state.bsBindingState.clear(); m_state.cp.pipeline = m_device->createComputePipeline( m_state.cp.cs.shader); - m_cpActivePipeline = m_state.cp.pipeline != nullptr - ? m_state.cp.pipeline->getPipelineHandle() - : VK_NULL_HANDLE; - if (m_state.cp.pipeline != nullptr) m_cmd->trackResource(m_state.cp.pipeline); + } + } + + + void DxvkContext::updateComputePipelineState() { + if (m_flags.test(DxvkContextFlag::CpDirtyPipelineState)) { + m_flags.clr(DxvkContextFlag::CpDirtyPipelineState); + + m_cpActivePipeline = m_state.cp.pipeline != nullptr + ? m_state.cp.pipeline->getPipelineHandle(m_state.cp.state) + : VK_NULL_HANDLE; if (m_cpActivePipeline != VK_NULL_HANDLE) { m_cmd->cmdBindPipeline( @@ -1329,7 +1337,7 @@ namespace dxvk { if (m_state.cp.pipeline != nullptr) { this->updateShaderDescriptors( VK_PIPELINE_BIND_POINT_COMPUTE, - m_state.cp.bs, + m_state.cp.state.bsBindingState, m_state.cp.pipeline->layout()); } } @@ -1367,7 +1375,7 @@ namespace dxvk { DxvkBindingState& bs = bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS ? m_state.gp.state.bsBindingState - : m_state.cp.bs; + : m_state.cp.state.bsBindingState; bool updatePipelineState = false; @@ -1538,10 +1546,10 @@ namespace dxvk { void DxvkContext::commitComputeState() { - // TODO handle CpDirtyPipelineState this->renderPassEnd(); this->updateComputePipeline(); this->updateComputeShaderResources(); + this->updateComputePipelineState(); this->updateComputeShaderDescriptors(); } @@ -1565,7 +1573,7 @@ namespace dxvk { auto layout = m_state.cp.pipeline->layout(); for (uint32_t i = 0; i < layout->bindingCount(); i++) { - if (m_state.cp.bs.isBound(i)) { + if (m_state.cp.state.bsBindingState.isBound(i)) { const DxvkDescriptorSlot binding = layout->binding(i); const DxvkShaderResourceSlot& slot = m_rc[binding.slot]; diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index e0d88e0f5..c0143b0cb 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -564,6 +564,7 @@ namespace dxvk { void renderPassEnd(); void updateComputePipeline(); + void updateComputePipelineState(); void updateGraphicsPipeline(); void updateGraphicsPipelineState(); diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index 9b34ce749..d28b0a110 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -71,11 +71,11 @@ namespace dxvk { struct DxvkGraphicsPipelineState { - DxvkShaderStage vs; - DxvkShaderStage tcs; - DxvkShaderStage tes; - DxvkShaderStage gs; - DxvkShaderStage fs; + DxvkShaderStage vs; + DxvkShaderStage tcs; + DxvkShaderStage tes; + DxvkShaderStage gs; + DxvkShaderStage fs; DxvkGraphicsPipelineStateInfo state; Rc pipeline; @@ -83,9 +83,10 @@ namespace dxvk { struct DxvkComputePipelineState { - DxvkBindingState bs; - DxvkShaderStage cs; - Rc pipeline; + DxvkShaderStage cs; + + DxvkComputePipelineStateInfo state; + Rc pipeline; };