1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-14 22:29:15 +01:00

[dxvk] Introduce compilePipeline method to Dxvk*Pipeline classes

Decouples the act of synchronously retrieving a handle
from asynchronously compiling the pipeline.
This commit is contained in:
Philip Rebohle 2019-07-30 12:14:52 +02:00
parent 3dc33c64a9
commit d01b6baf38
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
5 changed files with 105 additions and 46 deletions

View File

@ -43,34 +43,49 @@ namespace dxvk {
VkPipeline DxvkComputePipeline::getPipelineHandle( VkPipeline DxvkComputePipeline::getPipelineHandle(
const DxvkComputePipelineStateInfo& state) { const DxvkComputePipelineStateInfo& state) {
VkPipeline newPipelineHandle = VK_NULL_HANDLE; DxvkComputePipelineInstance* instance = nullptr;
{ std::lock_guard<sync::Spinlock> lock(m_mutex); { std::lock_guard<sync::Spinlock> lock(m_mutex);
auto instance = this->findInstance(state); instance = this->findInstance(state);
if (instance) if (instance)
return instance->pipeline(); return instance->pipeline();
// If no pipeline instance exists with the given state // If no pipeline instance exists with the given state
// vector, create a new one and add it to the list. // vector, create a new one and add it to the list.
newPipelineHandle = this->createPipeline(state); instance = this->createInstance(state);
// Add new pipeline to the set
m_pipelines.emplace_back(state, newPipelineHandle);
m_pipeMgr->m_numComputePipelines += 1;
} }
if (newPipelineHandle != VK_NULL_HANDLE) if (!instance)
this->writePipelineStateToCache(state); return VK_NULL_HANDLE;
return newPipelineHandle; this->writePipelineStateToCache(state);
return instance->pipeline();
}
void DxvkComputePipeline::compilePipeline(
const DxvkComputePipelineStateInfo& state) {
std::lock_guard<sync::Spinlock> lock(m_mutex);
if (!this->findInstance(state))
this->createInstance(state);
} }
const DxvkComputePipelineInstance* DxvkComputePipeline::findInstance( DxvkComputePipelineInstance* DxvkComputePipeline::createInstance(
const DxvkComputePipelineStateInfo& state) const { const DxvkComputePipelineStateInfo& state) {
for (const auto& instance : m_pipelines) { VkPipeline newPipelineHandle = this->createPipeline(state);
m_pipeMgr->m_numComputePipelines += 1;
return &m_pipelines.emplace_back(state, newPipelineHandle);
}
DxvkComputePipelineInstance* DxvkComputePipeline::findInstance(
const DxvkComputePipelineStateInfo& state) {
for (auto& instance : m_pipelines) {
if (instance.isCompatible(state)) if (instance.isCompatible(state))
return &instance; return &instance;
} }

View File

@ -109,7 +109,7 @@ namespace dxvk {
} }
/** /**
* \brief Pipeline handle * \brief Retrieves pipeline handle
* *
* \param [in] state Pipeline state * \param [in] state Pipeline state
* \returns Pipeline handle * \returns Pipeline handle
@ -117,6 +117,16 @@ namespace dxvk {
VkPipeline getPipelineHandle( VkPipeline getPipelineHandle(
const DxvkComputePipelineStateInfo& state); const DxvkComputePipelineStateInfo& state);
/**
* \brief Compiles a pipeline
*
* Asynchronously compiles the given pipeline
* and stores the result for future use.
* \param [in] state Pipeline state
*/
void compilePipeline(
const DxvkComputePipelineStateInfo& state);
private: private:
Rc<vk::DeviceFn> m_vkd; Rc<vk::DeviceFn> m_vkd;
@ -130,8 +140,11 @@ namespace dxvk {
sync::Spinlock m_mutex; sync::Spinlock m_mutex;
std::vector<DxvkComputePipelineInstance> m_pipelines; std::vector<DxvkComputePipelineInstance> m_pipelines;
const DxvkComputePipelineInstance* findInstance( DxvkComputePipelineInstance* createInstance(
const DxvkComputePipelineStateInfo& state) const; const DxvkComputePipelineStateInfo& state);
DxvkComputePipelineInstance* findInstance(
const DxvkComputePipelineStateInfo& state);
VkPipeline createPipeline( VkPipeline createPipeline(
const DxvkComputePipelineStateInfo& state) const; const DxvkComputePipelineStateInfo& state) const;

View File

@ -97,43 +97,58 @@ namespace dxvk {
VkPipeline DxvkGraphicsPipeline::getPipelineHandle( VkPipeline DxvkGraphicsPipeline::getPipelineHandle(
const DxvkGraphicsPipelineStateInfo& state, const DxvkGraphicsPipelineStateInfo& state,
const DxvkRenderPass& renderPass) { const DxvkRenderPass& renderPass) {
VkRenderPass renderPassHandle = renderPass.getDefaultHandle(); DxvkGraphicsPipelineInstance* instance = nullptr;
VkPipeline newPipelineHandle = VK_NULL_HANDLE;
{ std::lock_guard<sync::Spinlock> lock(m_mutex); { std::lock_guard<sync::Spinlock> lock(m_mutex);
auto instance = this->findInstance(state, renderPassHandle); instance = this->findInstance(state, renderPass);
if (instance != nullptr) if (instance)
return instance->pipeline(); return instance->pipeline();
// If the pipeline state vector is invalid, don't try
// to create a new pipeline, it won't work anyway.
if (!this->validatePipelineState(state))
return VK_NULL_HANDLE;
// If no pipeline instance exists with the given state instance = this->createInstance(state, renderPass);
// vector, create a new one and add it to the list.
newPipelineHandle = this->createPipeline(state, renderPass);
// Add new pipeline to the set
m_pipelines.emplace_back(state, renderPassHandle, newPipelineHandle);
m_pipeMgr->m_numGraphicsPipelines += 1;
} }
if (newPipelineHandle != VK_NULL_HANDLE) if (!instance)
this->writePipelineStateToCache(state, renderPass.format()); return VK_NULL_HANDLE;
return newPipelineHandle; this->writePipelineStateToCache(state, renderPass.format());
return instance->pipeline();
}
void DxvkGraphicsPipeline::compilePipeline(
const DxvkGraphicsPipelineStateInfo& state,
const DxvkRenderPass& renderPass) {
std::lock_guard<sync::Spinlock> lock(m_mutex);
if (!this->findInstance(state, renderPass))
this->createInstance(state, renderPass);
}
DxvkGraphicsPipelineInstance* DxvkGraphicsPipeline::createInstance(
const DxvkGraphicsPipelineStateInfo& state,
const DxvkRenderPass& renderPass) {
// If the pipeline state vector is invalid, don't try
// to create a new pipeline, it won't work anyway.
if (!this->validatePipelineState(state))
return nullptr;
VkPipeline newPipelineHandle = this->createPipeline(state, renderPass);
m_pipeMgr->m_numGraphicsPipelines += 1;
return &m_pipelines.emplace_back(state, renderPass.getDefaultHandle(), newPipelineHandle);
} }
const DxvkGraphicsPipelineInstance* DxvkGraphicsPipeline::findInstance( DxvkGraphicsPipelineInstance* DxvkGraphicsPipeline::findInstance(
const DxvkGraphicsPipelineStateInfo& state, const DxvkGraphicsPipelineStateInfo& state,
VkRenderPass renderPass) const { const DxvkRenderPass& renderPass) {
for (const auto& instance : m_pipelines) { VkRenderPass renderPassHandle = renderPass.getDefaultHandle();
if (instance.isCompatible(state, renderPass))
for (auto& instance : m_pipelines) {
if (instance.isCompatible(state, renderPassHandle))
return &instance; return &instance;
} }

View File

@ -253,6 +253,18 @@ namespace dxvk {
const DxvkGraphicsPipelineStateInfo& state, const DxvkGraphicsPipelineStateInfo& state,
const DxvkRenderPass& renderPass); const DxvkRenderPass& renderPass);
/**
* \brief Compiles a pipeline
*
* Asynchronously compiles the given pipeline
* and stores the result for future use.
* \param [in] state Pipeline state vector
* \param [in] renderPass The render pass
*/
void compilePipeline(
const DxvkGraphicsPipelineStateInfo& state,
const DxvkRenderPass& renderPass);
private: private:
Rc<vk::DeviceFn> m_vkd; Rc<vk::DeviceFn> m_vkd;
@ -273,9 +285,13 @@ namespace dxvk {
alignas(CACHE_LINE_SIZE) sync::Spinlock m_mutex; alignas(CACHE_LINE_SIZE) sync::Spinlock m_mutex;
std::vector<DxvkGraphicsPipelineInstance> m_pipelines; std::vector<DxvkGraphicsPipelineInstance> m_pipelines;
const DxvkGraphicsPipelineInstance* findInstance( DxvkGraphicsPipelineInstance* createInstance(
const DxvkGraphicsPipelineStateInfo& state, const DxvkGraphicsPipelineStateInfo& state,
VkRenderPass renderPass) const; const DxvkRenderPass& renderPass);
DxvkGraphicsPipelineInstance* findInstance(
const DxvkGraphicsPipelineStateInfo& state,
const DxvkRenderPass& renderPass);
VkPipeline createPipeline( VkPipeline createPipeline(
const DxvkGraphicsPipelineStateInfo& state, const DxvkGraphicsPipelineStateInfo& state,

View File

@ -262,7 +262,7 @@ namespace dxvk {
const auto& entry = m_entries[e->second]; const auto& entry = m_entries[e->second];
auto rp = m_passManager->getRenderPass(entry.format); auto rp = m_passManager->getRenderPass(entry.format);
pipeline->getPipelineHandle(entry.gpState, *rp); pipeline->compilePipeline(entry.gpState, *rp);
} }
} else { } else {
auto pipeline = m_pipeManager->createComputePipeline(item.cp); auto pipeline = m_pipeManager->createComputePipeline(item.cp);
@ -270,7 +270,7 @@ namespace dxvk {
for (auto e = entries.first; e != entries.second; e++) { for (auto e = entries.first; e != entries.second; e++) {
const auto& entry = m_entries[e->second]; const auto& entry = m_entries[e->second];
pipeline->getPipelineHandle(entry.cpState); pipeline->compilePipeline(entry.cpState);
} }
} }
} }