1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-19 05:52:11 +01:00

[dxvk] Avoid updating binding mask on hot path in updateShaderResources

Assuming that everything is bound by default allows us to save a few
CPU cycles per descriptor to update as long as that assumption holds
true, while adding only a small constant cost for the update operation.
This commit is contained in:
Philip Rebohle 2019-06-23 23:43:25 +02:00
parent b7769759f2
commit 3293bd21d1
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99

View File

@ -3525,7 +3525,8 @@ namespace dxvk {
bool DxvkContext::updateShaderResources(
VkPipelineBindPoint bindPoint,
const DxvkPipelineLayout* layout) {
bool updatePipelineState = false;
DxvkBindingMask bindMask;
bindMask.setFirst(layout->bindingCount());
// If the depth attachment is also bound as a shader
// resource, we have to use the appropriate layout
@ -3541,8 +3542,8 @@ namespace dxvk {
}
}
// Select the bound resource mask to update
auto& bindMask = bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS
// Select the active binding mask to update
auto& refMask = bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS
? m_state.gp.state.bsBindingMask
: m_state.cp.state.bsBindingMask;
@ -3553,8 +3554,6 @@ namespace dxvk {
switch (binding.type) {
case VK_DESCRIPTOR_TYPE_SAMPLER:
if (res.sampler != nullptr) {
updatePipelineState |= bindMask.set(i);
m_descInfos[i].image.sampler = res.sampler->handle();
m_descInfos[i].image.imageView = VK_NULL_HANDLE;
m_descInfos[i].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
@ -3562,15 +3561,13 @@ namespace dxvk {
if (m_rcTracked.set(binding.slot))
m_cmd->trackResource(res.sampler);
} else {
updatePipelineState |= bindMask.clr(i);
bindMask.clr(i);
m_descInfos[i].image = m_device->dummySamplerDescriptor();
} break;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
if (res.imageView != nullptr && res.imageView->handle(binding.view) != VK_NULL_HANDLE) {
updatePipelineState |= bindMask.set(i);
m_descInfos[i].image.sampler = VK_NULL_HANDLE;
m_descInfos[i].image.imageView = res.imageView->handle(binding.view);
m_descInfos[i].image.imageLayout = res.imageView->imageInfo().layout;
@ -3583,15 +3580,13 @@ namespace dxvk {
m_cmd->trackResource(res.imageView->image());
}
} else {
updatePipelineState |= bindMask.clr(i);
bindMask.clr(i);
m_descInfos[i].image = m_device->dummyImageViewDescriptor(binding.view);
} break;
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
if (res.sampler != nullptr && res.imageView != nullptr
&& res.imageView->handle(binding.view) != VK_NULL_HANDLE) {
updatePipelineState |= bindMask.set(i);
m_descInfos[i].image.sampler = res.sampler->handle();
m_descInfos[i].image.imageView = res.imageView->handle(binding.view);
m_descInfos[i].image.imageLayout = res.imageView->imageInfo().layout;
@ -3605,15 +3600,13 @@ namespace dxvk {
m_cmd->trackResource(res.imageView->image());
}
} else {
updatePipelineState |= bindMask.clr(i);
bindMask.clr(i);
m_descInfos[i].image = m_device->dummyImageSamplerDescriptor(binding.view);
} break;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
if (res.bufferView != nullptr) {
updatePipelineState |= bindMask.set(i);
res.bufferView->updateView();
m_descInfos[i].texelBuffer = res.bufferView->handle();
@ -3622,34 +3615,32 @@ namespace dxvk {
m_cmd->trackResource(res.bufferView->buffer());
}
} else {
updatePipelineState |= bindMask.clr(i);
bindMask.clr(i);
m_descInfos[i].texelBuffer = m_device->dummyBufferViewDescriptor();
} break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
if (res.bufferSlice.defined()) {
updatePipelineState |= bindMask.set(i);
m_descInfos[i] = res.bufferSlice.getDescriptor();
if (m_rcTracked.set(binding.slot))
m_cmd->trackResource(res.bufferSlice.buffer());
} else {
updatePipelineState |= bindMask.clr(i);
bindMask.clr(i);
m_descInfos[i].buffer = m_device->dummyBufferDescriptor();
} break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
if (res.bufferSlice.defined()) {
updatePipelineState |= bindMask.set(i);
m_descInfos[i] = res.bufferSlice.getDescriptor();
m_descInfos[i].buffer.offset = 0;
if (m_rcTracked.set(binding.slot))
m_cmd->trackResource(res.bufferSlice.buffer());
} else {
updatePipelineState |= bindMask.clr(i);
bindMask.clr(i);
m_descInfos[i].buffer = m_device->dummyBufferDescriptor();
} break;
@ -3658,6 +3649,13 @@ namespace dxvk {
}
}
// If some resources are not bound, we may need to
// update spec constants and rebind the pipeline
bool updatePipelineState = refMask != bindMask;
if (updatePipelineState)
refMask = bindMask;
return updatePipelineState;
}