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:
parent
8029712aa4
commit
644f33a82b
@ -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);
|
||||||
});
|
});
|
||||||
|
@ -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) {
|
||||||
|
@ -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 = { };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user