mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-13 19:29:14 +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:
parent
3dc33c64a9
commit
d01b6baf38
@ -43,34 +43,49 @@ namespace dxvk {
|
||||
|
||||
VkPipeline DxvkComputePipeline::getPipelineHandle(
|
||||
const DxvkComputePipelineStateInfo& state) {
|
||||
VkPipeline newPipelineHandle = VK_NULL_HANDLE;
|
||||
DxvkComputePipelineInstance* instance = nullptr;
|
||||
|
||||
{ std::lock_guard<sync::Spinlock> lock(m_mutex);
|
||||
|
||||
auto instance = this->findInstance(state);
|
||||
instance = this->findInstance(state);
|
||||
|
||||
if (instance)
|
||||
return instance->pipeline();
|
||||
|
||||
// If no pipeline instance exists with the given state
|
||||
// vector, create a new one and add it to the list.
|
||||
newPipelineHandle = this->createPipeline(state);
|
||||
|
||||
// Add new pipeline to the set
|
||||
m_pipelines.emplace_back(state, newPipelineHandle);
|
||||
m_pipeMgr->m_numComputePipelines += 1;
|
||||
instance = this->createInstance(state);
|
||||
}
|
||||
|
||||
if (newPipelineHandle != VK_NULL_HANDLE)
|
||||
this->writePipelineStateToCache(state);
|
||||
|
||||
return newPipelineHandle;
|
||||
if (!instance)
|
||||
return VK_NULL_HANDLE;
|
||||
|
||||
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(
|
||||
const DxvkComputePipelineStateInfo& state) const {
|
||||
for (const auto& instance : m_pipelines) {
|
||||
DxvkComputePipelineInstance* DxvkComputePipeline::createInstance(
|
||||
const DxvkComputePipelineStateInfo& state) {
|
||||
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))
|
||||
return &instance;
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Pipeline handle
|
||||
* \brief Retrieves pipeline handle
|
||||
*
|
||||
* \param [in] state Pipeline state
|
||||
* \returns Pipeline handle
|
||||
@ -117,6 +117,16 @@ namespace dxvk {
|
||||
VkPipeline getPipelineHandle(
|
||||
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:
|
||||
|
||||
Rc<vk::DeviceFn> m_vkd;
|
||||
@ -130,8 +140,11 @@ namespace dxvk {
|
||||
sync::Spinlock m_mutex;
|
||||
std::vector<DxvkComputePipelineInstance> m_pipelines;
|
||||
|
||||
const DxvkComputePipelineInstance* findInstance(
|
||||
const DxvkComputePipelineStateInfo& state) const;
|
||||
DxvkComputePipelineInstance* createInstance(
|
||||
const DxvkComputePipelineStateInfo& state);
|
||||
|
||||
DxvkComputePipelineInstance* findInstance(
|
||||
const DxvkComputePipelineStateInfo& state);
|
||||
|
||||
VkPipeline createPipeline(
|
||||
const DxvkComputePipelineStateInfo& state) const;
|
||||
|
@ -97,43 +97,58 @@ namespace dxvk {
|
||||
VkPipeline DxvkGraphicsPipeline::getPipelineHandle(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
const DxvkRenderPass& renderPass) {
|
||||
VkRenderPass renderPassHandle = renderPass.getDefaultHandle();
|
||||
|
||||
VkPipeline newPipelineHandle = VK_NULL_HANDLE;
|
||||
DxvkGraphicsPipelineInstance* instance = nullptr;
|
||||
|
||||
{ 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();
|
||||
|
||||
// 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
|
||||
// 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;
|
||||
instance = this->createInstance(state, renderPass);
|
||||
}
|
||||
|
||||
if (newPipelineHandle != VK_NULL_HANDLE)
|
||||
this->writePipelineStateToCache(state, renderPass.format());
|
||||
|
||||
return newPipelineHandle;
|
||||
if (!instance)
|
||||
return VK_NULL_HANDLE;
|
||||
|
||||
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,
|
||||
VkRenderPass renderPass) const {
|
||||
for (const auto& instance : m_pipelines) {
|
||||
if (instance.isCompatible(state, renderPass))
|
||||
const DxvkRenderPass& renderPass) {
|
||||
VkRenderPass renderPassHandle = renderPass.getDefaultHandle();
|
||||
|
||||
for (auto& instance : m_pipelines) {
|
||||
if (instance.isCompatible(state, renderPassHandle))
|
||||
return &instance;
|
||||
}
|
||||
|
||||
|
@ -253,6 +253,18 @@ namespace dxvk {
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
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:
|
||||
|
||||
Rc<vk::DeviceFn> m_vkd;
|
||||
@ -273,9 +285,13 @@ namespace dxvk {
|
||||
alignas(CACHE_LINE_SIZE) sync::Spinlock m_mutex;
|
||||
std::vector<DxvkGraphicsPipelineInstance> m_pipelines;
|
||||
|
||||
const DxvkGraphicsPipelineInstance* findInstance(
|
||||
DxvkGraphicsPipelineInstance* createInstance(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
VkRenderPass renderPass) const;
|
||||
const DxvkRenderPass& renderPass);
|
||||
|
||||
DxvkGraphicsPipelineInstance* findInstance(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
const DxvkRenderPass& renderPass);
|
||||
|
||||
VkPipeline createPipeline(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
|
@ -262,7 +262,7 @@ namespace dxvk {
|
||||
const auto& entry = m_entries[e->second];
|
||||
|
||||
auto rp = m_passManager->getRenderPass(entry.format);
|
||||
pipeline->getPipelineHandle(entry.gpState, *rp);
|
||||
pipeline->compilePipeline(entry.gpState, *rp);
|
||||
}
|
||||
} else {
|
||||
auto pipeline = m_pipeManager->createComputePipeline(item.cp);
|
||||
@ -270,7 +270,7 @@ namespace dxvk {
|
||||
|
||||
for (auto e = entries.first; e != entries.second; e++) {
|
||||
const auto& entry = m_entries[e->second];
|
||||
pipeline->getPipelineHandle(entry.cpState);
|
||||
pipeline->compilePipeline(entry.cpState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user