Commit 97eb0bc5 authored by Laszlo Agocs's avatar Laszlo Agocs
Browse files

d3d: minimize vertex input changes

parent bf2c8f6a
......@@ -962,18 +962,21 @@ public:
// When specified, srb can be different from ps' srb but the layouts must
// match. Basic tracking is included: no command is added to the cb when
// the pipeline or desc.set are the same as in the last call in the same
// frame; srb is updated automatically at this point whenever a referenced
// buffer, texture, etc. is out of date internally (due to rebuilding since
// the creation of the srb) - hence no need to manually recreate the srb in
// case a QRhiBuffer is "resized" etc.
// the pipeline or srb are the same as in the last call in the same frame;
// resource bindings are updated automatically at this point if a
// referenced buffer, texture, etc. has a new underlying native resource
// (due to rebuilding since the creation of the srb) - hence no need to
// rebuild the srb in case, for example, a QRhiBuffer is "resized" via
// setSize()+build().
void setGraphicsPipeline(QRhiGraphicsPipeline *ps,
QRhiShaderResourceBindings *srb = nullptr);
// The set* and draw* functions expect to have the pipeline set before on
// the command buffer. Otherwise, unspecified issues may arise depending on
// The set* and draw* functions expect to have a pipeline set already on
// the command buffer. Otherwise, unspecified issues may arise, depending on
// the backend.
// Some level of smartness can be expected from most backends: superfluous
// vertex input or index buffer changes are ignored automatically.
using VertexInput = QPair<QRhiBuffer *, quint32>; // buffer, offset
void setVertexInput(int startBinding, const QVector<VertexInput> &bindings,
QRhiBuffer *indexBuf = nullptr, quint32 indexOffset = 0,
......
......@@ -400,36 +400,61 @@ void QRhiD3D11::setVertexInput(QRhiCommandBuffer *cb, int startBinding, const QV
Q_ASSERT(inPass);
QD3D11CommandBuffer *cbD = QRHI_RES(QD3D11CommandBuffer, cb);
QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::BindVertexBuffers;
cmd.args.bindVertexBuffers.startSlot = startBinding;
cmd.args.bindVertexBuffers.slotCount = bindings.count();
bool needsBindVBuf = false;
for (int i = 0, ie = bindings.count(); i != ie; ++i) {
QRhiBuffer *buf = bindings[i].first;
quint32 ofs = bindings[i].second;
QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, buf);
const int inputSlot = startBinding + i;
QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, bindings[i].first);
Q_ASSERT(bufD->m_usage.testFlag(QRhiBuffer::VertexBuffer));
cmd.args.bindVertexBuffers.buffers[i] = bufD->buffer;
cmd.args.bindVertexBuffers.offsets[i] = ofs;
cmd.args.bindVertexBuffers.strides[i] =
QRHI_RES(QD3D11GraphicsPipeline, cbD->currentPipeline)->m_vertexInputLayout.bindings[i].stride;
if (bufD->m_type == QRhiBuffer::Dynamic)
executeBufferHostWritesForCurrentFrame(bufD);
if (cbD->currentVertexBuffers[inputSlot] != bufD->buffer
|| cbD->currentVertexOffsets[inputSlot] != bindings[i].second)
{
needsBindVBuf = true;
cbD->currentVertexBuffers[inputSlot] = bufD->buffer;
cbD->currentVertexOffsets[inputSlot] = bindings[i].second;
}
}
if (needsBindVBuf) {
QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::BindVertexBuffers;
cmd.args.bindVertexBuffers.startSlot = startBinding;
cmd.args.bindVertexBuffers.slotCount = bindings.count();
for (int i = 0, ie = bindings.count(); i != ie; ++i) {
QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, bindings[i].first);
cmd.args.bindVertexBuffers.buffers[i] = bufD->buffer;
cmd.args.bindVertexBuffers.offsets[i] = bindings[i].second;
cmd.args.bindVertexBuffers.strides[i] =
QRHI_RES(QD3D11GraphicsPipeline, cbD->currentPipeline)->m_vertexInputLayout.bindings[i].stride;
}
cbD->commands.append(cmd);
}
cbD->commands.append(cmd);
if (indexBuf) {
QD3D11Buffer *ibufD = QRHI_RES(QD3D11Buffer, indexBuf);
Q_ASSERT(ibufD->m_usage.testFlag(QRhiBuffer::IndexBuffer));
QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::BindIndexBuffer;
cmd.args.bindIndexBuffer.buffer = ibufD->buffer;
cmd.args.bindIndexBuffer.offset = indexOffset;
cmd.args.bindIndexBuffer.format = indexFormat == QRhiCommandBuffer::IndexUInt16 ? DXGI_FORMAT_R16_UINT
: DXGI_FORMAT_R32_UINT;
cbD->commands.append(cmd);
if (ibufD->m_type == QRhiBuffer::Dynamic)
executeBufferHostWritesForCurrentFrame(ibufD);
const DXGI_FORMAT dxgiFormat = indexFormat == QRhiCommandBuffer::IndexUInt16 ? DXGI_FORMAT_R16_UINT
: DXGI_FORMAT_R32_UINT;
if (cbD->currentIndexBuffer != ibufD->buffer
|| cbD->currentIndexOffset != indexOffset
|| cbD->currentIndexFormat != dxgiFormat)
{
cbD->currentIndexBuffer = ibufD->buffer;
cbD->currentIndexOffset = indexOffset;
cbD->currentIndexFormat = dxgiFormat;
QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::BindIndexBuffer;
cmd.args.bindIndexBuffer.buffer = ibufD->buffer;
cmd.args.bindIndexBuffer.offset = indexOffset;
cmd.args.bindIndexBuffer.format = dxgiFormat;
cbD->commands.append(cmd);
}
}
}
......
......@@ -364,6 +364,11 @@ struct QD3D11CommandBuffer : public QRhiCommandBuffer
uint currentPipelineGeneration;
QRhiShaderResourceBindings *currentSrb;
uint currentSrbGeneration;
ID3D11Buffer *currentIndexBuffer;
quint32 currentIndexOffset;
DXGI_FORMAT currentIndexFormat;
ID3D11Buffer *currentVertexBuffers[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
UINT currentVertexOffsets[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
QVector<QByteArray> dataRetainPool;
QVector<QImage> imageRetainPool;
......@@ -389,6 +394,11 @@ struct QD3D11CommandBuffer : public QRhiCommandBuffer
currentPipelineGeneration = 0;
currentSrb = nullptr;
currentSrbGeneration = 0;
currentIndexBuffer = nullptr;
currentIndexOffset = 0;
currentIndexFormat = DXGI_FORMAT_R16_UINT;
memset(currentVertexBuffers, 0, sizeof(currentVertexBuffers));
memset(currentVertexOffsets, 0, sizeof(currentVertexOffsets));
}
};
......
......@@ -45,7 +45,7 @@ dxc for d3d as an alternative to fxc?
hlsl -> dxc -> spirv -> spirv-cross hmmm...
+++ done
mtl: minimize vertex input changes
d3d, mtl: minimize vertex input changes
mtl: cbuffers, textures, samplers set should be batched too
mtl: reduce set*
mtl: report readback temp buf
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment