mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 14:52:10 +01:00
[dxvk] Enable state cache for compute pipelines
Also cleans up some code to get the design more in line with how graphics pipelines are handled.
This commit is contained in:
parent
6c8ac9e5f4
commit
b49876528a
@ -5,6 +5,7 @@
|
|||||||
#include "dxvk_device.h"
|
#include "dxvk_device.h"
|
||||||
#include "dxvk_pipemanager.h"
|
#include "dxvk_pipemanager.h"
|
||||||
#include "dxvk_spec_const.h"
|
#include "dxvk_spec_const.h"
|
||||||
|
#include "dxvk_state_cache.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
@ -40,7 +41,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
DxvkComputePipeline::~DxvkComputePipeline() {
|
DxvkComputePipeline::~DxvkComputePipeline() {
|
||||||
this->destroyPipelines();
|
for (const auto& instance : m_pipelines)
|
||||||
|
this->destroyPipeline(instance.pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -54,28 +56,41 @@ namespace dxvk {
|
|||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no pipeline exists with the given state vector,
|
// If no pipeline instance exists with the given state
|
||||||
// create a new one and add it to the pipeline set.
|
// vector, create a new one and add it to the list.
|
||||||
VkPipeline newPipeline = this->compilePipeline(state, m_basePipeline);
|
VkPipeline newPipelineBase = m_basePipeline.load();
|
||||||
|
VkPipeline newPipelineHandle = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
// FIXME for some reason, compiling the exact
|
||||||
|
// same pipeline crashes inside driver code
|
||||||
|
{ std::lock_guard<sync::Spinlock> lock(m_mutex);
|
||||||
|
newPipelineHandle = this->compilePipeline(
|
||||||
|
state, newPipelineBase);
|
||||||
|
}
|
||||||
|
|
||||||
{ std::lock_guard<sync::Spinlock> lock(m_mutex);
|
{ std::lock_guard<sync::Spinlock> lock(m_mutex);
|
||||||
|
|
||||||
// Discard the pipeline if another thread
|
// Discard the pipeline if another thread
|
||||||
// was faster compiling the same pipeline
|
// was faster compiling the same pipeline
|
||||||
if (this->findPipeline(state, pipeline)) {
|
if (this->findPipeline(state, pipeline)) {
|
||||||
m_vkd->vkDestroyPipeline(m_vkd->device(), newPipeline, nullptr);
|
this->destroyPipeline(newPipelineHandle);
|
||||||
|
m_vkd->vkDestroyPipeline(m_vkd->device(), newPipelineHandle, nullptr);
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add new pipeline to the set
|
// Add new pipeline to the set
|
||||||
m_pipelines.push_back({ state, newPipeline });
|
m_pipelines.push_back({ state, newPipelineHandle });
|
||||||
m_pipeMgr->m_numComputePipelines += 1;
|
m_pipeMgr->m_numComputePipelines += 1;
|
||||||
|
|
||||||
if (m_basePipeline == VK_NULL_HANDLE)
|
|
||||||
m_basePipeline = newPipeline;
|
|
||||||
|
|
||||||
return newPipeline;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use the new pipeline as the base pipeline for derivative pipelines
|
||||||
|
if (newPipelineBase == VK_NULL_HANDLE && newPipelineHandle != VK_NULL_HANDLE)
|
||||||
|
m_basePipeline.compare_exchange_strong(newPipelineBase, newPipelineHandle);
|
||||||
|
|
||||||
|
if (newPipelineHandle != VK_NULL_HANDLE)
|
||||||
|
this->writePipelineStateToCache(state);
|
||||||
|
|
||||||
|
return newPipelineHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -143,9 +158,22 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkComputePipeline::destroyPipelines() {
|
void DxvkComputePipeline::destroyPipeline(VkPipeline pipeline) {
|
||||||
for (const PipelineStruct& pair : m_pipelines)
|
m_vkd->vkDestroyPipeline(m_vkd->device(), pipeline, nullptr);
|
||||||
m_vkd->vkDestroyPipeline(m_vkd->device(), pair.pipeline, nullptr);
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkComputePipeline::writePipelineStateToCache(
|
||||||
|
const DxvkComputePipelineStateInfo& state) const {
|
||||||
|
if (m_pipeMgr->m_stateCache == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DxvkStateCacheKey key;
|
||||||
|
|
||||||
|
if (m_cs != nullptr)
|
||||||
|
key.cs = m_cs->getShaderKey();
|
||||||
|
|
||||||
|
m_pipeMgr->m_stateCache->addComputePipeline(key, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "dxvk_bind_mask.h"
|
#include "dxvk_bind_mask.h"
|
||||||
@ -79,7 +80,7 @@ namespace dxvk {
|
|||||||
sync::Spinlock m_mutex;
|
sync::Spinlock m_mutex;
|
||||||
std::vector<PipelineStruct> m_pipelines;
|
std::vector<PipelineStruct> m_pipelines;
|
||||||
|
|
||||||
VkPipeline m_basePipeline = VK_NULL_HANDLE;
|
std::atomic<VkPipeline> m_basePipeline = { VK_NULL_HANDLE };
|
||||||
|
|
||||||
bool findPipeline(
|
bool findPipeline(
|
||||||
const DxvkComputePipelineStateInfo& state,
|
const DxvkComputePipelineStateInfo& state,
|
||||||
@ -89,7 +90,11 @@ namespace dxvk {
|
|||||||
const DxvkComputePipelineStateInfo& state,
|
const DxvkComputePipelineStateInfo& state,
|
||||||
VkPipeline baseHandle) const;
|
VkPipeline baseHandle) const;
|
||||||
|
|
||||||
void destroyPipelines();
|
void destroyPipeline(
|
||||||
|
VkPipeline pipeline);
|
||||||
|
|
||||||
|
void writePipelineStateToCache(
|
||||||
|
const DxvkComputePipelineStateInfo& state) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user