1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00

[dxvk] Implement support for dynamic buffer binding offsets

This commit is contained in:
Philip Rebohle 2018-06-22 00:33:06 +02:00
parent 826b1245a1
commit 4b5ec1be3e
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 154 additions and 53 deletions

View File

@ -231,12 +231,14 @@ namespace dxvk {
void cmdBindDescriptorSet( void cmdBindDescriptorSet(
VkPipelineBindPoint pipeline, VkPipelineBindPoint pipeline,
VkPipelineLayout pipelineLayout, VkPipelineLayout pipelineLayout,
VkDescriptorSet descriptorSet) { VkDescriptorSet descriptorSet,
uint32_t dynamicOffsetCount,
const uint32_t* pDynamicOffsets) {
m_vkd->vkCmdBindDescriptorSets(m_execBuffer, m_vkd->vkCmdBindDescriptorSets(m_execBuffer,
pipeline, pipelineLayout, 0, 1, pipeline, pipelineLayout, 0, 1,
&descriptorSet, 0, nullptr); &descriptorSet, dynamicOffsetCount, pDynamicOffsets);
} }

View File

@ -311,7 +311,8 @@ namespace dxvk {
pipeInfo.pipeline); pipeInfo.pipeline);
m_cmd->cmdBindDescriptorSet( m_cmd->cmdBindDescriptorSet(
VK_PIPELINE_BIND_POINT_COMPUTE, VK_PIPELINE_BIND_POINT_COMPUTE,
pipeInfo.pipeLayout, descriptorSet); pipeInfo.pipeLayout, descriptorSet,
0, nullptr);
m_cmd->cmdPushConstants( m_cmd->cmdPushConstants(
pipeInfo.pipeLayout, pipeInfo.pipeLayout,
VK_SHADER_STAGE_COMPUTE_BIT, VK_SHADER_STAGE_COMPUTE_BIT,
@ -548,7 +549,8 @@ namespace dxvk {
pipeInfo.pipeline); pipeInfo.pipeline);
m_cmd->cmdBindDescriptorSet( m_cmd->cmdBindDescriptorSet(
VK_PIPELINE_BIND_POINT_COMPUTE, VK_PIPELINE_BIND_POINT_COMPUTE,
pipeInfo.pipeLayout, descriptorSet); pipeInfo.pipeLayout, descriptorSet,
0, nullptr);
m_cmd->cmdPushConstants( m_cmd->cmdPushConstants(
pipeInfo.pipeLayout, pipeInfo.pipeLayout,
VK_SHADER_STAGE_COMPUTE_BIT, VK_SHADER_STAGE_COMPUTE_BIT,
@ -1109,7 +1111,7 @@ namespace dxvk {
m_cmd->cmdBeginRenderPass(&passInfo, VK_SUBPASS_CONTENTS_INLINE); m_cmd->cmdBeginRenderPass(&passInfo, VK_SUBPASS_CONTENTS_INLINE);
m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeInfo.pipeHandle); m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeInfo.pipeHandle);
m_cmd->cmdBindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, m_cmd->cmdBindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS,
pipeInfo.pipeLayout, descriptorWrite.dstSet); pipeInfo.pipeLayout, descriptorWrite.dstSet, 0, nullptr);
m_cmd->cmdSetViewport(0, 1, &viewport); m_cmd->cmdSetViewport(0, 1, &viewport);
m_cmd->cmdSetScissor (0, 1, &scissor); m_cmd->cmdSetScissor (0, 1, &scissor);
@ -1146,12 +1148,22 @@ namespace dxvk {
if (usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) if (usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers); m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers);
if (usage & (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) {
| VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
| VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT))
m_flags.set(DxvkContextFlag::GpDirtyResources, m_flags.set(DxvkContextFlag::GpDirtyResources,
DxvkContextFlag::CpDirtyResources); DxvkContextFlag::CpDirtyResources);
}
if (usage & (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) {
if (prevSlice.handle() != slice.handle()) {
m_flags.set(DxvkContextFlag::GpDirtyResources,
DxvkContextFlag::CpDirtyResources);
} else {
m_flags.set(DxvkContextFlag::GpDirtyDescriptorOffsets,
DxvkContextFlag::CpDirtyDescriptorOffsets);
}
}
} }
@ -1783,58 +1795,94 @@ namespace dxvk {
void DxvkContext::updateComputeShaderResources() { void DxvkContext::updateComputeShaderResources() {
if (m_flags.test(DxvkContextFlag::CpDirtyResources)) { if (m_state.cp.pipeline == nullptr)
if (m_state.cp.pipeline != nullptr) { return;
this->updateShaderResources(
VK_PIPELINE_BIND_POINT_COMPUTE, if ((m_flags.test(DxvkContextFlag::CpDirtyResources))
m_state.cp.pipeline->layout()); || (m_flags.test(DxvkContextFlag::CpDirtyDescriptorOffsets)
} && m_state.cp.pipeline->layout()->hasStaticBufferBindings())) {
m_flags.clr(DxvkContextFlag::CpDirtyResources);
this->updateShaderResources(
VK_PIPELINE_BIND_POINT_COMPUTE,
m_state.cp.pipeline->layout());
m_flags.set(
DxvkContextFlag::CpDirtyDescriptorSet,
DxvkContextFlag::CpDirtyDescriptorOffsets);
} }
} }
void DxvkContext::updateComputeShaderDescriptors() { void DxvkContext::updateComputeShaderDescriptors() {
if (m_flags.test(DxvkContextFlag::CpDirtyResources)) { if (m_state.cp.pipeline == nullptr)
m_flags.clr(DxvkContextFlag::CpDirtyResources); return;
if (m_state.cp.pipeline != nullptr) { if (m_flags.test(DxvkContextFlag::CpDirtyDescriptorSet)) {
this->updateShaderDescriptors( m_cpSet = this->updateShaderDescriptors(
VK_PIPELINE_BIND_POINT_COMPUTE, VK_PIPELINE_BIND_POINT_COMPUTE,
m_state.cp.state.bsBindingState, m_state.cp.state.bsBindingState,
m_state.cp.pipeline->layout()); m_state.cp.pipeline->layout());
}
} }
if (m_flags.test(DxvkContextFlag::CpDirtyDescriptorOffsets)) {
this->updateShaderDescriptorSetBinding(
VK_PIPELINE_BIND_POINT_COMPUTE, m_cpSet,
m_state.cp.pipeline->layout());
}
m_flags.clr(
DxvkContextFlag::CpDirtyDescriptorOffsets,
DxvkContextFlag::CpDirtyDescriptorSet);
} }
void DxvkContext::updateGraphicsShaderResources() { void DxvkContext::updateGraphicsShaderResources() {
if (m_flags.test(DxvkContextFlag::GpDirtyResources)) { if (m_state.gp.pipeline == nullptr)
if (m_state.gp.pipeline != nullptr) { return;
this->updateShaderResources(
VK_PIPELINE_BIND_POINT_GRAPHICS, if ((m_flags.test(DxvkContextFlag::GpDirtyResources))
m_state.gp.pipeline->layout()); || (m_flags.test(DxvkContextFlag::GpDirtyDescriptorOffsets)
} && m_state.gp.pipeline->layout()->hasStaticBufferBindings())) {
m_flags.clr(DxvkContextFlag::GpDirtyResources);
this->updateShaderResources(
VK_PIPELINE_BIND_POINT_GRAPHICS,
m_state.gp.pipeline->layout());
m_flags.set(
DxvkContextFlag::GpDirtyDescriptorSet,
DxvkContextFlag::GpDirtyDescriptorOffsets);
} }
} }
void DxvkContext::updateGraphicsShaderDescriptors() { void DxvkContext::updateGraphicsShaderDescriptors() {
if (m_flags.test(DxvkContextFlag::GpDirtyResources)) { if (m_state.gp.pipeline == nullptr)
m_flags.clr(DxvkContextFlag::GpDirtyResources); return;
if (m_state.gp.pipeline != nullptr) { if (m_flags.test(DxvkContextFlag::GpDirtyDescriptorSet)) {
this->updateShaderDescriptors( m_gpSet = this->updateShaderDescriptors(
VK_PIPELINE_BIND_POINT_GRAPHICS, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_state.gp.state.bsBindingState, m_state.gp.state.bsBindingState,
m_state.gp.pipeline->layout()); m_state.gp.pipeline->layout());
}
} }
if (m_flags.test(DxvkContextFlag::GpDirtyDescriptorOffsets)) {
this->updateShaderDescriptorSetBinding(
VK_PIPELINE_BIND_POINT_GRAPHICS, m_gpSet,
m_state.gp.pipeline->layout());
}
m_flags.clr(
DxvkContextFlag::GpDirtyDescriptorOffsets,
DxvkContextFlag::GpDirtyDescriptorSet);
} }
void DxvkContext::updateShaderResources( void DxvkContext::updateShaderResources(
VkPipelineBindPoint bindPoint, VkPipelineBindPoint bindPoint,
const Rc<DxvkPipelineLayout>& layout) { const DxvkPipelineLayout* layout) {
DxvkBindingState& bindingState = DxvkBindingState& bindingState =
bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS
? m_state.gp.state.bsBindingState ? m_state.gp.state.bsBindingState
@ -1917,11 +1965,27 @@ namespace dxvk {
m_descInfos[i].buffer = m_device->dummyBufferDescriptor(); m_descInfos[i].buffer = m_device->dummyBufferDescriptor();
} break; } break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
if (res.bufferSlice.defined()) {
updatePipelineState |= bindingState.setBound(i);
auto physicalSlice = res.bufferSlice.physicalSlice();
m_descInfos[i].buffer.buffer = physicalSlice.handle();
m_descInfos[i].buffer.offset = 0; /* dynamic */
m_descInfos[i].buffer.range = physicalSlice.length();
m_cmd->trackResource(physicalSlice.resource());
} else {
updatePipelineState |= bindingState.setUnbound(i);
m_descInfos[i].buffer = m_device->dummyBufferDescriptor();
} break;
default: default:
Logger::err(str::format("DxvkContext: Unhandled descriptor type: ", binding.type)); Logger::err(str::format("DxvkContext: Unhandled descriptor type: ", binding.type));
} }
} }
if (updatePipelineState) { if (updatePipelineState) {
m_flags.set(bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS m_flags.set(bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS
? DxvkContextFlag::GpDirtyPipelineState ? DxvkContextFlag::GpDirtyPipelineState
@ -1930,21 +1994,43 @@ namespace dxvk {
} }
void DxvkContext::updateShaderDescriptors( VkDescriptorSet DxvkContext::updateShaderDescriptors(
VkPipelineBindPoint bindPoint, VkPipelineBindPoint bindPoint,
const DxvkBindingState& bindingState, const DxvkBindingState& bindingState,
const Rc<DxvkPipelineLayout>& layout) { const DxvkPipelineLayout* layout) {
VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
if (layout->bindingCount() != 0) { if (layout->bindingCount() != 0) {
const VkDescriptorSet dset = descriptorSet = m_cmd->allocateDescriptorSet(
m_cmd->allocateDescriptorSet( layout->descriptorSetLayout());
layout->descriptorSetLayout());
m_cmd->updateDescriptorSetWithTemplate( m_cmd->updateDescriptorSetWithTemplate(
dset, layout->descriptorTemplate(), descriptorSet, layout->descriptorTemplate(),
m_descInfos.data()); m_descInfos.data());
}
return descriptorSet;
}
void DxvkContext::updateShaderDescriptorSetBinding(
VkPipelineBindPoint bindPoint,
VkDescriptorSet set,
const DxvkPipelineLayout* layout) {
if (set != VK_NULL_HANDLE) {
for (uint32_t i = 0; i < layout->dynamicBindingCount(); i++) {
const auto& binding = layout->dynamicBinding(i);
const auto& res = m_rc[binding.slot];
m_descOffsets[i] = res.bufferSlice.defined()
? res.bufferSlice.physicalSlice().offset()
: 0;
}
m_cmd->cmdBindDescriptorSet(bindPoint, m_cmd->cmdBindDescriptorSet(bindPoint,
layout->pipelineLayout(), dset); layout->pipelineLayout(), set,
layout->dynamicBindingCount(),
m_descOffsets.data());
} }
} }
@ -2128,10 +2214,12 @@ namespace dxvk {
switch (binding.type) { switch (binding.type) {
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
access.set(DxvkAccess::Write); access.set(DxvkAccess::Write);
/* fall through */ /* fall through */
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
requiresBarrier = m_barriers.isBufferDirty( requiresBarrier = m_barriers.isBufferDirty(
slot.bufferSlice.physicalSlice(), access); slot.bufferSlice.physicalSlice(), access);
break; break;
@ -2180,10 +2268,12 @@ namespace dxvk {
switch (binding.type) { switch (binding.type) {
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
access |= VK_ACCESS_SHADER_WRITE_BIT; access |= VK_ACCESS_SHADER_WRITE_BIT;
/* fall through */ /* fall through */
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
m_barriers.accessBuffer( m_barriers.accessBuffer(
slot.bufferSlice.physicalSlice(), slot.bufferSlice.physicalSlice(),
stages, access, stages, access,

View File

@ -636,11 +636,15 @@ namespace dxvk {
VkPipeline m_gpActivePipeline = VK_NULL_HANDLE; VkPipeline m_gpActivePipeline = VK_NULL_HANDLE;
VkPipeline m_cpActivePipeline = VK_NULL_HANDLE; VkPipeline m_cpActivePipeline = VK_NULL_HANDLE;
VkDescriptorSet m_gpSet = VK_NULL_HANDLE;
VkDescriptorSet m_cpSet = VK_NULL_HANDLE;
std::vector<DxvkQueryRevision> m_activeQueries; std::vector<DxvkQueryRevision> m_activeQueries;
std::array<DxvkShaderResourceSlot, MaxNumResourceSlots> m_rc; std::array<DxvkShaderResourceSlot, MaxNumResourceSlots> m_rc;
std::array<DxvkDescriptorInfo, MaxNumActiveBindings> m_descInfos; std::array<DxvkDescriptorInfo, MaxNumActiveBindings> m_descInfos;
std::array<uint32_t, MaxNumActiveBindings> m_descOffsets;
void startRenderPass(); void startRenderPass();
void spillRenderPass(); void spillRenderPass();
@ -673,13 +677,18 @@ namespace dxvk {
void updateShaderResources( void updateShaderResources(
VkPipelineBindPoint bindPoint, VkPipelineBindPoint bindPoint,
const Rc<DxvkPipelineLayout>& layout); const DxvkPipelineLayout* layout);
void updateShaderDescriptors( VkDescriptorSet updateShaderDescriptors(
VkPipelineBindPoint bindPoint, VkPipelineBindPoint bindPoint,
const DxvkBindingState& bindingState, const DxvkBindingState& bindingState,
const Rc<DxvkPipelineLayout>& layout); const DxvkPipelineLayout* layout);
void updateShaderDescriptorSetBinding(
VkPipelineBindPoint bindPoint,
VkDescriptorSet set,
const DxvkPipelineLayout* layout);
void updateFramebuffer(); void updateFramebuffer();
void updateIndexBufferBinding(); void updateIndexBufferBinding();