mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-29 17:52:18 +01:00
[dxvk] Enable the use of VK_KHR_descriptor_update_template
Reduces the CPU overhead of descriptor set updates, which usually happen once per draw call. Gains seem to be minor in most games, some outliers show significantly better performance (i.e. Tomb Raider).
This commit is contained in:
parent
0f800c6c51
commit
94aa650f3e
@ -134,11 +134,12 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void updateDescriptorSet(
|
||||
uint32_t descriptorCount,
|
||||
const VkWriteDescriptorSet* descriptorWrites) {
|
||||
m_vkd->vkUpdateDescriptorSets(m_vkd->device(),
|
||||
descriptorCount, descriptorWrites, 0, nullptr);
|
||||
void updateDescriptorSetWithTemplate(
|
||||
VkDescriptorSet descriptorSet,
|
||||
VkDescriptorUpdateTemplateKHR descriptorTemplate,
|
||||
const void* data) {
|
||||
m_vkd->vkUpdateDescriptorSetWithTemplateKHR(m_vkd->device(),
|
||||
descriptorSet, descriptorTemplate, data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,7 +26,8 @@ namespace dxvk {
|
||||
|
||||
m_layout = new DxvkPipelineLayout(m_vkd,
|
||||
slotMapping.bindingCount(),
|
||||
slotMapping.bindingInfos());
|
||||
slotMapping.bindingInfos(),
|
||||
VK_PIPELINE_BIND_POINT_COMPUTE);
|
||||
|
||||
m_cs = cs->createShaderModule(m_vkd, slotMapping);
|
||||
}
|
||||
|
@ -7,20 +7,7 @@
|
||||
namespace dxvk {
|
||||
|
||||
DxvkContext::DxvkContext(const Rc<DxvkDevice>& device)
|
||||
: m_device(device) {
|
||||
for (uint32_t i = 0; i < m_descWrites.size(); i++) {
|
||||
m_descWrites[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
m_descWrites[i].pNext = nullptr;
|
||||
m_descWrites[i].dstSet = VK_NULL_HANDLE;
|
||||
m_descWrites[i].dstBinding = i;
|
||||
m_descWrites[i].dstArrayElement = 0;
|
||||
m_descWrites[i].descriptorCount = 1;
|
||||
m_descWrites[i].descriptorType = VkDescriptorType(0);
|
||||
m_descWrites[i].pImageInfo = &m_descInfos[i].image;
|
||||
m_descWrites[i].pBufferInfo = &m_descInfos[i].buffer;
|
||||
m_descWrites[i].pTexelBufferView = &m_descInfos[i].texelBuffer;
|
||||
}
|
||||
}
|
||||
: m_device(device) { }
|
||||
|
||||
|
||||
DxvkContext::~DxvkContext() {
|
||||
@ -1620,13 +1607,10 @@ namespace dxvk {
|
||||
m_cmd->allocateDescriptorSet(
|
||||
layout->descriptorSetLayout());
|
||||
|
||||
for (uint32_t i = 0; i < layout->bindingCount(); i++) {
|
||||
m_descWrites[i].dstSet = dset;
|
||||
m_descWrites[i].descriptorType = layout->binding(i).type;
|
||||
}
|
||||
m_cmd->updateDescriptorSetWithTemplate(
|
||||
dset, layout->descriptorTemplate(),
|
||||
m_descInfos.data());
|
||||
|
||||
m_cmd->updateDescriptorSet(
|
||||
layout->bindingCount(), m_descWrites.data());
|
||||
m_cmd->cmdBindDescriptorSet(bindPoint,
|
||||
layout->pipelineLayout(), dset);
|
||||
}
|
||||
|
@ -578,7 +578,6 @@ namespace dxvk {
|
||||
|
||||
std::array<DxvkShaderResourceSlot, MaxNumResourceSlots> m_rc;
|
||||
std::array<DxvkDescriptorInfo, MaxNumActiveBindings> m_descInfos;
|
||||
std::array<VkWriteDescriptorSet, MaxNumActiveBindings> m_descWrites;
|
||||
|
||||
void renderPassBegin();
|
||||
void renderPassEnd();
|
||||
|
@ -129,11 +129,12 @@ namespace dxvk {
|
||||
* used by DXVK if supported by the implementation.
|
||||
*/
|
||||
struct DxvkDeviceExtensions : public DxvkExtensionList {
|
||||
DxvkExtension amdRasterizationOrder = { this, VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME, DxvkExtensionType::Optional };
|
||||
DxvkExtension khrMaintenance1 = { this, VK_KHR_MAINTENANCE1_EXTENSION_NAME, DxvkExtensionType::Required };
|
||||
DxvkExtension khrMaintenance2 = { this, VK_KHR_MAINTENANCE2_EXTENSION_NAME, DxvkExtensionType::Desired };
|
||||
DxvkExtension khrShaderDrawParameters = { this, VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, DxvkExtensionType::Required };
|
||||
DxvkExtension khrSwapchain = { this, VK_KHR_SWAPCHAIN_EXTENSION_NAME, DxvkExtensionType::Required };
|
||||
DxvkExtension amdRasterizationOrder = { this, VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME, DxvkExtensionType::Optional };
|
||||
DxvkExtension khrDescriptorUpdateTemplate = { this, VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME, DxvkExtensionType::Required };
|
||||
DxvkExtension khrMaintenance1 = { this, VK_KHR_MAINTENANCE1_EXTENSION_NAME, DxvkExtensionType::Required };
|
||||
DxvkExtension khrMaintenance2 = { this, VK_KHR_MAINTENANCE2_EXTENSION_NAME, DxvkExtensionType::Desired };
|
||||
DxvkExtension khrShaderDrawParameters = { this, VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, DxvkExtensionType::Required };
|
||||
DxvkExtension khrSwapchain = { this, VK_KHR_SWAPCHAIN_EXTENSION_NAME, DxvkExtensionType::Required };
|
||||
};
|
||||
|
||||
}
|
@ -52,7 +52,8 @@ namespace dxvk {
|
||||
|
||||
m_layout = new DxvkPipelineLayout(m_vkd,
|
||||
slotMapping.bindingCount(),
|
||||
slotMapping.bindingInfos());
|
||||
slotMapping.bindingInfos(),
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS);
|
||||
|
||||
if (vs != nullptr) m_vs = vs ->createShaderModule(m_vkd, slotMapping);
|
||||
if (tcs != nullptr) m_tcs = tcs->createShaderModule(m_vkd, slotMapping);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "dxvk_descriptor.h"
|
||||
#include "dxvk_pipelayout.h"
|
||||
|
||||
namespace dxvk {
|
||||
@ -44,26 +45,32 @@ namespace dxvk {
|
||||
DxvkPipelineLayout::DxvkPipelineLayout(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
uint32_t bindingCount,
|
||||
const DxvkDescriptorSlot* bindingInfos)
|
||||
: m_vkd(vkd) {
|
||||
|
||||
m_bindingSlots.resize(bindingCount);
|
||||
const DxvkDescriptorSlot* bindingInfos,
|
||||
VkPipelineBindPoint pipelineBindPoint)
|
||||
: m_vkd(vkd), m_bindingSlots(bindingCount) {
|
||||
|
||||
for (uint32_t i = 0; i < bindingCount; i++)
|
||||
m_bindingSlots[i] = bindingInfos[i];
|
||||
|
||||
std::vector<VkDescriptorSetLayoutBinding> bindings;
|
||||
std::vector<VkDescriptorSetLayoutBinding> bindings(bindingCount);
|
||||
std::vector<VkDescriptorUpdateTemplateEntryKHR> tEntries(bindingCount);
|
||||
|
||||
for (uint32_t i = 0; i < bindingCount; i++) {
|
||||
VkDescriptorSetLayoutBinding binding;
|
||||
binding.binding = i;
|
||||
binding.descriptorType = bindingInfos[i].type;
|
||||
binding.descriptorCount = 1;
|
||||
binding.stageFlags = bindingInfos[i].stages;
|
||||
binding.pImmutableSamplers = nullptr;
|
||||
bindings.push_back(binding);
|
||||
bindings[i].binding = i;
|
||||
bindings[i].descriptorType = bindingInfos[i].type;
|
||||
bindings[i].descriptorCount = 1;
|
||||
bindings[i].stageFlags = bindingInfos[i].stages;
|
||||
bindings[i].pImmutableSamplers = nullptr;
|
||||
|
||||
tEntries[i].dstBinding = i;
|
||||
tEntries[i].dstArrayElement = 0;
|
||||
tEntries[i].descriptorCount = 1;
|
||||
tEntries[i].descriptorType = bindingInfos[i].type;
|
||||
tEntries[i].offset = sizeof(DxvkDescriptorInfo) * i;
|
||||
tEntries[i].stride = 0;
|
||||
}
|
||||
|
||||
// Create descriptor set layout
|
||||
VkDescriptorSetLayoutCreateInfo dsetInfo;
|
||||
dsetInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
dsetInfo.pNext = nullptr;
|
||||
@ -75,6 +82,7 @@ namespace dxvk {
|
||||
&dsetInfo, nullptr, &m_descriptorSetLayout) != VK_SUCCESS)
|
||||
throw DxvkError("DxvkPipelineLayout: Failed to create descriptor set layout");
|
||||
|
||||
// Create pipeline layout
|
||||
VkPipelineLayoutCreateInfo pipeInfo;
|
||||
pipeInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
pipeInfo.pNext = nullptr;
|
||||
@ -85,24 +93,42 @@ namespace dxvk {
|
||||
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);
|
||||
&pipeInfo, nullptr, &m_pipelineLayout) != VK_SUCCESS) {
|
||||
m_vkd->vkDestroyDescriptorSetLayout(m_vkd->device(), m_descriptorSetLayout, nullptr);
|
||||
throw DxvkError("DxvkPipelineLayout: Failed to create pipeline layout");
|
||||
}
|
||||
|
||||
// Create descriptor update template
|
||||
VkDescriptorUpdateTemplateCreateInfoKHR templateInfo;
|
||||
templateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR;
|
||||
templateInfo.pNext = nullptr;
|
||||
templateInfo.flags = 0;
|
||||
templateInfo.descriptorUpdateEntryCount = tEntries.size();
|
||||
templateInfo.pDescriptorUpdateEntries = tEntries.data();
|
||||
templateInfo.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR;
|
||||
templateInfo.descriptorSetLayout = m_descriptorSetLayout;
|
||||
templateInfo.pipelineBindPoint = pipelineBindPoint;
|
||||
templateInfo.pipelineLayout = m_pipelineLayout;
|
||||
templateInfo.set = 0;
|
||||
|
||||
if (m_vkd->vkCreateDescriptorUpdateTemplateKHR(m_vkd->device(),
|
||||
&templateInfo, nullptr, &m_descriptorTemplate) != VK_SUCCESS) {
|
||||
m_vkd->vkDestroyDescriptorSetLayout(m_vkd->device(), m_descriptorSetLayout, nullptr);
|
||||
m_vkd->vkDestroyPipelineLayout(m_vkd->device(), m_pipelineLayout, nullptr);
|
||||
throw DxvkError("DxvkPipelineLayout: Failed to create descriptor update template");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DxvkPipelineLayout::~DxvkPipelineLayout() {
|
||||
if (m_pipelineLayout != VK_NULL_HANDLE) {
|
||||
m_vkd->vkDestroyPipelineLayout(
|
||||
m_vkd->device(), m_pipelineLayout, nullptr);
|
||||
}
|
||||
m_vkd->vkDestroyDescriptorUpdateTemplateKHR(
|
||||
m_vkd->device(), m_descriptorTemplate, nullptr);
|
||||
|
||||
if (m_descriptorSetLayout != VK_NULL_HANDLE) {
|
||||
m_vkd->vkDestroyDescriptorSetLayout(
|
||||
m_vkd->device(), m_descriptorSetLayout, nullptr);
|
||||
}
|
||||
m_vkd->vkDestroyPipelineLayout(
|
||||
m_vkd->device(), m_pipelineLayout, nullptr);
|
||||
|
||||
m_vkd->vkDestroyDescriptorSetLayout(
|
||||
m_vkd->device(), m_descriptorSetLayout, nullptr);
|
||||
}
|
||||
|
||||
}
|
@ -111,7 +111,8 @@ namespace dxvk {
|
||||
DxvkPipelineLayout(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
uint32_t bindingCount,
|
||||
const DxvkDescriptorSlot* bindingInfos);
|
||||
const DxvkDescriptorSlot* bindingInfos,
|
||||
VkPipelineBindPoint pipelineBindPoint);
|
||||
|
||||
~DxvkPipelineLayout();
|
||||
|
||||
@ -157,12 +158,21 @@ namespace dxvk {
|
||||
return m_pipelineLayout;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Descriptor update template
|
||||
* \returns Descriptor update template
|
||||
*/
|
||||
VkDescriptorUpdateTemplateKHR descriptorTemplate() const {
|
||||
return m_descriptorTemplate;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Rc<vk::DeviceFn> m_vkd;
|
||||
Rc<vk::DeviceFn> m_vkd;
|
||||
|
||||
VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE;
|
||||
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
|
||||
VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE;
|
||||
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
|
||||
VkDescriptorUpdateTemplateKHR m_descriptorTemplate = VK_NULL_HANDLE;
|
||||
|
||||
std::vector<DxvkDescriptorSlot> m_bindingSlots;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user