1
0
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:
Philip Rebohle 2022-07-06 01:14:02 +02:00
parent 6265b5b809
commit cb56e16a4b
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 56 additions and 17 deletions

View File

@ -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);
}
} }

View File

@ -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;

View File

@ -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;
} }
@ -341,5 +342,18 @@ namespace dxvk {
std::tuple(m_device, shader.ptr(), layout)); std::tuple(m_device, shader.ptr(), layout));
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;
}
} }

View File

@ -271,6 +271,9 @@ namespace dxvk {
DxvkShaderPipelineLibrary* createPipelineLibrary( DxvkShaderPipelineLibrary* createPipelineLibrary(
const Rc<DxvkShader>& shader); const Rc<DxvkShader>& shader);
DxvkShaderPipelineLibrary* findPipelineLibrary(
const Rc<DxvkShader>& shader);
}; };
} }