[dxvk] Store and create pipeline layout objects in pipeline manager

This should help avoid a lot of duplication.
This commit is contained in:
Philip Rebohle 2022-06-13 16:58:32 +02:00
parent 79ecd4e94a
commit ec5ea71174
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
6 changed files with 109 additions and 11 deletions

View File

@ -12,9 +12,10 @@ namespace dxvk {
DxvkComputePipeline::DxvkComputePipeline(
DxvkPipelineManager* pipeMgr,
DxvkComputePipelineShaders shaders)
DxvkComputePipelineShaders shaders,
DxvkBindingLayoutObjects* layout)
: m_vkd(pipeMgr->m_device->vkd()), m_pipeMgr(pipeMgr),
m_shaders(std::move(shaders)) {
m_shaders(std::move(shaders)), m_bindings(layout) {
m_shaders.cs->defineResourceSlots(m_slotMapping);
m_slotMapping.makeDescriptorsDynamic(

View File

@ -91,7 +91,8 @@ namespace dxvk {
DxvkComputePipeline(
DxvkPipelineManager* pipeMgr,
DxvkComputePipelineShaders shaders);
DxvkComputePipelineShaders shaders,
DxvkBindingLayoutObjects* layout);
~DxvkComputePipeline();
@ -114,6 +115,18 @@ namespace dxvk {
DxvkPipelineLayout* layout() const {
return m_layout.ptr();
}
/**
* \brief Pipeline layout
*
* Stores the pipeline layout and the descriptor set
* layouts, as well as information on the resource
* slots used by the pipeline.
* \returns Pipeline layout
*/
DxvkBindingLayoutObjects* getBindings() const {
return m_bindings;
}
/**
* \brief Retrieves pipeline handle
@ -142,6 +155,7 @@ namespace dxvk {
DxvkComputePipelineShaders m_shaders;
DxvkDescriptorSlotMapping m_slotMapping;
DxvkBindingLayoutObjects* m_bindings;
Rc<DxvkPipelineLayout> m_layout;
alignas(CACHE_LINE_SIZE)

View File

@ -10,9 +10,10 @@ namespace dxvk {
DxvkGraphicsPipeline::DxvkGraphicsPipeline(
DxvkPipelineManager* pipeMgr,
DxvkGraphicsPipelineShaders shaders)
DxvkGraphicsPipelineShaders shaders,
DxvkBindingLayoutObjects* layout)
: m_vkd(pipeMgr->m_device->vkd()), m_pipeMgr(pipeMgr),
m_shaders(std::move(shaders)) {
m_shaders(std::move(shaders)), m_bindings(layout) {
if (m_shaders.vs != nullptr) m_shaders.vs ->defineResourceSlots(m_slotMapping);
if (m_shaders.tcs != nullptr) m_shaders.tcs->defineResourceSlots(m_slotMapping);
if (m_shaders.tes != nullptr) m_shaders.tes->defineResourceSlots(m_slotMapping);

View File

@ -149,7 +149,8 @@ namespace dxvk {
DxvkGraphicsPipeline(
DxvkPipelineManager* pipeMgr,
DxvkGraphicsPipelineShaders shaders);
DxvkGraphicsPipelineShaders shaders,
DxvkBindingLayoutObjects* layout);
~DxvkGraphicsPipeline();
@ -181,6 +182,18 @@ namespace dxvk {
return m_layout.ptr();
}
/**
* \brief Pipeline layout
*
* Stores the pipeline layout and the descriptor set
* layout, as well as information on the resource
* slots used by the pipeline.
* \returns Pipeline layout
*/
DxvkBindingLayoutObjects* getBindings() const {
return m_bindings;
}
/**
* \brief Queries shader for a given stage
*
@ -225,6 +238,7 @@ namespace dxvk {
DxvkGraphicsPipelineShaders m_shaders;
DxvkDescriptorSlotMapping m_slotMapping;
DxvkBindingLayoutObjects* m_bindings;
Rc<DxvkPipelineLayout> m_layout;
uint32_t m_vsIn = 0;

View File

@ -31,11 +31,13 @@ namespace dxvk {
auto pair = m_computePipelines.find(shaders);
if (pair != m_computePipelines.end())
return &pair->second;
auto layout = createPipelineLayout(shaders.cs->getBindings());
auto iter = m_computePipelines.emplace(
std::piecewise_construct,
std::tuple(shaders),
std::tuple(this, shaders));
std::tuple(this, shaders, layout));
return &iter.first->second;
}
@ -50,11 +52,28 @@ namespace dxvk {
auto pair = m_graphicsPipelines.find(shaders);
if (pair != m_graphicsPipelines.end())
return &pair->second;
DxvkBindingLayout mergedLayout;
mergedLayout.merge(shaders.vs->getBindings());
if (shaders.tcs != nullptr)
mergedLayout.merge(shaders.tcs->getBindings());
if (shaders.tes != nullptr)
mergedLayout.merge(shaders.tes->getBindings());
if (shaders.gs != nullptr)
mergedLayout.merge(shaders.gs->getBindings());
if (shaders.fs != nullptr)
mergedLayout.merge(shaders.fs->getBindings());
auto layout = createPipelineLayout(mergedLayout);
auto iter = m_graphicsPipelines.emplace(
std::piecewise_construct,
std::tuple(shaders),
std::tuple(this, shaders));
std::tuple(this, shaders, layout));
return &iter.first->second;
}
@ -84,5 +103,38 @@ namespace dxvk {
if (m_stateCache != nullptr)
m_stateCache->stopWorkerThreads();
}
DxvkBindingSetLayout* DxvkPipelineManager::createDescriptorSetLayout(
const DxvkBindingSetLayoutKey& key) {
auto pair = m_descriptorSetLayouts.find(key);
if (pair != m_descriptorSetLayouts.end())
return &pair->second;
auto iter = m_descriptorSetLayouts.emplace(
std::piecewise_construct,
std::tuple(key),
std::tuple(m_device, key));
return &iter.first->second;
}
DxvkBindingLayoutObjects* DxvkPipelineManager::createPipelineLayout(
const DxvkBindingLayout& layout) {
auto pair = m_pipelineLayouts.find(layout);
if (pair != m_pipelineLayouts.end())
return &pair->second;
std::array<const DxvkBindingSetLayout*, DxvkDescriptorSets::SetCount> setLayouts = { };
for (uint32_t i = 0; i < setLayouts.size(); i++)
setLayouts[i] = createDescriptorSetLayout(layout.getBindingList(i));
auto iter = m_pipelineLayouts.emplace(
std::piecewise_construct,
std::tuple(layout),
std::tuple(m_device, layout, setLayouts.data()));
return &iter.first->second;
}
}

View File

@ -106,6 +106,16 @@ namespace dxvk {
dxvk::mutex m_mutex;
std::unordered_map<
DxvkBindingSetLayoutKey,
DxvkBindingSetLayout,
DxvkHash, DxvkEq> m_descriptorSetLayouts;
std::unordered_map<
DxvkBindingLayout,
DxvkBindingLayoutObjects,
DxvkHash, DxvkEq> m_pipelineLayouts;
std::unordered_map<
DxvkComputePipelineShaders,
DxvkComputePipeline,
@ -115,7 +125,13 @@ namespace dxvk {
DxvkGraphicsPipelineShaders,
DxvkGraphicsPipeline,
DxvkHash, DxvkEq> m_graphicsPipelines;
DxvkBindingSetLayout* createDescriptorSetLayout(
const DxvkBindingSetLayoutKey& key);
DxvkBindingLayoutObjects* createPipelineLayout(
const DxvkBindingLayout& layout);
};
}