mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 05:52:11 +01:00
[dxvk] Add use counter to pipeline libraries
And destroy Vulkan pipeline objects once the counter reaches zero.
This commit is contained in:
parent
1f9db49727
commit
764de6ff82
@ -30,6 +30,9 @@ namespace dxvk {
|
||||
|
||||
|
||||
DxvkComputePipeline::~DxvkComputePipeline() {
|
||||
if (m_libraryHandle)
|
||||
m_library->releasePipelineHandle();
|
||||
|
||||
for (const auto& instance : m_pipelines)
|
||||
this->destroyPipeline(instance.handle);
|
||||
}
|
||||
@ -45,7 +48,7 @@ namespace dxvk {
|
||||
// Retrieve actual pipeline handle on first use. This
|
||||
// may wait for an ongoing compile job to finish, or
|
||||
// compile the pipeline immediately on the calling thread.
|
||||
m_libraryHandle = m_library->getPipelineHandle(
|
||||
m_libraryHandle = m_library->acquirePipelineHandle(
|
||||
DxvkShaderPipelineLibraryCompileArgs());
|
||||
|
||||
return m_libraryHandle;
|
||||
|
@ -880,9 +880,13 @@ namespace dxvk {
|
||||
|
||||
|
||||
DxvkGraphicsPipeline::~DxvkGraphicsPipeline() {
|
||||
for (const auto& instance : m_fastPipelines)
|
||||
for (const auto& instance : m_fastPipelines) {
|
||||
this->destroyPipeline(instance.second);
|
||||
|
||||
m_vsLibrary->releasePipelineHandle();
|
||||
m_fsLibrary->releasePipelineHandle();
|
||||
}
|
||||
|
||||
for (const auto& instance : m_basePipelines)
|
||||
this->destroyPipeline(instance.second);
|
||||
}
|
||||
@ -1102,8 +1106,8 @@ namespace dxvk {
|
||||
|
||||
std::array<VkPipeline, 4> libraries = {{
|
||||
key.viLibrary->getHandle(),
|
||||
m_vsLibrary->getPipelineHandle(key.args),
|
||||
m_fsLibrary->getPipelineHandle(key.args),
|
||||
m_vsLibrary->acquirePipelineHandle(key.args),
|
||||
m_fsLibrary->acquirePipelineHandle(key.args),
|
||||
key.foLibrary->getHandle(),
|
||||
}};
|
||||
|
||||
|
@ -890,10 +890,7 @@ namespace dxvk {
|
||||
|
||||
|
||||
DxvkShaderPipelineLibrary::~DxvkShaderPipelineLibrary() {
|
||||
auto vk = m_device->vkd();
|
||||
|
||||
vk->vkDestroyPipeline(vk->device(), m_pipeline, nullptr);
|
||||
vk->vkDestroyPipeline(vk->device(), m_pipelineNoDepthClip, nullptr);
|
||||
this->destroyShaderPipelinesLocked();
|
||||
}
|
||||
|
||||
|
||||
@ -911,10 +908,13 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
VkPipeline DxvkShaderPipelineLibrary::getPipelineHandle(
|
||||
VkPipeline DxvkShaderPipelineLibrary::acquirePipelineHandle(
|
||||
const DxvkShaderPipelineLibraryCompileArgs& args) {
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
if (m_device->mustTrackPipelineLifetime())
|
||||
m_useCount += 1;
|
||||
|
||||
VkShaderStageFlagBits stage = getShaderStage();
|
||||
|
||||
VkPipeline& pipeline = (stage == VK_SHADER_STAGE_VERTEX_BIT && !args.depthClipEnable)
|
||||
@ -929,6 +929,16 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkShaderPipelineLibrary::releasePipelineHandle() {
|
||||
if (m_device->mustTrackPipelineLifetime()) {
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
if (!(--m_useCount))
|
||||
this->destroyShaderPipelinesLocked();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DxvkShaderPipelineLibrary::compilePipeline() {
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
@ -955,6 +965,17 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkShaderPipelineLibrary::destroyShaderPipelinesLocked() {
|
||||
auto vk = m_device->vkd();
|
||||
|
||||
vk->vkDestroyPipeline(vk->device(), m_pipeline, nullptr);
|
||||
vk->vkDestroyPipeline(vk->device(), m_pipelineNoDepthClip, nullptr);
|
||||
|
||||
m_pipeline = VK_NULL_HANDLE;
|
||||
m_pipelineNoDepthClip = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
|
||||
VkPipeline DxvkShaderPipelineLibrary::compileShaderPipelineLocked(
|
||||
const DxvkShaderPipelineLibraryCompileArgs& args) {
|
||||
VkShaderStageFlagBits stage = getShaderStage();
|
||||
|
@ -396,16 +396,26 @@ namespace dxvk {
|
||||
VkShaderModuleIdentifierEXT getModuleIdentifier();
|
||||
|
||||
/**
|
||||
* \brief Queries pipeline handle for the given set of arguments
|
||||
* \brief Acquires pipeline handle for the given set of arguments
|
||||
*
|
||||
* Either returns an already compiled pipeline library object, or
|
||||
* performs the compilation step if that has not happened yet.
|
||||
* Increments the use count by one.
|
||||
* \param [in] args Compile arguments
|
||||
* \returns Vulkan pipeline handle
|
||||
*/
|
||||
VkPipeline getPipelineHandle(
|
||||
VkPipeline acquirePipelineHandle(
|
||||
const DxvkShaderPipelineLibraryCompileArgs& args);
|
||||
|
||||
/**
|
||||
* \brief Releases pipeline
|
||||
*
|
||||
* Decrements the use count by 1. If the use count reaches 0,
|
||||
* any previously compiled pipeline library object may be
|
||||
* destroyed in order to save memory.
|
||||
*/
|
||||
void releasePipelineHandle();
|
||||
|
||||
/**
|
||||
* \brief Compiles the pipeline with default arguments
|
||||
*
|
||||
@ -425,11 +435,14 @@ namespace dxvk {
|
||||
dxvk::mutex m_mutex;
|
||||
VkPipeline m_pipeline = VK_NULL_HANDLE;
|
||||
VkPipeline m_pipelineNoDepthClip = VK_NULL_HANDLE;
|
||||
uint32_t m_useCount = 0u;
|
||||
bool m_compiledOnce = false;
|
||||
|
||||
dxvk::mutex m_identifierMutex;
|
||||
VkShaderModuleIdentifierEXT m_identifier = { VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT };
|
||||
|
||||
void destroyShaderPipelinesLocked();
|
||||
|
||||
VkPipeline compileShaderPipelineLocked(
|
||||
const DxvkShaderPipelineLibraryCompileArgs& args);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user