mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 14:52:11 +01:00
[dxvk] Add way to create partial pipeline layouts
This commit is contained in:
parent
3b10efbc30
commit
30c25ee1f0
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user