mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-14 00:48:44 +01:00
[dxvk] Only use descriptor update templates in 32-bit builds
This commit is contained in:
parent
15cf130369
commit
f34d1c886a
@ -26,6 +26,19 @@ namespace dxvk {
|
|||||||
// Init framebuffer info with default render pass in case
|
// Init framebuffer info with default render pass in case
|
||||||
// the app does not explicitly bind any render targets
|
// the app does not explicitly bind any render targets
|
||||||
m_state.om.framebufferInfo = makeFramebufferInfo(m_state.om.renderTargets);
|
m_state.om.framebufferInfo = makeFramebufferInfo(m_state.om.renderTargets);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < MaxNumActiveBindings; i++) {
|
||||||
|
m_descriptorWrites[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
m_descriptorWrites[i].pNext = nullptr;
|
||||||
|
m_descriptorWrites[i].dstSet = VK_NULL_HANDLE;
|
||||||
|
m_descriptorWrites[i].dstBinding = 0;
|
||||||
|
m_descriptorWrites[i].dstArrayElement = 0;
|
||||||
|
m_descriptorWrites[i].descriptorCount = 1;
|
||||||
|
m_descriptorWrites[i].descriptorType = VK_DESCRIPTOR_TYPE_MAX_ENUM;
|
||||||
|
m_descriptorWrites[i].pImageInfo = &m_descriptors[i].image;
|
||||||
|
m_descriptorWrites[i].pBufferInfo = &m_descriptors[i].buffer;
|
||||||
|
m_descriptorWrites[i].pTexelBufferView = &m_descriptors[i].texelBuffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4150,10 +4163,13 @@ namespace dxvk {
|
|||||||
|
|
||||||
template<VkPipelineBindPoint BindPoint>
|
template<VkPipelineBindPoint BindPoint>
|
||||||
void DxvkContext::updateResourceBindings(const DxvkBindingLayoutObjects* layout) {
|
void DxvkContext::updateResourceBindings(const DxvkBindingLayoutObjects* layout) {
|
||||||
std::array<DxvkDescriptorInfo, MaxNumActiveBindings> descriptors;
|
|
||||||
|
|
||||||
const auto& bindings = layout->layout();
|
const auto& bindings = layout->layout();
|
||||||
|
|
||||||
|
// On 32-bit wine, vkUpdateDescriptorSets has significant overhead due
|
||||||
|
// to struct conversion, so we should use descriptor update templates.
|
||||||
|
// For 64-bit applications, using templates is slower on some drivers.
|
||||||
|
constexpr bool useDescriptorTemplates = env::is32BitHostPlatform();
|
||||||
|
|
||||||
// This relies on the bind mask being cleared when the pipeline layout changes.
|
// This relies on the bind mask being cleared when the pipeline layout changes.
|
||||||
DxvkBindingMask& refBindMask = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS
|
DxvkBindingMask& refBindMask = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS
|
||||||
? m_state.gp.state.bsBindingMask
|
? m_state.gp.state.bsBindingMask
|
||||||
@ -4169,6 +4185,7 @@ namespace dxvk {
|
|||||||
dirtySetMask &= layoutSetMask;
|
dirtySetMask &= layoutSetMask;
|
||||||
|
|
||||||
uint32_t firstUpdated = bit::tzcnt(dirtySetMask);
|
uint32_t firstUpdated = bit::tzcnt(dirtySetMask);
|
||||||
|
uint32_t k = 0;
|
||||||
|
|
||||||
while (dirtySetMask) {
|
while (dirtySetMask) {
|
||||||
uint32_t setIndex = bit::tzcnt(dirtySetMask);
|
uint32_t setIndex = bit::tzcnt(dirtySetMask);
|
||||||
@ -4180,22 +4197,31 @@ namespace dxvk {
|
|||||||
|
|
||||||
newBindMask.setRange(bindingIndex, bindingCount);
|
newBindMask.setRange(bindingIndex, bindingCount);
|
||||||
|
|
||||||
|
VkDescriptorSet& set = m_descriptorState.getSet<BindPoint>(setIndex);
|
||||||
|
set = allocateDescriptorSet(layout->getSetLayout(setIndex));
|
||||||
|
|
||||||
for (uint32_t j = 0; j < bindingCount; j++) {
|
for (uint32_t j = 0; j < bindingCount; j++) {
|
||||||
const auto& binding = bindings.getBinding(setIndex, j);
|
const auto& binding = bindings.getBinding(setIndex, j);
|
||||||
|
|
||||||
|
if (!useDescriptorTemplates) {
|
||||||
|
m_descriptorWrites[k].dstSet = set;
|
||||||
|
m_descriptorWrites[k].dstBinding = j;
|
||||||
|
m_descriptorWrites[k].descriptorType = binding.descriptorType;
|
||||||
|
}
|
||||||
|
|
||||||
switch (binding.descriptorType) {
|
switch (binding.descriptorType) {
|
||||||
case VK_DESCRIPTOR_TYPE_SAMPLER: {
|
case VK_DESCRIPTOR_TYPE_SAMPLER: {
|
||||||
const auto& res = m_rc[binding.resourceBinding];
|
const auto& res = m_rc[binding.resourceBinding];
|
||||||
|
|
||||||
if (res.sampler != nullptr) {
|
if (res.sampler != nullptr) {
|
||||||
descriptors[j].image.sampler = res.sampler->handle();
|
m_descriptors[k].image.sampler = res.sampler->handle();
|
||||||
descriptors[j].image.imageView = VK_NULL_HANDLE;
|
m_descriptors[k].image.imageView = VK_NULL_HANDLE;
|
||||||
descriptors[j].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
m_descriptors[k].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
|
||||||
if (m_rcTracked.set(binding.resourceBinding))
|
if (m_rcTracked.set(binding.resourceBinding))
|
||||||
m_cmd->trackResource<DxvkAccess::None>(res.sampler);
|
m_cmd->trackResource<DxvkAccess::None>(res.sampler);
|
||||||
} else {
|
} else {
|
||||||
descriptors[j].image = m_common->dummyResources().samplerDescriptor();
|
m_descriptors[k].image = m_common->dummyResources().samplerDescriptor();
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -4203,16 +4229,16 @@ namespace dxvk {
|
|||||||
const auto& res = m_rc[binding.resourceBinding];
|
const auto& res = m_rc[binding.resourceBinding];
|
||||||
|
|
||||||
if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) {
|
if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) {
|
||||||
descriptors[j].image.sampler = VK_NULL_HANDLE;
|
m_descriptors[k].image.sampler = VK_NULL_HANDLE;
|
||||||
descriptors[j].image.imageView = res.imageView->handle(binding.viewType);
|
m_descriptors[k].image.imageView = res.imageView->handle(binding.viewType);
|
||||||
descriptors[j].image.imageLayout = res.imageView->imageInfo().layout;
|
m_descriptors[k].image.imageLayout = res.imageView->imageInfo().layout;
|
||||||
|
|
||||||
if (m_rcTracked.set(binding.resourceBinding)) {
|
if (m_rcTracked.set(binding.resourceBinding)) {
|
||||||
m_cmd->trackResource<DxvkAccess::None>(res.imageView);
|
m_cmd->trackResource<DxvkAccess::None>(res.imageView);
|
||||||
m_cmd->trackResource<DxvkAccess::Read>(res.imageView->image());
|
m_cmd->trackResource<DxvkAccess::Read>(res.imageView->image());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
descriptors[j].image = m_common->dummyResources().imageViewDescriptor(binding.viewType, true);
|
m_descriptors[k].image = m_common->dummyResources().imageViewDescriptor(binding.viewType, true);
|
||||||
newBindMask.clr(bindingIndex + j);
|
newBindMask.clr(bindingIndex + j);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -4221,16 +4247,16 @@ namespace dxvk {
|
|||||||
const auto& res = m_rc[binding.resourceBinding];
|
const auto& res = m_rc[binding.resourceBinding];
|
||||||
|
|
||||||
if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) {
|
if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) {
|
||||||
descriptors[j].image.sampler = VK_NULL_HANDLE;
|
m_descriptors[k].image.sampler = VK_NULL_HANDLE;
|
||||||
descriptors[j].image.imageView = res.imageView->handle(binding.viewType);
|
m_descriptors[k].image.imageView = res.imageView->handle(binding.viewType);
|
||||||
descriptors[j].image.imageLayout = res.imageView->imageInfo().layout;
|
m_descriptors[k].image.imageLayout = res.imageView->imageInfo().layout;
|
||||||
|
|
||||||
if (m_rcTracked.set(binding.resourceBinding)) {
|
if (m_rcTracked.set(binding.resourceBinding)) {
|
||||||
m_cmd->trackResource<DxvkAccess::None>(res.imageView);
|
m_cmd->trackResource<DxvkAccess::None>(res.imageView);
|
||||||
m_cmd->trackResource<DxvkAccess::Write>(res.imageView->image());
|
m_cmd->trackResource<DxvkAccess::Write>(res.imageView->image());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
descriptors[j].image = m_common->dummyResources().imageViewDescriptor(binding.viewType, false);
|
m_descriptors[k].image = m_common->dummyResources().imageViewDescriptor(binding.viewType, false);
|
||||||
newBindMask.clr(bindingIndex + j);
|
newBindMask.clr(bindingIndex + j);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -4240,9 +4266,9 @@ namespace dxvk {
|
|||||||
|
|
||||||
if (res.sampler != nullptr && res.imageView != nullptr
|
if (res.sampler != nullptr && res.imageView != nullptr
|
||||||
&& res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) {
|
&& res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) {
|
||||||
descriptors[j].image.sampler = res.sampler->handle();
|
m_descriptors[k].image.sampler = res.sampler->handle();
|
||||||
descriptors[j].image.imageView = res.imageView->handle(binding.viewType);
|
m_descriptors[k].image.imageView = res.imageView->handle(binding.viewType);
|
||||||
descriptors[j].image.imageLayout = res.imageView->imageInfo().layout;
|
m_descriptors[k].image.imageLayout = res.imageView->imageInfo().layout;
|
||||||
|
|
||||||
if (m_rcTracked.set(binding.resourceBinding)) {
|
if (m_rcTracked.set(binding.resourceBinding)) {
|
||||||
m_cmd->trackResource<DxvkAccess::None>(res.sampler);
|
m_cmd->trackResource<DxvkAccess::None>(res.sampler);
|
||||||
@ -4250,7 +4276,7 @@ namespace dxvk {
|
|||||||
m_cmd->trackResource<DxvkAccess::Read>(res.imageView->image());
|
m_cmd->trackResource<DxvkAccess::Read>(res.imageView->image());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
descriptors[j].image = m_common->dummyResources().imageSamplerDescriptor(binding.viewType);
|
m_descriptors[k].image = m_common->dummyResources().imageSamplerDescriptor(binding.viewType);
|
||||||
newBindMask.clr(bindingIndex + j);
|
newBindMask.clr(bindingIndex + j);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -4260,14 +4286,14 @@ namespace dxvk {
|
|||||||
|
|
||||||
if (res.bufferView != nullptr) {
|
if (res.bufferView != nullptr) {
|
||||||
res.bufferView->updateView();
|
res.bufferView->updateView();
|
||||||
descriptors[j].texelBuffer = res.bufferView->handle();
|
m_descriptors[k].texelBuffer = res.bufferView->handle();
|
||||||
|
|
||||||
if (m_rcTracked.set(binding.resourceBinding)) {
|
if (m_rcTracked.set(binding.resourceBinding)) {
|
||||||
m_cmd->trackResource<DxvkAccess::None>(res.bufferView);
|
m_cmd->trackResource<DxvkAccess::None>(res.bufferView);
|
||||||
m_cmd->trackResource<DxvkAccess::Read>(res.bufferView->buffer());
|
m_cmd->trackResource<DxvkAccess::Read>(res.bufferView->buffer());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
descriptors[j].texelBuffer = m_common->dummyResources().bufferViewDescriptor();
|
m_descriptors[k].texelBuffer = m_common->dummyResources().bufferViewDescriptor();
|
||||||
newBindMask.clr(bindingIndex + j);
|
newBindMask.clr(bindingIndex + j);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -4277,14 +4303,14 @@ namespace dxvk {
|
|||||||
|
|
||||||
if (res.bufferView != nullptr) {
|
if (res.bufferView != nullptr) {
|
||||||
res.bufferView->updateView();
|
res.bufferView->updateView();
|
||||||
descriptors[j].texelBuffer = res.bufferView->handle();
|
m_descriptors[k].texelBuffer = res.bufferView->handle();
|
||||||
|
|
||||||
if (m_rcTracked.set(binding.resourceBinding)) {
|
if (m_rcTracked.set(binding.resourceBinding)) {
|
||||||
m_cmd->trackResource<DxvkAccess::None>(res.bufferView);
|
m_cmd->trackResource<DxvkAccess::None>(res.bufferView);
|
||||||
m_cmd->trackResource<DxvkAccess::Write>(res.bufferView->buffer());
|
m_cmd->trackResource<DxvkAccess::Write>(res.bufferView->buffer());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
descriptors[j].texelBuffer = m_common->dummyResources().bufferViewDescriptor();
|
m_descriptors[k].texelBuffer = m_common->dummyResources().bufferViewDescriptor();
|
||||||
newBindMask.clr(bindingIndex + j);
|
newBindMask.clr(bindingIndex + j);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -4293,12 +4319,12 @@ namespace dxvk {
|
|||||||
const auto& res = m_rc[binding.resourceBinding];
|
const auto& res = m_rc[binding.resourceBinding];
|
||||||
|
|
||||||
if (res.bufferSlice.defined()) {
|
if (res.bufferSlice.defined()) {
|
||||||
descriptors[j] = res.bufferSlice.getDescriptor();
|
m_descriptors[k] = res.bufferSlice.getDescriptor();
|
||||||
|
|
||||||
if (m_rcTracked.set(binding.resourceBinding))
|
if (m_rcTracked.set(binding.resourceBinding))
|
||||||
m_cmd->trackResource<DxvkAccess::Read>(res.bufferSlice.buffer());
|
m_cmd->trackResource<DxvkAccess::Read>(res.bufferSlice.buffer());
|
||||||
} else {
|
} else {
|
||||||
descriptors[j].buffer = m_common->dummyResources().bufferDescriptor();
|
m_descriptors[k].buffer = m_common->dummyResources().bufferDescriptor();
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -4306,12 +4332,12 @@ namespace dxvk {
|
|||||||
const auto& res = m_rc[binding.resourceBinding];
|
const auto& res = m_rc[binding.resourceBinding];
|
||||||
|
|
||||||
if (res.bufferSlice.defined()) {
|
if (res.bufferSlice.defined()) {
|
||||||
descriptors[j] = res.bufferSlice.getDescriptor();
|
m_descriptors[k] = res.bufferSlice.getDescriptor();
|
||||||
|
|
||||||
if (m_rcTracked.set(binding.resourceBinding))
|
if (m_rcTracked.set(binding.resourceBinding))
|
||||||
m_cmd->trackResource<DxvkAccess::Write>(res.bufferSlice.buffer());
|
m_cmd->trackResource<DxvkAccess::Write>(res.bufferSlice.buffer());
|
||||||
} else {
|
} else {
|
||||||
descriptors[j].buffer = m_common->dummyResources().bufferDescriptor();
|
m_descriptors[k].buffer = m_common->dummyResources().bufferDescriptor();
|
||||||
newBindMask.clr(bindingIndex + j);
|
newBindMask.clr(bindingIndex + j);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -4319,18 +4345,22 @@ namespace dxvk {
|
|||||||
default:
|
default:
|
||||||
Logger::err(str::format("DxvkContext: Unhandled descriptor type: ", binding.descriptorType));
|
Logger::err(str::format("DxvkContext: Unhandled descriptor type: ", binding.descriptorType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
k += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and populate descriptor set with the given descriptors
|
if (useDescriptorTemplates) {
|
||||||
VkDescriptorSet& set = m_descriptorState.getSet<BindPoint>(setIndex);
|
m_cmd->updateDescriptorSetWithTemplate(set,
|
||||||
set = allocateDescriptorSet(layout->getSetLayout(setIndex));
|
layout->getSetUpdateTemplate(setIndex),
|
||||||
|
&m_descriptors[k - bindingCount]);
|
||||||
m_cmd->updateDescriptorSetWithTemplate(set,
|
}
|
||||||
layout->getSetUpdateTemplate(setIndex), descriptors.data());
|
|
||||||
|
|
||||||
dirtySetMask &= dirtySetMask - 1;
|
dirtySetMask &= dirtySetMask - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!useDescriptorTemplates && k)
|
||||||
|
m_cmd->updateDescriptorSets(k, m_descriptorWrites.data());
|
||||||
|
|
||||||
// Bind all descriptor sets that need updating
|
// Bind all descriptor sets that need updating
|
||||||
uint32_t bindSetMask = layoutSetMask & ~((1u << firstUpdated) - 1);
|
uint32_t bindSetMask = layoutSetMask & ~((1u << firstUpdated) - 1);
|
||||||
|
|
||||||
|
@ -1070,6 +1070,9 @@ namespace dxvk {
|
|||||||
|
|
||||||
std::vector<DxvkDeferredClear> m_deferredClears;
|
std::vector<DxvkDeferredClear> m_deferredClears;
|
||||||
|
|
||||||
|
std::array<VkWriteDescriptorSet, MaxNumActiveBindings> m_descriptorWrites;
|
||||||
|
std::array<DxvkDescriptorInfo, MaxNumActiveBindings> m_descriptors;
|
||||||
|
|
||||||
std::array<DxvkShaderResourceSlot, MaxNumResourceSlots> m_rc;
|
std::array<DxvkShaderResourceSlot, MaxNumResourceSlots> m_rc;
|
||||||
std::array<DxvkGraphicsPipeline*, 4096> m_gpLookupCache = { };
|
std::array<DxvkGraphicsPipeline*, 4096> m_gpLookupCache = { };
|
||||||
std::array<DxvkComputePipeline*, 256> m_cpLookupCache = { };
|
std::array<DxvkComputePipeline*, 256> m_cpLookupCache = { };
|
||||||
|
@ -235,7 +235,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Queries descriptor template
|
* \brief Queries descriptor template
|
||||||
* \returns Descriptor set template
|
* \returns Descriptor update template
|
||||||
*/
|
*/
|
||||||
VkDescriptorUpdateTemplate getSetUpdateTemplate() const {
|
VkDescriptorUpdateTemplate getSetUpdateTemplate() const {
|
||||||
return m_template;
|
return m_template;
|
||||||
|
Loading…
Reference in New Issue
Block a user