#pragma once #include <atomic> #include <vector> #include "dxvk_bind_mask.h" #include "dxvk_pipecache.h" #include "dxvk_pipelayout.h" #include "dxvk_resource.h" #include "dxvk_shader.h" #include "dxvk_stats.h" namespace dxvk { class DxvkDevice; class DxvkPipelineManager; /** * \brief Compute pipeline state info */ struct DxvkComputePipelineStateInfo { bool operator == (const DxvkComputePipelineStateInfo& other) const; bool operator != (const DxvkComputePipelineStateInfo& other) const; DxvkBindingMask bsBindingMask; }; /** * \brief Compute pipeline * * Stores a compute pipeline object and the corresponding * pipeline layout. Unlike graphics pipelines, compute * pipelines do not need to be recompiled against any sort * of pipeline state. */ class DxvkComputePipeline : public DxvkResource { public: DxvkComputePipeline( DxvkPipelineManager* pipeMgr, const Rc<DxvkShader>& cs); ~DxvkComputePipeline(); /** * \brief Pipeline layout * * Stores the pipeline layout and the descriptor set * layout, as well as information on the resource * slots used by the pipeline. * \returns Pipeline layout */ DxvkPipelineLayout* layout() const { return m_layout.ptr(); } /** * \brief Pipeline handle * * \param [in] state Pipeline state * \returns Pipeline handle */ VkPipeline getPipelineHandle( const DxvkComputePipelineStateInfo& state); private: struct PipelineStruct { DxvkComputePipelineStateInfo stateVector; VkPipeline pipeline; }; Rc<vk::DeviceFn> m_vkd; DxvkPipelineManager* m_pipeMgr; Rc<DxvkPipelineLayout> m_layout; Rc<DxvkShaderModule> m_cs; sync::Spinlock m_mutex; std::vector<PipelineStruct> m_pipelines; VkPipeline m_basePipeline = VK_NULL_HANDLE; bool findPipeline( const DxvkComputePipelineStateInfo& state, VkPipeline& pipeline) const; VkPipeline compilePipeline( const DxvkComputePipelineStateInfo& state, VkPipeline baseHandle) const; void destroyPipeline( VkPipeline pipeline); void writePipelineStateToCache( const DxvkComputePipelineStateInfo& state) const; }; }