mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-14 09:23:53 +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());
|
this->destroyPipeline(instance.fastHandle.load());
|
||||||
|
|
||||||
for (const auto& instance : m_basePipelines)
|
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);
|
VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fastHandle) {
|
// If that didn't succeed, link a pipeline using the
|
||||||
// If that didn't succeed, link a pipeline using the
|
// pre-compiled fragment and vertex shader libraries.
|
||||||
// pre-compiled fragment and vertex shader libraries.
|
if (!fastHandle)
|
||||||
DxvkGraphicsPipelineVertexInputState viState(m_device, state, m_shaders.vs.ptr());
|
baseHandle = this->getBasePipeline(state);
|
||||||
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;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Create optimized variant right away, no choice
|
// Create optimized variant right away, no choice
|
||||||
fastHandle = this->createOptimizedPipeline(state, 0);
|
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(
|
bool DxvkGraphicsPipeline::canCreateBasePipeline(
|
||||||
const DxvkGraphicsPipelineStateInfo& state) const {
|
const DxvkGraphicsPipelineStateInfo& state) const {
|
||||||
if (!m_vsLibrary || !m_fsLibrary)
|
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(
|
VkPipeline DxvkGraphicsPipeline::createBasePipeline(
|
||||||
const DxvkGraphicsPipelineBaseInstanceKey& key) const {
|
const DxvkGraphicsPipelineBaseInstanceKey& key) const {
|
||||||
auto vk = m_device->vkd();
|
auto vk = m_device->vkd();
|
||||||
|
@ -274,26 +274,23 @@ namespace dxvk {
|
|||||||
const DxvkGraphicsPipelineVertexInputLibrary* viLibrary = nullptr;
|
const DxvkGraphicsPipelineVertexInputLibrary* viLibrary = nullptr;
|
||||||
const DxvkGraphicsPipelineFragmentOutputLibrary* foLibrary = nullptr;
|
const DxvkGraphicsPipelineFragmentOutputLibrary* foLibrary = nullptr;
|
||||||
DxvkShaderPipelineLibraryCompileArgs args;
|
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
|
* \brief Graphics pipeline
|
||||||
*
|
*
|
||||||
@ -413,7 +410,10 @@ namespace dxvk {
|
|||||||
alignas(CACHE_LINE_SIZE)
|
alignas(CACHE_LINE_SIZE)
|
||||||
dxvk::mutex m_mutex;
|
dxvk::mutex m_mutex;
|
||||||
sync::List<DxvkGraphicsPipelineInstance> m_pipelines;
|
sync::List<DxvkGraphicsPipelineInstance> m_pipelines;
|
||||||
sync::List<DxvkGraphicsPipelineBaseInstance> m_basePipelines;
|
|
||||||
|
std::unordered_map<
|
||||||
|
DxvkGraphicsPipelineBaseInstanceKey,
|
||||||
|
VkPipeline, DxvkHash, DxvkEq> m_basePipelines;
|
||||||
|
|
||||||
DxvkGraphicsPipelineInstance* createInstance(
|
DxvkGraphicsPipelineInstance* createInstance(
|
||||||
const DxvkGraphicsPipelineStateInfo& state,
|
const DxvkGraphicsPipelineStateInfo& state,
|
||||||
@ -422,12 +422,12 @@ namespace dxvk {
|
|||||||
DxvkGraphicsPipelineInstance* findInstance(
|
DxvkGraphicsPipelineInstance* findInstance(
|
||||||
const DxvkGraphicsPipelineStateInfo& state);
|
const DxvkGraphicsPipelineStateInfo& state);
|
||||||
|
|
||||||
DxvkGraphicsPipelineBaseInstance* createBaseInstance(
|
|
||||||
const DxvkGraphicsPipelineBaseInstanceKey& key);
|
|
||||||
|
|
||||||
bool canCreateBasePipeline(
|
bool canCreateBasePipeline(
|
||||||
const DxvkGraphicsPipelineStateInfo& state) const;
|
const DxvkGraphicsPipelineStateInfo& state) const;
|
||||||
|
|
||||||
|
VkPipeline getBasePipeline(
|
||||||
|
const DxvkGraphicsPipelineStateInfo& state);
|
||||||
|
|
||||||
VkPipeline createBasePipeline(
|
VkPipeline createBasePipeline(
|
||||||
const DxvkGraphicsPipelineBaseInstanceKey& key) const;
|
const DxvkGraphicsPipelineBaseInstanceKey& key) const;
|
||||||
|
|
||||||
|
@ -329,6 +329,10 @@ namespace dxvk {
|
|||||||
bool operator != (const DxvkShaderPipelineLibraryCompileArgs& other) const {
|
bool operator != (const DxvkShaderPipelineLibraryCompileArgs& other) const {
|
||||||
return !this->operator == (other);
|
return !this->operator == (other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t hash() const {
|
||||||
|
return size_t(depthClipEnable);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user