2017-12-03 20:23:26 +01:00
|
|
|
#include <cstring>
|
|
|
|
|
2017-12-07 09:38:31 +01:00
|
|
|
#include "dxvk_pipelayout.h"
|
2017-12-03 00:40:58 +01:00
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
2017-12-07 09:38:31 +01:00
|
|
|
DxvkDescriptorSlotMapping:: DxvkDescriptorSlotMapping() { }
|
|
|
|
DxvkDescriptorSlotMapping::~DxvkDescriptorSlotMapping() { }
|
|
|
|
|
|
|
|
|
|
|
|
void DxvkDescriptorSlotMapping::defineSlot(
|
|
|
|
uint32_t slot,
|
|
|
|
VkDescriptorType type,
|
2018-01-09 20:35:29 +01:00
|
|
|
VkImageViewType view,
|
2017-12-07 09:38:31 +01:00
|
|
|
VkShaderStageFlagBits stage) {
|
|
|
|
uint32_t bindingId = this->getBindingId(slot);
|
|
|
|
|
|
|
|
if (bindingId != InvalidBinding) {
|
2017-12-20 12:13:08 +01:00
|
|
|
m_descriptorSlots[bindingId].stages |= stage;
|
2017-12-07 09:38:31 +01:00
|
|
|
} else {
|
|
|
|
DxvkDescriptorSlot slotInfo;
|
|
|
|
slotInfo.slot = slot;
|
|
|
|
slotInfo.type = type;
|
2018-01-09 20:35:29 +01:00
|
|
|
slotInfo.view = view;
|
2017-12-07 09:38:31 +01:00
|
|
|
slotInfo.stages = stage;
|
|
|
|
m_descriptorSlots.push_back(slotInfo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-08 22:30:41 +01:00
|
|
|
uint32_t DxvkDescriptorSlotMapping::getBindingId(uint32_t slot) const {
|
2017-12-07 09:38:31 +01:00
|
|
|
// This won't win a performance competition, but the number
|
|
|
|
// of bindings used by a shader is usually much smaller than
|
|
|
|
// the number of resource slots available to the system.
|
|
|
|
for (uint32_t i = 0; i < m_descriptorSlots.size(); i++) {
|
2017-12-20 12:13:08 +01:00
|
|
|
if (m_descriptorSlots[i].slot == slot)
|
2017-12-07 09:38:31 +01:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return InvalidBinding;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-01-23 17:40:36 +01:00
|
|
|
DxvkPipelineLayout::DxvkPipelineLayout(
|
2017-12-03 20:23:26 +01:00
|
|
|
const Rc<vk::DeviceFn>& vkd,
|
|
|
|
uint32_t bindingCount,
|
|
|
|
const DxvkDescriptorSlot* bindingInfos)
|
2017-12-03 00:40:58 +01:00
|
|
|
: m_vkd(vkd) {
|
|
|
|
|
2017-12-03 20:23:26 +01:00
|
|
|
m_bindingSlots.resize(bindingCount);
|
2018-01-10 13:44:04 +01:00
|
|
|
|
|
|
|
for (uint32_t i = 0; i < bindingCount; i++)
|
|
|
|
m_bindingSlots[i] = bindingInfos[i];
|
2017-12-03 20:23:26 +01:00
|
|
|
|
|
|
|
std::vector<VkDescriptorSetLayoutBinding> bindings;
|
|
|
|
|
2017-12-03 00:40:58 +01:00
|
|
|
for (uint32_t i = 0; i < bindingCount; i++) {
|
|
|
|
VkDescriptorSetLayoutBinding binding;
|
|
|
|
binding.binding = i;
|
|
|
|
binding.descriptorType = bindingInfos[i].type;
|
2017-12-03 20:23:26 +01:00
|
|
|
binding.descriptorCount = 1;
|
2017-12-03 00:40:58 +01:00
|
|
|
binding.stageFlags = bindingInfos[i].stages;
|
|
|
|
binding.pImmutableSamplers = nullptr;
|
2017-12-03 20:23:26 +01:00
|
|
|
bindings.push_back(binding);
|
2017-12-03 00:40:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
VkDescriptorSetLayoutCreateInfo dsetInfo;
|
|
|
|
dsetInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
|
|
|
dsetInfo.pNext = nullptr;
|
|
|
|
dsetInfo.flags = 0;
|
2017-12-03 20:23:26 +01:00
|
|
|
dsetInfo.bindingCount = bindings.size();
|
|
|
|
dsetInfo.pBindings = bindings.data();
|
2017-12-03 00:40:58 +01:00
|
|
|
|
|
|
|
if (m_vkd->vkCreateDescriptorSetLayout(m_vkd->device(),
|
|
|
|
&dsetInfo, nullptr, &m_descriptorSetLayout) != VK_SUCCESS)
|
2018-01-23 17:40:36 +01:00
|
|
|
throw DxvkError("DxvkPipelineLayout: Failed to create descriptor set layout");
|
2017-12-03 00:40:58 +01:00
|
|
|
|
|
|
|
VkPipelineLayoutCreateInfo pipeInfo;
|
|
|
|
pipeInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
|
|
|
pipeInfo.pNext = nullptr;
|
|
|
|
pipeInfo.flags = 0;
|
|
|
|
pipeInfo.setLayoutCount = 1;
|
|
|
|
pipeInfo.pSetLayouts = &m_descriptorSetLayout;
|
|
|
|
pipeInfo.pushConstantRangeCount = 0;
|
|
|
|
pipeInfo.pPushConstantRanges = nullptr;
|
|
|
|
|
|
|
|
if (m_vkd->vkCreatePipelineLayout(m_vkd->device(),
|
|
|
|
&pipeInfo, nullptr, &m_pipelineLayout) != VK_SUCCESS) {
|
|
|
|
m_vkd->vkDestroyDescriptorSetLayout(
|
|
|
|
m_vkd->device(), m_descriptorSetLayout, nullptr);
|
2018-01-23 17:40:36 +01:00
|
|
|
throw DxvkError("DxvkPipelineLayout: Failed to create pipeline layout");
|
2017-12-03 00:40:58 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-01-23 17:40:36 +01:00
|
|
|
DxvkPipelineLayout::~DxvkPipelineLayout() {
|
2017-12-03 00:40:58 +01:00
|
|
|
if (m_pipelineLayout != VK_NULL_HANDLE) {
|
|
|
|
m_vkd->vkDestroyPipelineLayout(
|
|
|
|
m_vkd->device(), m_pipelineLayout, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_descriptorSetLayout != VK_NULL_HANDLE) {
|
|
|
|
m_vkd->vkDestroyDescriptorSetLayout(
|
|
|
|
m_vkd->device(), m_descriptorSetLayout, nullptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|