mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-13 07:08:50 +01:00
[dxvk] Use precompiled compute pipelines whenever possible
This commit is contained in:
parent
6265b5b809
commit
cb56e16a4b
@ -14,11 +14,14 @@ namespace dxvk {
|
|||||||
DxvkDevice* device,
|
DxvkDevice* device,
|
||||||
DxvkPipelineManager* pipeMgr,
|
DxvkPipelineManager* pipeMgr,
|
||||||
DxvkComputePipelineShaders shaders,
|
DxvkComputePipelineShaders shaders,
|
||||||
DxvkBindingLayoutObjects* layout)
|
DxvkBindingLayoutObjects* layout,
|
||||||
|
DxvkShaderPipelineLibrary* library)
|
||||||
: m_device (device),
|
: m_device (device),
|
||||||
m_cache (&pipeMgr->m_cache),
|
m_cache (&pipeMgr->m_cache),
|
||||||
m_stateCache (&pipeMgr->m_stateCache),
|
m_stateCache (&pipeMgr->m_stateCache),
|
||||||
m_stats (&pipeMgr->m_stats),
|
m_stats (&pipeMgr->m_stats),
|
||||||
|
m_library (library),
|
||||||
|
m_libraryHandle (VK_NULL_HANDLE),
|
||||||
m_shaders (std::move(shaders)),
|
m_shaders (std::move(shaders)),
|
||||||
m_bindings (layout) {
|
m_bindings (layout) {
|
||||||
|
|
||||||
@ -33,28 +36,43 @@ namespace dxvk {
|
|||||||
|
|
||||||
VkPipeline DxvkComputePipeline::getPipelineHandle(
|
VkPipeline DxvkComputePipeline::getPipelineHandle(
|
||||||
const DxvkComputePipelineStateInfo& state) {
|
const DxvkComputePipelineStateInfo& state) {
|
||||||
DxvkComputePipelineInstance* instance = this->findInstance(state);
|
if (m_library) {
|
||||||
|
// For compute pipelines that can be precompiled, we can use that
|
||||||
if (unlikely(!instance)) {
|
// pipeline variant unconditionally since there is no state for us
|
||||||
std::lock_guard<dxvk::mutex> lock(m_mutex);
|
// to worry about other than specialization constants
|
||||||
instance = this->findInstance(state);
|
if (unlikely(!m_libraryHandle)) {
|
||||||
|
m_libraryHandle = m_library->getPipelineHandle(m_cache->handle(),
|
||||||
if (!instance) {
|
DxvkShaderPipelineLibraryCompileArgs());
|
||||||
instance = this->createInstance(state);
|
m_stats->numComputePipelines += 1;
|
||||||
this->writePipelineStateToCache(state);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return instance->pipeline();
|
return m_libraryHandle;
|
||||||
|
} else {
|
||||||
|
DxvkComputePipelineInstance* instance = this->findInstance(state);
|
||||||
|
|
||||||
|
if (unlikely(!instance)) {
|
||||||
|
std::lock_guard<dxvk::mutex> lock(m_mutex);
|
||||||
|
instance = this->findInstance(state);
|
||||||
|
|
||||||
|
if (!instance) {
|
||||||
|
instance = this->createInstance(state);
|
||||||
|
this->writePipelineStateToCache(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance->pipeline();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkComputePipeline::compilePipeline(
|
void DxvkComputePipeline::compilePipeline(
|
||||||
const DxvkComputePipelineStateInfo& state) {
|
const DxvkComputePipelineStateInfo& state) {
|
||||||
std::lock_guard<dxvk::mutex> lock(m_mutex);
|
if (!m_library) {
|
||||||
|
std::lock_guard<dxvk::mutex> lock(m_mutex);
|
||||||
|
|
||||||
if (!this->findInstance(state))
|
if (!this->findInstance(state))
|
||||||
this->createInstance(state);
|
this->createInstance(state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -96,7 +96,8 @@ namespace dxvk {
|
|||||||
DxvkDevice* device,
|
DxvkDevice* device,
|
||||||
DxvkPipelineManager* pipeMgr,
|
DxvkPipelineManager* pipeMgr,
|
||||||
DxvkComputePipelineShaders shaders,
|
DxvkComputePipelineShaders shaders,
|
||||||
DxvkBindingLayoutObjects* layout);
|
DxvkBindingLayoutObjects* layout,
|
||||||
|
DxvkShaderPipelineLibrary* library);
|
||||||
|
|
||||||
~DxvkComputePipeline();
|
~DxvkComputePipeline();
|
||||||
|
|
||||||
@ -146,6 +147,9 @@ namespace dxvk {
|
|||||||
DxvkStateCache* m_stateCache;
|
DxvkStateCache* m_stateCache;
|
||||||
DxvkPipelineStats* m_stats;
|
DxvkPipelineStats* m_stats;
|
||||||
|
|
||||||
|
DxvkShaderPipelineLibrary* m_library;
|
||||||
|
VkPipeline m_libraryHandle;
|
||||||
|
|
||||||
DxvkComputePipelineShaders m_shaders;
|
DxvkComputePipelineShaders m_shaders;
|
||||||
DxvkBindingLayoutObjects* m_bindings;
|
DxvkBindingLayoutObjects* m_bindings;
|
||||||
|
|
||||||
|
@ -189,11 +189,12 @@ namespace dxvk {
|
|||||||
return &pair->second;
|
return &pair->second;
|
||||||
|
|
||||||
auto layout = createPipelineLayout(shaders.cs->getBindings());
|
auto layout = createPipelineLayout(shaders.cs->getBindings());
|
||||||
|
auto library = findPipelineLibrary(shaders.cs);
|
||||||
|
|
||||||
auto iter = m_computePipelines.emplace(
|
auto iter = m_computePipelines.emplace(
|
||||||
std::piecewise_construct,
|
std::piecewise_construct,
|
||||||
std::tuple(shaders),
|
std::tuple(shaders),
|
||||||
std::tuple(m_device, this, shaders, layout));
|
std::tuple(m_device, this, shaders, layout, library));
|
||||||
return &iter.first->second;
|
return &iter.first->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,4 +343,17 @@ namespace dxvk {
|
|||||||
return &iter.first->second;
|
return &iter.first->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkShaderPipelineLibrary* DxvkPipelineManager::findPipelineLibrary(
|
||||||
|
const Rc<DxvkShader>& shader) {
|
||||||
|
DxvkShaderPipelineLibraryKey key;
|
||||||
|
key.shader = shader;
|
||||||
|
|
||||||
|
auto pair = m_shaderLibraries.find(key);
|
||||||
|
if (pair == m_shaderLibraries.end())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return &pair->second;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -271,6 +271,9 @@ namespace dxvk {
|
|||||||
DxvkShaderPipelineLibrary* createPipelineLibrary(
|
DxvkShaderPipelineLibrary* createPipelineLibrary(
|
||||||
const Rc<DxvkShader>& shader);
|
const Rc<DxvkShader>& shader);
|
||||||
|
|
||||||
|
DxvkShaderPipelineLibrary* findPipelineLibrary(
|
||||||
|
const Rc<DxvkShader>& shader);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user