[dxvk] Add way to create partial pipeline layouts

This commit is contained in:
Philip Rebohle 2022-07-05 13:17:10 +02:00
parent 3b10efbc30
commit 30c25ee1f0
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 57 additions and 19 deletions

View File

@ -208,8 +208,8 @@ namespace dxvk {
}
DxvkBindingLayout::DxvkBindingLayout()
: m_pushConst { 0, 0, 0 } {
DxvkBindingLayout::DxvkBindingLayout(VkShaderStageFlags stages)
: m_pushConst { 0, 0, 0 }, m_stages(stages) {
}
@ -219,6 +219,21 @@ namespace dxvk {
}
uint32_t DxvkBindingLayout::getSetMask() const {
uint32_t mask = 0;
if (m_stages & (VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT)) {
mask |= (1u << DxvkDescriptorSets::FsViews)
| (1u << DxvkDescriptorSets::FsBuffers);
}
if (m_stages & (VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_VERTEX_BIT))
mask |= (1u << DxvkDescriptorSets::VsAll);
return mask;
}
void DxvkBindingLayout::addBinding(const DxvkBindingInfo& binding) {
uint32_t set = binding.computeSetIndex();
m_bindings[set].addBinding(binding);
@ -244,6 +259,9 @@ namespace dxvk {
bool DxvkBindingLayout::eq(const DxvkBindingLayout& other) const {
if (m_stages != other.m_stages)
return false;
for (uint32_t i = 0; i < m_bindings.size(); i++) {
if (!m_bindings[i].eq(other.m_bindings[i]))
return false;
@ -260,6 +278,7 @@ namespace dxvk {
size_t DxvkBindingLayout::hash() const {
DxvkHashState hash;
hash.add(m_stages);
for (uint32_t i = 0; i < m_bindings.size(); i++)
hash.add(m_bindings[i].hash());
@ -278,26 +297,30 @@ namespace dxvk {
: m_device(device), m_layout(layout) {
auto vk = m_device->vkd();
std::array<VkDescriptorSetLayout, DxvkDescriptorSets::SetCount> setLayouts;
std::array<VkDescriptorSetLayout, DxvkDescriptorSets::SetCount> setLayouts = { };
for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) {
m_bindingObjects[i] = setObjects[i];
setLayouts[i] = setObjects[i]->getSetLayout();
uint32_t bindingCount = m_layout.getBindingCount(i);
// Sets can be null for partial layouts
if (setObjects[i]) {
setLayouts[i] = setObjects[i]->getSetLayout();
for (uint32_t j = 0; j < bindingCount; j++) {
const DxvkBindingInfo& binding = m_layout.getBinding(i, j);
uint32_t bindingCount = m_layout.getBindingCount(i);
DxvkBindingMapping mapping;
mapping.set = i;
mapping.binding = j;
for (uint32_t j = 0; j < bindingCount; j++) {
const DxvkBindingInfo& binding = m_layout.getBinding(i, j);
m_mapping.insert({ binding.resourceBinding, mapping });
DxvkBindingMapping mapping;
mapping.set = i;
mapping.binding = j;
m_mapping.insert({ binding.resourceBinding, mapping });
}
if (bindingCount)
m_setMask |= 1u << i;
}
if (bindingCount)
m_setMask |= 1u << i;
}
VkPushConstantRange pushConst = m_layout.getPushConstantRange();
@ -306,6 +329,9 @@ namespace dxvk {
pipelineLayoutInfo.setLayoutCount = setLayouts.size();
pipelineLayoutInfo.pSetLayouts = setLayouts.data();
if (m_layout.getSetMask() != (1u << DxvkDescriptorSets::SetCount) - 1)
pipelineLayoutInfo.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT;
if (pushConst.stageFlags && pushConst.size) {
pipelineLayoutInfo.pushConstantRangeCount = 1;
pipelineLayoutInfo.pPushConstantRanges = &pushConst;

View File

@ -261,7 +261,7 @@ namespace dxvk {
public:
DxvkBindingLayout();
DxvkBindingLayout(VkShaderStageFlags stages);
~DxvkBindingLayout();
/**
@ -304,6 +304,14 @@ namespace dxvk {
return m_pushConst;
}
/**
* \brief Queries defined descriptor set layouts
*
* Any set layout not included in this must be null.
* \returns Bit mask of defined descriptor sets
*/
uint32_t getSetMask() const;
/**
* \brief Adds a binding to the layout
* \param [in] binding Binding info
@ -345,6 +353,7 @@ namespace dxvk {
std::array<DxvkBindingList, DxvkDescriptorSets::SetCount> m_bindings;
VkPushConstantRange m_pushConst;
VkShaderStageFlags m_stages;
};

View File

@ -52,7 +52,7 @@ namespace dxvk {
if (pair != m_graphicsPipelines.end())
return &pair->second;
DxvkBindingLayout mergedLayout;
DxvkBindingLayout mergedLayout(VK_SHADER_STAGE_ALL_GRAPHICS);
mergedLayout.merge(shaders.vs->getBindings());
if (shaders.tcs != nullptr)
@ -157,9 +157,12 @@ namespace dxvk {
return &pair->second;
std::array<const DxvkBindingSetLayout*, DxvkDescriptorSets::SetCount> setLayouts = { };
uint32_t setMask = layout.getSetMask();
for (uint32_t i = 0; i < setLayouts.size(); i++)
setLayouts[i] = createDescriptorSetLayout(layout.getBindingList(i));
for (uint32_t i = 0; i < setLayouts.size(); i++) {
if (setMask & (1u << i))
setLayouts[i] = createDescriptorSetLayout(layout.getBindingList(i));
}
auto iter = m_pipelineLayouts.emplace(
std::piecewise_construct,

View File

@ -63,7 +63,7 @@ namespace dxvk {
DxvkShader::DxvkShader(
const DxvkShaderCreateInfo& info,
SpirvCodeBuffer&& spirv)
: m_info(info), m_code(spirv) {
: m_info(info), m_code(spirv), m_bindings(info.stage) {
m_info.uniformData = nullptr;
m_info.bindings = nullptr;