1
0
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:
Philip Rebohle 2018-03-17 23:50:03 +01:00
parent 0f800c6c51
commit 94aa650f3e
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
8 changed files with 83 additions and 60 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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();

View File

@ -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 };
};
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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;