diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index 35310474e..a5555ff76 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -30,6 +30,16 @@ namespace dxvk { m_descriptorSlots.push_back(slotInfo); } } + + + void DxvkDescriptorSlotMapping::definePushConstRange( + VkShaderStageFlagBits stage, + uint32_t offset, + uint32_t size) { + m_pushConstRange.stageFlags |= stage; + m_pushConstRange.size = std::max( + m_pushConstRange.size, offset + size); + } uint32_t DxvkDescriptorSlotMapping::getBindingId(uint32_t slot) const { @@ -81,7 +91,9 @@ namespace dxvk { const Rc& vkd, const DxvkDescriptorSlotMapping& slotMapping, VkPipelineBindPoint pipelineBindPoint) - : m_vkd(vkd), m_bindingSlots(slotMapping.bindingCount()) { + : m_vkd (vkd), + m_pushConstRange(slotMapping.pushConstRange()), + m_bindingSlots (slotMapping.bindingCount()) { auto bindingCount = slotMapping.bindingCount(); auto bindingInfos = slotMapping.bindingInfos(); @@ -137,6 +149,11 @@ namespace dxvk { pipeInfo.pSetLayouts = &m_descriptorSetLayout; pipeInfo.pushConstantRangeCount = 0; pipeInfo.pPushConstantRanges = nullptr; + + if (m_pushConstRange.size) { + pipeInfo.pushConstantRangeCount = 1; + pipeInfo.pPushConstantRanges = &m_pushConstRange; + } if (m_vkd->vkCreatePipelineLayout(m_vkd->device(), &pipeInfo, nullptr, &m_pipelineLayout) != VK_SUCCESS) { diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index 17001ee01..38c1b75f7 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -65,6 +65,14 @@ namespace dxvk { const DxvkDescriptorSlot* bindingInfos() const { return m_descriptorSlots.data(); } + + /** + * \brief Push constant range + * \returns Push constant range + */ + VkPushConstantRange pushConstRange() const { + return m_pushConstRange; + } /** * \brief Defines a new slot @@ -85,6 +93,18 @@ namespace dxvk { VkImageViewType view, VkShaderStageFlagBits stage, VkAccessFlags access); + + /** + * \brief Defines new push constant range + * + * \param [in] stage Shader stage + * \param [in] offset Range offset + * \param [in] size Range size + */ + void definePushConstRange( + VkShaderStageFlagBits stage, + uint32_t offset, + uint32_t size); /** * \brief Gets binding ID for a slot @@ -112,6 +132,7 @@ namespace dxvk { private: std::vector m_descriptorSlots; + VkPushConstantRange m_pushConstRange = { }; uint32_t countDescriptors( VkDescriptorType type) const; @@ -166,6 +187,14 @@ namespace dxvk { return m_bindingSlots.data(); } + /** + * \brief Push constant range + * \returns Push constant range + */ + const VkPushConstantRange& pushConstRange() const { + return m_pushConstRange; + } + /** * \brief Descriptor set layout handle * \returns Descriptor set layout handle @@ -244,6 +273,7 @@ namespace dxvk { Rc m_vkd; + VkPushConstantRange m_pushConstRange = { }; VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE; VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; VkDescriptorUpdateTemplateKHR m_descriptorTemplate = VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 5e513b359..d24273e25 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -151,6 +151,12 @@ namespace dxvk { DxvkDescriptorSlotMapping& mapping) const { for (const auto& slot : m_slots) mapping.defineSlot(slot.slot, slot.type, slot.view, m_stage, slot.access); + + if (m_interface.pushConstSize) { + mapping.definePushConstRange(m_stage, + m_interface.pushConstOffset, + m_interface.pushConstSize); + } } diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index fb38e2ba4..492eb97fc 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -43,8 +43,10 @@ namespace dxvk { * purely for validation purposes. */ struct DxvkInterfaceSlots { - uint32_t inputSlots = 0; - uint32_t outputSlots = 0; + uint32_t inputSlots = 0; + uint32_t outputSlots = 0; + uint32_t pushConstOffset = 0; + uint32_t pushConstSize = 0; };