[dxvk] Reuse linked base pipelines if possible

No reason to create identical pipelines multiple times.
This commit is contained in:
Philip Rebohle 2022-07-07 15:29:10 +02:00
parent 5562ff4472
commit 498444f1a8
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 50 additions and 8 deletions

View File

@ -494,10 +494,11 @@ namespace dxvk {
DxvkGraphicsPipeline::~DxvkGraphicsPipeline() {
for (const auto& instance : m_pipelines) {
this->destroyPipeline(instance.baseHandle.load());
for (const auto& instance : m_pipelines)
this->destroyPipeline(instance.fastHandle.load());
}
for (const auto& instance : m_basePipelines)
this->destroyPipeline(instance.handle);
}
@ -610,7 +611,7 @@ namespace dxvk {
key.foLibrary = m_manager->createFragmentOutputLibrary(foState);
key.args.depthClipEnable = state.rs.depthClipEnable();
baseHandle = this->createBasePipeline(key);
baseHandle = this->createBaseInstance(key)->handle;
} else {
// Create optimized variant right away, no choice
fastHandle = this->createOptimizedPipeline(state);
@ -632,6 +633,20 @@ namespace dxvk {
}
DxvkGraphicsPipelineBaseInstance* DxvkGraphicsPipeline::createBaseInstance(
const DxvkGraphicsPipelineBaseInstanceKey& key) {
for (auto& instance : m_basePipelines) {
if (instance.key.viLibrary == key.viLibrary
&& instance.key.foLibrary == key.foLibrary
&& instance.key.args == key.args)
return &instance;
}
VkPipeline handle = createBasePipeline(key);
return &(*m_basePipelines.emplace(key, handle));
}
bool DxvkGraphicsPipeline::canCreateBasePipeline(
const DxvkGraphicsPipelineStateInfo& state) const {
if (!m_vsLibrary || !m_fsLibrary)

View File

@ -263,12 +263,35 @@ namespace dxvk {
};
/**
* \brief Base instance key
*
* Stores the libraries and arguments used to
* compile a base pipeline.
*/
struct DxvkGraphicsPipelineBaseInstanceKey {
const DxvkGraphicsPipelineVertexInputLibrary* viLibrary;
const DxvkGraphicsPipelineFragmentOutputLibrary* foLibrary;
const DxvkGraphicsPipelineVertexInputLibrary* viLibrary = nullptr;
const DxvkGraphicsPipelineFragmentOutputLibrary* foLibrary = nullptr;
DxvkShaderPipelineLibraryCompileArgs args;
};
/**
* \brief Base pipeline instance
*
* Stores the key and handle of a base pipeline.
*/
struct DxvkGraphicsPipelineBaseInstance {
DxvkGraphicsPipelineBaseInstance() { }
DxvkGraphicsPipelineBaseInstance(
const DxvkGraphicsPipelineBaseInstanceKey& key_,
VkPipeline handle_)
: key(key_), handle(handle_) { }
DxvkGraphicsPipelineBaseInstanceKey key;
VkPipeline handle = VK_NULL_HANDLE;
};
/**
* \brief Graphics pipeline
@ -386,8 +409,9 @@ namespace dxvk {
// List of pipeline instances, shared between threads
alignas(CACHE_LINE_SIZE)
dxvk::mutex m_mutex;
sync::List<DxvkGraphicsPipelineInstance> m_pipelines;
dxvk::mutex m_mutex;
sync::List<DxvkGraphicsPipelineInstance> m_pipelines;
sync::List<DxvkGraphicsPipelineBaseInstance> m_basePipelines;
DxvkGraphicsPipelineInstance* createInstance(
const DxvkGraphicsPipelineStateInfo& state);
@ -395,6 +419,9 @@ namespace dxvk {
DxvkGraphicsPipelineInstance* findInstance(
const DxvkGraphicsPipelineStateInfo& state);
DxvkGraphicsPipelineBaseInstance* createBaseInstance(
const DxvkGraphicsPipelineBaseInstanceKey& key);
bool canCreateBasePipeline(
const DxvkGraphicsPipelineStateInfo& state) const;