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

[dxvk] Optimize unbound vertex buffer handling

We can actually just set the stride to 0 when binding a null
buffer, so that we can avoid all the runtime tracking.
This commit is contained in:
Philip Rebohle 2019-05-08 00:52:30 +02:00
parent 8029712aa4
commit 644f33a82b
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 7 additions and 19 deletions

View File

@ -3200,7 +3200,7 @@ namespace dxvk {
EmitCs([ EmitCs([
cSlotId = Slot, cSlotId = Slot,
cBufferSlice = pBuffer != nullptr ? pBuffer->GetBufferSlice(Offset) : DxvkBufferSlice(), cBufferSlice = pBuffer != nullptr ? pBuffer->GetBufferSlice(Offset) : DxvkBufferSlice(),
cStride = pBuffer != nullptr ? Stride : 0 cStride = Stride
] (DxvkContext* ctx) { ] (DxvkContext* ctx) {
ctx->bindVertexBuffer(cSlotId, cBufferSlice, cStride); ctx->bindVertexBuffer(cSlotId, cBufferSlice, cStride);
}); });

View File

@ -242,6 +242,9 @@ namespace dxvk {
m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers); m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers);
} }
if (unlikely(!buffer.defined()))
stride = 0;
if (m_state.vi.vertexStrides[binding] != stride) { if (m_state.vi.vertexStrides[binding] != stride) {
m_state.vi.vertexStrides[binding] = stride; m_state.vi.vertexStrides[binding] = stride;
m_flags.set(DxvkContextFlag::GpDirtyPipelineState); m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
@ -3316,14 +3319,10 @@ namespace dxvk {
this->pauseTransformFeedback(); this->pauseTransformFeedback();
// Fix up vertex binding strides for unbound buffers // Set up vertex buffer strides for active bindings
for (uint32_t i = 0; i < m_state.gp.state.ilBindingCount; i++) { for (uint32_t i = 0; i < m_state.gp.state.ilBindingCount; i++) {
const uint32_t binding = m_state.gp.state.ilBindings[i].binding; const uint32_t binding = m_state.gp.state.ilBindings[i].binding;
m_state.gp.state.ilBindings[i].stride = m_state.vi.vertexStrides[binding];
m_state.gp.state.ilBindings[i].stride
= (m_state.vi.bindingMask & (1u << binding)) != 0
? m_state.vi.vertexStrides[binding]
: 0;
} }
for (uint32_t i = m_state.gp.state.ilBindingCount; i < MaxNumVertexBindings; i++) for (uint32_t i = m_state.gp.state.ilBindingCount; i < MaxNumVertexBindings; i++)
@ -3679,10 +3678,10 @@ namespace dxvk {
// Set buffer handles and offsets for active bindings // Set buffer handles and offsets for active bindings
uint32_t bindingMask = 0; uint32_t bindingMask = 0;
uint32_t bindingDead = 0;
for (uint32_t i = 0; i < m_state.gp.state.ilBindingCount; i++) { for (uint32_t i = 0; i < m_state.gp.state.ilBindingCount; i++) {
uint32_t binding = m_state.gp.state.ilBindings[i].binding; uint32_t binding = m_state.gp.state.ilBindings[i].binding;
bindingMask |= 1u << binding;
if (likely(m_state.vi.vertexBuffers[binding].defined())) { if (likely(m_state.vi.vertexBuffers[binding].defined())) {
auto vbo = m_state.vi.vertexBuffers[binding].getDescriptor(); auto vbo = m_state.vi.vertexBuffers[binding].getDescriptor();
@ -3690,24 +3689,14 @@ namespace dxvk {
buffers[binding] = vbo.buffer.buffer; buffers[binding] = vbo.buffer.buffer;
offsets[binding] = vbo.buffer.offset; offsets[binding] = vbo.buffer.offset;
bindingMask |= 1u << binding;
m_cmd->trackResource(m_state.vi.vertexBuffers[binding].buffer()); m_cmd->trackResource(m_state.vi.vertexBuffers[binding].buffer());
} else { } else {
buffers[binding] = m_device->dummyBufferHandle(); buffers[binding] = m_device->dummyBufferHandle();
offsets[binding] = 0; offsets[binding] = 0;
bindingDead |= 1u << binding;
} }
} }
// Adjust stride of inactive bindings if needed
if (unlikely(m_state.vi.bindingMask != bindingMask)) {
m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
m_state.vi.bindingMask = bindingMask;
}
// Actually bind all the vertex buffers. // Actually bind all the vertex buffers.
bindingMask |= bindingDead;
uint32_t bindingIndex = 0; uint32_t bindingIndex = 0;
while (bindingMask) { while (bindingMask) {

View File

@ -81,7 +81,6 @@ namespace dxvk {
struct DxvkVertexInputState { struct DxvkVertexInputState {
DxvkBufferSlice indexBuffer; DxvkBufferSlice indexBuffer;
VkIndexType indexType = VK_INDEX_TYPE_UINT32; VkIndexType indexType = VK_INDEX_TYPE_UINT32;
uint32_t bindingMask = 0;
std::array<DxvkBufferSlice, DxvkLimits::MaxNumVertexBindings> vertexBuffers = { }; std::array<DxvkBufferSlice, DxvkLimits::MaxNumVertexBindings> vertexBuffers = { };
std::array<uint32_t, DxvkLimits::MaxNumVertexBindings> vertexStrides = { }; std::array<uint32_t, DxvkLimits::MaxNumVertexBindings> vertexStrides = { };