mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-13 16:08:50 +01:00
[dxvk] Use unordered map to look up base pipelines
No reason to use a linear list here. The object is always locked when we access this list, so we don't need the lock-free one here.
This commit is contained in:
parent
0eaad2eb5b
commit
0a15146746
@ -541,7 +541,7 @@ namespace dxvk {
|
||||
this->destroyPipeline(instance.fastHandle.load());
|
||||
|
||||
for (const auto& instance : m_basePipelines)
|
||||
this->destroyPipeline(instance.handle);
|
||||
this->destroyPipeline(instance.second);
|
||||
}
|
||||
|
||||
|
||||
@ -654,19 +654,10 @@ namespace dxvk {
|
||||
VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT);
|
||||
}
|
||||
|
||||
if (!fastHandle) {
|
||||
// If that didn't succeed, link a pipeline using the
|
||||
// pre-compiled fragment and vertex shader libraries.
|
||||
DxvkGraphicsPipelineVertexInputState viState(m_device, state, m_shaders.vs.ptr());
|
||||
DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr());
|
||||
|
||||
DxvkGraphicsPipelineBaseInstanceKey key;
|
||||
key.viLibrary = m_manager->createVertexInputLibrary(viState);
|
||||
key.foLibrary = m_manager->createFragmentOutputLibrary(foState);
|
||||
key.args.depthClipEnable = state.rs.depthClipEnable();
|
||||
|
||||
baseHandle = this->createBaseInstance(key)->handle;
|
||||
}
|
||||
// If that didn't succeed, link a pipeline using the
|
||||
// pre-compiled fragment and vertex shader libraries.
|
||||
if (!fastHandle)
|
||||
baseHandle = this->getBasePipeline(state);
|
||||
} else {
|
||||
// Create optimized variant right away, no choice
|
||||
fastHandle = this->createOptimizedPipeline(state, 0);
|
||||
@ -692,20 +683,6 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
DxvkGraphicsPipelineBaseInstance* DxvkGraphicsPipeline::createBaseInstance(
|
||||
const DxvkGraphicsPipelineBaseInstanceKey& key) {
|
||||
for (auto& instance : m_basePipelines) {
|
||||
if (instance.key.viLibrary == key.viLibrary
|
||||
&& instance.key.foLibrary == key.foLibrary
|
||||
&& instance.key.args == key.args)
|
||||
return &instance;
|
||||
}
|
||||
|
||||
VkPipeline handle = createBasePipeline(key);
|
||||
return &(*m_basePipelines.emplace(key, handle));
|
||||
}
|
||||
|
||||
|
||||
bool DxvkGraphicsPipeline::canCreateBasePipeline(
|
||||
const DxvkGraphicsPipelineStateInfo& state) const {
|
||||
if (!m_vsLibrary || !m_fsLibrary)
|
||||
@ -751,6 +728,26 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
VkPipeline DxvkGraphicsPipeline::getBasePipeline(
|
||||
const DxvkGraphicsPipelineStateInfo& state) {
|
||||
DxvkGraphicsPipelineVertexInputState viState(m_device, state, m_shaders.vs.ptr());
|
||||
DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr());
|
||||
|
||||
DxvkGraphicsPipelineBaseInstanceKey key;
|
||||
key.viLibrary = m_manager->createVertexInputLibrary(viState);
|
||||
key.foLibrary = m_manager->createFragmentOutputLibrary(foState);
|
||||
key.args.depthClipEnable = state.rs.depthClipEnable();
|
||||
|
||||
auto entry = m_basePipelines.find(key);
|
||||
if (entry != m_basePipelines.end())
|
||||
return entry->second;
|
||||
|
||||
VkPipeline handle = createBasePipeline(key);
|
||||
m_basePipelines.insert({ key, handle });
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
VkPipeline DxvkGraphicsPipeline::createBasePipeline(
|
||||
const DxvkGraphicsPipelineBaseInstanceKey& key) const {
|
||||
auto vk = m_device->vkd();
|
||||
|
@ -274,26 +274,23 @@ namespace dxvk {
|
||||
const DxvkGraphicsPipelineVertexInputLibrary* viLibrary = nullptr;
|
||||
const DxvkGraphicsPipelineFragmentOutputLibrary* foLibrary = nullptr;
|
||||
DxvkShaderPipelineLibraryCompileArgs args;
|
||||
|
||||
bool eq(const DxvkGraphicsPipelineBaseInstanceKey& other) const {
|
||||
return viLibrary == other.viLibrary
|
||||
&& foLibrary == other.foLibrary
|
||||
&& args == other.args;
|
||||
}
|
||||
|
||||
size_t hash() const {
|
||||
DxvkHashState hash;
|
||||
hash.add(size_t(viLibrary));
|
||||
hash.add(size_t(foLibrary));
|
||||
hash.add(args.hash());
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Base pipeline instance
|
||||
*
|
||||
* Stores the key and handle of a base pipeline.
|
||||
*/
|
||||
struct DxvkGraphicsPipelineBaseInstance {
|
||||
DxvkGraphicsPipelineBaseInstance() { }
|
||||
DxvkGraphicsPipelineBaseInstance(
|
||||
const DxvkGraphicsPipelineBaseInstanceKey& key_,
|
||||
VkPipeline handle_)
|
||||
: key(key_), handle(handle_) { }
|
||||
|
||||
DxvkGraphicsPipelineBaseInstanceKey key;
|
||||
VkPipeline handle = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Graphics pipeline
|
||||
*
|
||||
@ -413,7 +410,10 @@ namespace dxvk {
|
||||
alignas(CACHE_LINE_SIZE)
|
||||
dxvk::mutex m_mutex;
|
||||
sync::List<DxvkGraphicsPipelineInstance> m_pipelines;
|
||||
sync::List<DxvkGraphicsPipelineBaseInstance> m_basePipelines;
|
||||
|
||||
std::unordered_map<
|
||||
DxvkGraphicsPipelineBaseInstanceKey,
|
||||
VkPipeline, DxvkHash, DxvkEq> m_basePipelines;
|
||||
|
||||
DxvkGraphicsPipelineInstance* createInstance(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
@ -422,12 +422,12 @@ namespace dxvk {
|
||||
DxvkGraphicsPipelineInstance* findInstance(
|
||||
const DxvkGraphicsPipelineStateInfo& state);
|
||||
|
||||
DxvkGraphicsPipelineBaseInstance* createBaseInstance(
|
||||
const DxvkGraphicsPipelineBaseInstanceKey& key);
|
||||
|
||||
bool canCreateBasePipeline(
|
||||
const DxvkGraphicsPipelineStateInfo& state) const;
|
||||
|
||||
VkPipeline getBasePipeline(
|
||||
const DxvkGraphicsPipelineStateInfo& state);
|
||||
|
||||
VkPipeline createBasePipeline(
|
||||
const DxvkGraphicsPipelineBaseInstanceKey& key) const;
|
||||
|
||||
|
@ -329,6 +329,10 @@ namespace dxvk {
|
||||
bool operator != (const DxvkShaderPipelineLibraryCompileArgs& other) const {
|
||||
return !this->operator == (other);
|
||||
}
|
||||
|
||||
size_t hash() const {
|
||||
return size_t(depthClipEnable);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user