summaryrefslogtreecommitdiffstats
path: root/src/gui/rhi
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2020-10-13 19:29:00 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2020-10-16 09:48:09 +0200
commit0461c535fcb26ea231ee8645e67ef2e8d4429e95 (patch)
treeedfaba6cc782e0a3c281d28aa2956ae2a3ddedd4 /src/gui/rhi
parent802d98d318d1dabf377d1030b81e99fe57f1b483 (diff)
rhi: Further reduce copying in the command buffer
Change-Id: I2e2ff5f4b8aa91d0accb01108a5199b98c371455 Reviewed-by: Christian Strømme <christian.stromme@qt.io>
Diffstat (limited to 'src/gui/rhi')
-rw-r--r--src/gui/rhi/qrhi_p_p.h32
-rw-r--r--src/gui/rhi/qrhid3d11.cpp116
-rw-r--r--src/gui/rhi/qrhid3d11_p_p.h16
-rw-r--r--src/gui/rhi/qrhigles2.cpp114
-rw-r--r--src/gui/rhi/qrhigles2_p_p.h14
-rw-r--r--src/gui/rhi/qrhivulkan.cpp99
-rw-r--r--src/gui/rhi/qrhivulkan_p_p.h7
7 files changed, 170 insertions, 228 deletions
diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h
index 491f0c6f26..8a85227bae 100644
--- a/src/gui/rhi/qrhi_p_p.h
+++ b/src/gui/rhi/qrhi_p_p.h
@@ -655,6 +655,38 @@ private:
Q_DECLARE_TYPEINFO(QRhiPassResourceTracker::Buffer, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QRhiPassResourceTracker::Texture, Q_MOVABLE_TYPE);
+template<typename T, int GROW = 1024>
+class QRhiBackendCommandList
+{
+public:
+ QRhiBackendCommandList() = default;
+ ~QRhiBackendCommandList() { delete v; }
+ inline void reset() { p = 0; }
+ inline bool isEmpty() const { return p == 0; }
+ inline T &get() {
+ if (p == a) {
+ a += GROW;
+ T *nv = new T[a];
+ if (v) {
+ memcpy(nv, v, p * sizeof(T));
+ delete[] v;
+ }
+ v = nv;
+ }
+ return v[p++];
+ }
+ inline void unget() { --p; }
+ inline T *cbegin() const { return v; }
+ inline T *cend() const { return v + p; }
+ inline T *begin() { return v; }
+ inline T *end() { return v + p; }
+private:
+ Q_DISABLE_COPY(QRhiBackendCommandList)
+ T *v = nullptr;
+ int a = 0;
+ int p = 0;
+};
+
QT_END_NAMESPACE
#endif
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index ce954c9fe0..0db32e794f 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -649,10 +649,9 @@ void QRhiD3D11::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
cbD->currentComputePipeline = nullptr;
cbD->currentPipelineGeneration = psD->generation;
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::BindGraphicsPipeline;
cmd.args.bindGraphicsPipeline.ps = psD;
- cbD->commands.append(cmd);
}
}
@@ -778,7 +777,7 @@ void QRhiD3D11::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
}
cbD->currentSrbGeneration = srbD->generation;
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::BindShaderResources;
cmd.args.bindShaderResources.srb = srbD;
// dynamic offsets have to be applied at the time of executing the bind
@@ -786,7 +785,7 @@ void QRhiD3D11::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
cmd.args.bindShaderResources.offsetOnlyChange = !srbChanged && !srbRebuilt && !srbUpdate && srbD->hasDynamicOffset;
cmd.args.bindShaderResources.dynamicOffsetCount = 0;
if (srbD->hasDynamicOffset) {
- if (dynamicOffsetCount < QD3D11CommandBuffer::Command::MAX_DYNAMIC_OFFSET_COUNT) {
+ if (dynamicOffsetCount < QD3D11CommandBuffer::MAX_DYNAMIC_OFFSET_COUNT) {
cmd.args.bindShaderResources.dynamicOffsetCount = dynamicOffsetCount;
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
for (int i = 0; i < dynamicOffsetCount; ++i) {
@@ -799,11 +798,9 @@ void QRhiD3D11::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
}
} else {
qWarning("Too many dynamic offsets (%d, max is %d)",
- dynamicOffsetCount, QD3D11CommandBuffer::Command::MAX_DYNAMIC_OFFSET_COUNT);
+ dynamicOffsetCount, QD3D11CommandBuffer::MAX_DYNAMIC_OFFSET_COUNT);
}
}
-
- cbD->commands.append(cmd);
}
}
@@ -832,13 +829,13 @@ void QRhiD3D11::setVertexInput(QRhiCommandBuffer *cb,
}
if (needsBindVBuf) {
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::BindVertexBuffers;
cmd.args.bindVertexBuffers.startSlot = startBinding;
- if (bindingCount > QD3D11CommandBuffer::Command::MAX_VERTEX_BUFFER_BINDING_COUNT) {
+ if (bindingCount > QD3D11CommandBuffer::MAX_VERTEX_BUFFER_BINDING_COUNT) {
qWarning("Too many vertex buffer bindings (%d, max is %d)",
- bindingCount, QD3D11CommandBuffer::Command::MAX_VERTEX_BUFFER_BINDING_COUNT);
- bindingCount = QD3D11CommandBuffer::Command::MAX_VERTEX_BUFFER_BINDING_COUNT;
+ bindingCount, QD3D11CommandBuffer::MAX_VERTEX_BUFFER_BINDING_COUNT);
+ bindingCount = QD3D11CommandBuffer::MAX_VERTEX_BUFFER_BINDING_COUNT;
}
cmd.args.bindVertexBuffers.slotCount = bindingCount;
QD3D11GraphicsPipeline *psD = QRHI_RES(QD3D11GraphicsPipeline, cbD->currentGraphicsPipeline);
@@ -850,7 +847,6 @@ void QRhiD3D11::setVertexInput(QRhiCommandBuffer *cb,
cmd.args.bindVertexBuffers.offsets[i] = bindings[i].second;
cmd.args.bindVertexBuffers.strides[i] = inputLayout.bindingAt(i)->stride();
}
- cbD->commands.append(cmd);
}
if (indexBuf) {
@@ -869,12 +865,11 @@ void QRhiD3D11::setVertexInput(QRhiCommandBuffer *cb,
cbD->currentIndexOffset = indexOffset;
cbD->currentIndexFormat = dxgiFormat;
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
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);
}
}
}
@@ -886,21 +881,19 @@ void QRhiD3D11::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport)
Q_ASSERT(cbD->currentTarget);
const QSize outputSize = cbD->currentTarget->pixelSize();
- QD3D11CommandBuffer::Command cmd;
- cmd.cmd = QD3D11CommandBuffer::Command::Viewport;
-
// d3d expects top-left, QRhiViewport is bottom-left
float x, y, w, h;
if (!qrhi_toTopLeftRenderTargetRect(outputSize, viewport.viewport(), &x, &y, &w, &h))
return;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
+ cmd.cmd = QD3D11CommandBuffer::Command::Viewport;
cmd.args.viewport.x = x;
cmd.args.viewport.y = y;
cmd.args.viewport.w = w;
cmd.args.viewport.h = h;
cmd.args.viewport.d0 = viewport.minDepth();
cmd.args.viewport.d1 = viewport.maxDepth();
- cbD->commands.append(cmd);
}
void QRhiD3D11::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
@@ -910,19 +903,17 @@ void QRhiD3D11::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
Q_ASSERT(cbD->currentTarget);
const QSize outputSize = cbD->currentTarget->pixelSize();
- QD3D11CommandBuffer::Command cmd;
- cmd.cmd = QD3D11CommandBuffer::Command::Scissor;
-
// d3d expects top-left, QRhiScissor is bottom-left
int x, y, w, h;
if (!qrhi_toTopLeftRenderTargetRect(outputSize, scissor.scissor(), &x, &y, &w, &h))
return;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
+ cmd.cmd = QD3D11CommandBuffer::Command::Scissor;
cmd.args.scissor.x = x;
cmd.args.scissor.y = y;
cmd.args.scissor.w = w;
cmd.args.scissor.h = h;
- cbD->commands.append(cmd);
}
void QRhiD3D11::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
@@ -930,14 +921,13 @@ void QRhiD3D11::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
QD3D11CommandBuffer *cbD = QRHI_RES(QD3D11CommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QD3D11CommandBuffer::RenderPass);
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::BlendConstants;
cmd.args.blendConstants.ps = QRHI_RES(QD3D11GraphicsPipeline, cbD->currentGraphicsPipeline);
cmd.args.blendConstants.c[0] = float(c.redF());
cmd.args.blendConstants.c[1] = float(c.greenF());
cmd.args.blendConstants.c[2] = float(c.blueF());
cmd.args.blendConstants.c[3] = float(c.alphaF());
- cbD->commands.append(cmd);
}
void QRhiD3D11::setStencilRef(QRhiCommandBuffer *cb, quint32 refValue)
@@ -945,11 +935,10 @@ void QRhiD3D11::setStencilRef(QRhiCommandBuffer *cb, quint32 refValue)
QD3D11CommandBuffer *cbD = QRHI_RES(QD3D11CommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QD3D11CommandBuffer::RenderPass);
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::StencilRef;
cmd.args.stencilRef.ps = QRHI_RES(QD3D11GraphicsPipeline, cbD->currentGraphicsPipeline);
cmd.args.stencilRef.ref = refValue;
- cbD->commands.append(cmd);
}
void QRhiD3D11::draw(QRhiCommandBuffer *cb, quint32 vertexCount,
@@ -958,14 +947,13 @@ void QRhiD3D11::draw(QRhiCommandBuffer *cb, quint32 vertexCount,
QD3D11CommandBuffer *cbD = QRHI_RES(QD3D11CommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QD3D11CommandBuffer::RenderPass);
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::Draw;
cmd.args.draw.ps = QRHI_RES(QD3D11GraphicsPipeline, cbD->currentGraphicsPipeline);
cmd.args.draw.vertexCount = vertexCount;
cmd.args.draw.instanceCount = instanceCount;
cmd.args.draw.firstVertex = firstVertex;
cmd.args.draw.firstInstance = firstInstance;
- cbD->commands.append(cmd);
}
void QRhiD3D11::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
@@ -974,7 +962,7 @@ void QRhiD3D11::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
QD3D11CommandBuffer *cbD = QRHI_RES(QD3D11CommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QD3D11CommandBuffer::RenderPass);
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::DrawIndexed;
cmd.args.drawIndexed.ps = QRHI_RES(QD3D11GraphicsPipeline, cbD->currentGraphicsPipeline);
cmd.args.drawIndexed.indexCount = indexCount;
@@ -982,7 +970,6 @@ void QRhiD3D11::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
cmd.args.drawIndexed.firstIndex = firstIndex;
cmd.args.drawIndexed.vertexOffset = vertexOffset;
cmd.args.drawIndexed.firstInstance = firstInstance;
- cbD->commands.append(cmd);
}
void QRhiD3D11::debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name)
@@ -991,10 +978,9 @@ void QRhiD3D11::debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name)
return;
QD3D11CommandBuffer *cbD = QRHI_RES(QD3D11CommandBuffer, cb);
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::DebugMarkBegin;
qstrncpy(cmd.args.debugMark.s, name.constData(), sizeof(cmd.args.debugMark.s));
- cbD->commands.append(cmd);
}
void QRhiD3D11::debugMarkEnd(QRhiCommandBuffer *cb)
@@ -1003,9 +989,8 @@ void QRhiD3D11::debugMarkEnd(QRhiCommandBuffer *cb)
return;
QD3D11CommandBuffer *cbD = QRHI_RES(QD3D11CommandBuffer, cb);
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::DebugMarkEnd;
- cbD->commands.append(cmd);
}
void QRhiD3D11::debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg)
@@ -1014,10 +999,9 @@ void QRhiD3D11::debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg)
return;
QD3D11CommandBuffer *cbD = QRHI_RES(QD3D11CommandBuffer, cb);
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::DebugMarkMsg;
qstrncpy(cmd.args.debugMark.s, msg.constData(), sizeof(cmd.args.debugMark.s));
- cbD->commands.append(cmd);
}
const QRhiNativeHandles *QRhiD3D11::nativeHandles(QRhiCommandBuffer *cb)
@@ -1040,10 +1024,9 @@ void QRhiD3D11::endExternal(QRhiCommandBuffer *cb)
Q_ASSERT(cbD->commands.isEmpty());
cbD->resetCachedState();
if (cbD->currentTarget) { // could be compute, no rendertarget then
- QD3D11CommandBuffer::Command fbCmd;
+ QD3D11CommandBuffer::Command &fbCmd(cbD->commands.get());
fbCmd.cmd = QD3D11CommandBuffer::Command::SetRenderTarget;
fbCmd.args.setRenderTarget.rt = cbD->currentTarget;
- cbD->commands.append(fbCmd);
}
}
@@ -1340,12 +1323,11 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
box.front = 0;
// back, right, bottom are exclusive
box.back = 1;
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::UpdateSubRes;
cmd.args.updateSubRes.dst = texD->tex;
cmd.args.updateSubRes.dstSubRes = subres;
- bool cmdValid = true;
if (!subresDesc.image().isNull()) {
QImage img = subresDesc.image();
QSize size = img.size();
@@ -1404,10 +1386,8 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
cmd.args.updateSubRes.srcRowPitch = bpl;
} else {
qWarning("Invalid texture upload for %p layer=%d mip=%d", texD, layer, level);
- cmdValid = false;
+ cbD->commands.unget();
}
- if (cmdValid)
- cbD->commands.append(cmd);
}
void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)
@@ -1427,7 +1407,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, u.buf);
Q_ASSERT(bufD->m_type != QRhiBuffer::Dynamic);
Q_ASSERT(u.offset + u.data.size() <= bufD->m_size);
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::UpdateSubRes;
cmd.args.updateSubRes.dst = bufD->buffer;
cmd.args.updateSubRes.dstSubRes = 0;
@@ -1443,7 +1423,6 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
box.right = UINT(u.offset + u.data.size()); // no -1: right, bottom, back are exclusive, see D3D11_BOX doc
cmd.args.updateSubRes.hasDstBox = true;
cmd.args.updateSubRes.dstBox = box;
- cbD->commands.append(cmd);
} else if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::Read) {
QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, u.buf);
if (bufD->m_type == QRhiBuffer::Dynamic) {
@@ -1466,7 +1445,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
}
QRHI_PROF_F(newReadbackBuffer(qint64(qintptr(readback.stagingBuf)), bufD, readback.byteSize));
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::CopySubRes;
cmd.args.copySubRes.dst = readback.stagingBuf;
cmd.args.copySubRes.dstSubRes = 0;
@@ -1481,7 +1460,6 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
box.back = box.bottom = 1;
box.right = UINT(u.offset + u.readSize);
cmd.args.copySubRes.srcBox = box;
- cbD->commands.append(cmd);
activeBufferReadbacks.append(readback);
}
@@ -1517,7 +1495,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
srcBox.right = srcBox.left + UINT(copySize.width());
srcBox.bottom = srcBox.top + UINT(copySize.height());
srcBox.back = 1;
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::CopySubRes;
cmd.args.copySubRes.dst = dstD->tex;
cmd.args.copySubRes.dstSubRes = dstSubRes;
@@ -1527,7 +1505,6 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cmd.args.copySubRes.srcSubRes = srcSubRes;
cmd.args.copySubRes.hasSrcBox = true;
cmd.args.copySubRes.srcBox = srcBox;
- cbD->commands.append(cmd);
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Read) {
TextureReadback readback;
readback.desc = u.rb;
@@ -1557,14 +1534,13 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
if (swapChainD->sampleDesc.Count > 1) {
// Unlike with textures, reading back a multisample swapchain image
// has to be supported. Insert a resolve.
- QD3D11CommandBuffer::Command rcmd;
+ QD3D11CommandBuffer::Command &rcmd(cbD->commands.get());
rcmd.cmd = QD3D11CommandBuffer::Command::ResolveSubRes;
rcmd.args.resolveSubRes.dst = swapChainD->backBufferTex;
rcmd.args.resolveSubRes.dstSubRes = 0;
rcmd.args.resolveSubRes.src = swapChainD->msaaTex[swapChainD->currentFrameSlot];
rcmd.args.resolveSubRes.srcSubRes = 0;
rcmd.args.resolveSubRes.format = swapChainD->colorFormat;
- cbD->commands.append(rcmd);
}
src = swapChainD->backBufferTex;
dxgiFormat = swapChainD->colorFormat;
@@ -1597,7 +1573,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
texD ? static_cast<QRhiResource *>(texD) : static_cast<QRhiResource *>(swapChainD),
byteSize));
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::CopySubRes;
cmd.args.copySubRes.dst = stagingTex;
cmd.args.copySubRes.dstSubRes = 0;
@@ -1606,7 +1582,6 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cmd.args.copySubRes.src = src;
cmd.args.copySubRes.srcSubRes = subres;
cmd.args.copySubRes.hasSrcBox = false;
- cbD->commands.append(cmd);
readback.stagingTex = stagingTex;
readback.byteSize = byteSize;
@@ -1617,10 +1592,9 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
activeTextureReadbacks.append(readback);
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::GenMips) {
Q_ASSERT(u.dst->flags().testFlag(QRhiTexture::UsedWithGenerateMips));
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::GenMip;
cmd.args.genMip.srv = QRHI_RES(QD3D11Texture, u.dst)->srv;
- cbD->commands.append(cmd);
}
}
@@ -1732,14 +1706,13 @@ void QRhiD3D11::beginPass(QRhiCommandBuffer *cb,
wantsDsClear = !rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents);
}
- QD3D11CommandBuffer::Command fbCmd;
- fbCmd.cmd = QD3D11CommandBuffer::Command::ResetShaderResources;
- cbD->commands.append(fbCmd);
+ cbD->commands.get().cmd = QD3D11CommandBuffer::Command::ResetShaderResources;
+
+ QD3D11CommandBuffer::Command &fbCmd(cbD->commands.get());
fbCmd.cmd = QD3D11CommandBuffer::Command::SetRenderTarget;
fbCmd.args.setRenderTarget.rt = rt;
- cbD->commands.append(fbCmd);
- QD3D11CommandBuffer::Command clearCmd;
+ QD3D11CommandBuffer::Command &clearCmd(cbD->commands.get());
clearCmd.cmd = QD3D11CommandBuffer::Command::Clear;
clearCmd.args.clear.rt = rt;
clearCmd.args.clear.mask = 0;
@@ -1754,7 +1727,6 @@ void QRhiD3D11::beginPass(QRhiCommandBuffer *cb,
clearCmd.args.clear.c[3] = float(colorClearValue.alphaF());
clearCmd.args.clear.d = depthStencilClearValue.depthClearValue();
clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue();
- cbD->commands.append(clearCmd);
cbD->recordingPass = QD3D11CommandBuffer::RenderPass;
cbD->currentTarget = rt;
@@ -1780,7 +1752,7 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
QD3D11Texture *srcTexD = QRHI_RES(QD3D11Texture, colorAtt.texture());
QD3D11RenderBuffer *srcRbD = QRHI_RES(QD3D11RenderBuffer, colorAtt.renderBuffer());
Q_ASSERT(srcTexD || srcRbD);
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::ResolveSubRes;
cmd.args.resolveSubRes.dst = dstTexD->tex;
cmd.args.resolveSubRes.dstSubRes = D3D11CalcSubresource(UINT(colorAtt.resolveLevel()),
@@ -1791,14 +1763,17 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
if (srcTexD->dxgiFormat != dstTexD->dxgiFormat) {
qWarning("Resolve source (%d) and destination (%d) formats do not match",
int(srcTexD->dxgiFormat), int(dstTexD->dxgiFormat));
+ cbD->commands.unget();
continue;
}
if (srcTexD->sampleDesc.Count <= 1) {
qWarning("Cannot resolve a non-multisample texture");
+ cbD->commands.unget();
continue;
}
if (srcTexD->m_pixelSize != dstTexD->m_pixelSize) {
qWarning("Resolve source and destination sizes do not match");
+ cbD->commands.unget();
continue;
}
} else {
@@ -1806,16 +1781,17 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
if (srcRbD->dxgiFormat != dstTexD->dxgiFormat) {
qWarning("Resolve source (%d) and destination (%d) formats do not match",
int(srcRbD->dxgiFormat), int(dstTexD->dxgiFormat));
+ cbD->commands.unget();
continue;
}
if (srcRbD->m_pixelSize != dstTexD->m_pixelSize) {
qWarning("Resolve source and destination sizes do not match");
+ cbD->commands.unget();
continue;
}
}
cmd.args.resolveSubRes.srcSubRes = D3D11CalcSubresource(0, UINT(colorAtt.layer()), 1);
cmd.args.resolveSubRes.format = dstTexD->dxgiFormat;
- cbD->commands.append(cmd);
}
}
@@ -1836,9 +1812,8 @@ void QRhiD3D11::beginComputePass(QRhiCommandBuffer *cb,
if (resourceUpdates)
enqueueResourceUpdates(cb, resourceUpdates);
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::ResetShaderResources;
- cbD->commands.append(cmd);
cbD->recordingPass = QD3D11CommandBuffer::ComputePass;
@@ -1868,10 +1843,9 @@ void QRhiD3D11::setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *p
cbD->currentComputePipeline = psD;
cbD->currentPipelineGeneration = psD->generation;
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::BindComputePipeline;
cmd.args.bindComputePipeline.ps = psD;
- cbD->commands.append(cmd);
}
}
@@ -1880,12 +1854,11 @@ void QRhiD3D11::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
QD3D11CommandBuffer *cbD = QRHI_RES(QD3D11CommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QD3D11CommandBuffer::ComputePass);
- QD3D11CommandBuffer::Command cmd;
+ QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::Dispatch;
cmd.args.dispatch.x = UINT(x);
cmd.args.dispatch.y = UINT(y);
cmd.args.dispatch.z = UINT(z);
- cbD->commands.append(cmd);
}
static inline QPair<int, int> mapBinding(int binding,
@@ -2214,7 +2187,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
const uint *dynOfsPairs, int dynOfsPairCount,
bool offsetOnlyChange)
{
- UINT offsets[QD3D11CommandBuffer::Command::MAX_DYNAMIC_OFFSET_COUNT];
+ UINT offsets[QD3D11CommandBuffer::MAX_DYNAMIC_OFFSET_COUNT];
if (srbD->vsubufsPresent) {
for (int i = 0, ie = srbD->vsubufs.batches.count(); i != ie; ++i) {
@@ -2448,7 +2421,8 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
}
}
- for (const QD3D11CommandBuffer::Command &cmd : qAsConst(cbD->commands)) {
+ for (auto it = cbD->commands.cbegin(), end = cbD->commands.cend(); it != end; ++it) {
+ const QD3D11CommandBuffer::Command &cmd(*it);
switch (cmd.cmd) {
case QD3D11CommandBuffer::Command::ResetShaderResources:
resetShaderResources();
diff --git a/src/gui/rhi/qrhid3d11_p_p.h b/src/gui/rhi/qrhid3d11_p_p.h
index 1572751e6c..ff62327bdf 100644
--- a/src/gui/rhi/qrhid3d11_p_p.h
+++ b/src/gui/rhi/qrhid3d11_p_p.h
@@ -326,6 +326,10 @@ struct QD3D11CommandBuffer : public QRhiCommandBuffer
~QD3D11CommandBuffer();
void destroy() override;
+ // these must be kept at a reasonably low value otherwise sizeof Command explodes
+ static const int MAX_DYNAMIC_OFFSET_COUNT = 8;
+ static const int MAX_VERTEX_BUFFER_BINDING_COUNT = 8;
+
struct Command {
enum Cmd {
ResetShaderResources,
@@ -354,13 +358,9 @@ struct QD3D11CommandBuffer : public QRhiCommandBuffer
enum ClearFlag { Color = 1, Depth = 2, Stencil = 4 };
Cmd cmd;
- // these must be kept at a reasonably low value otherwise sizeof Command explodes
- static const int MAX_DYNAMIC_OFFSET_COUNT = 8;
- static const int MAX_VERTEX_BUFFER_BINDING_COUNT = 8;
-
// QRhi*/QD3D11* references should be kept at minimum (so no
// QRhiTexture/Buffer/etc. pointers).
- union {
+ union Args {
struct {
QRhiRenderTarget *rt;
} setRenderTarget;
@@ -470,7 +470,7 @@ struct QD3D11CommandBuffer : public QRhiCommandBuffer
ComputePass
};
- QVarLengthArray<Command, 1024> commands;
+ QRhiBackendCommandList<Command> commands;
PassType recordingPass;
QRhiRenderTarget *currentTarget;
QRhiGraphicsPipeline *currentGraphicsPipeline;
@@ -503,7 +503,7 @@ struct QD3D11CommandBuffer : public QRhiCommandBuffer
return imageRetainPool.last().constBits();
}
void resetCommands() {
- commands.clear();
+ commands.reset();
dataRetainPool.clear();
bufferDataRetainPool.clear();
imageRetainPool.clear();
@@ -532,8 +532,6 @@ struct QD3D11CommandBuffer : public QRhiCommandBuffer
}
};
-Q_DECLARE_TYPEINFO(QD3D11CommandBuffer::Command, Q_MOVABLE_TYPE);
-
struct QD3D11SwapChain : public QRhiSwapChain
{
QD3D11SwapChain(QRhiImplementation *rhi);
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index 39f03a784f..785c341a0f 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -1072,10 +1072,9 @@ void QRhiGles2::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
cbD->currentComputePipeline = nullptr;
cbD->currentPipelineGeneration = psD->generation;
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::BindGraphicsPipeline;
cmd.args.bindGraphicsPipeline.ps = ps;
- cbD->commands.append(cmd);
}
}
@@ -1151,9 +1150,7 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
}
const bool srbChanged = gfxPsD ? (cbD->currentGraphicsSrb != srb) : (cbD->currentComputeSrb != srb);
- const bool srbRebuilt = cbD->currentSrbGeneration != srbD->generation;
-
- if (srbChanged || srbRebuilt || srbD->hasDynamicOffset) {
+ if (srbChanged || cbD->currentSrbGeneration != srbD->generation || srbD->hasDynamicOffset) {
if (gfxPsD) {
cbD->currentGraphicsSrb = srb;
cbD->currentComputeSrb = nullptr;
@@ -1163,14 +1160,14 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
}
cbD->currentSrbGeneration = srbD->generation;
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::BindShaderResources;
cmd.args.bindShaderResources.maybeGraphicsPs = gfxPsD;
cmd.args.bindShaderResources.maybeComputePs = compPsD;
cmd.args.bindShaderResources.srb = srb;
cmd.args.bindShaderResources.dynamicOffsetCount = 0;
if (srbD->hasDynamicOffset) {
- if (dynamicOffsetCount < QGles2CommandBuffer::Command::MAX_DYNAMIC_OFFSET_COUNT) {
+ if (dynamicOffsetCount < QGles2CommandBuffer::MAX_DYNAMIC_OFFSET_COUNT) {
cmd.args.bindShaderResources.dynamicOffsetCount = dynamicOffsetCount;
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
for (int i = 0; i < dynamicOffsetCount; ++i) {
@@ -1180,10 +1177,9 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
}
} else {
qWarning("Too many dynamic offsets (%d, max is %d)",
- dynamicOffsetCount, QGles2CommandBuffer::Command::MAX_DYNAMIC_OFFSET_COUNT);
+ dynamicOffsetCount, QGles2CommandBuffer::MAX_DYNAMIC_OFFSET_COUNT);
}
}
- cbD->commands.append(cmd);
}
}
@@ -1201,13 +1197,12 @@ void QRhiGles2::setVertexInput(QRhiCommandBuffer *cb,
QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, buf);
Q_ASSERT(bufD->m_usage.testFlag(QRhiBuffer::VertexBuffer));
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::BindVertexBuffer;
cmd.args.bindVertexBuffer.ps = cbD->currentGraphicsPipeline;
cmd.args.bindVertexBuffer.buffer = bufD->buffer;
cmd.args.bindVertexBuffer.offset = ofs;
cmd.args.bindVertexBuffer.binding = startBinding + i;
- cbD->commands.append(cmd);
if (cbD->passNeedsResourceTracking) {
trackedRegisterBuffer(&passResTracker, bufD, QRhiPassResourceTracker::BufVertexInput,
@@ -1219,12 +1214,11 @@ void QRhiGles2::setVertexInput(QRhiCommandBuffer *cb,
QGles2Buffer *ibufD = QRHI_RES(QGles2Buffer, indexBuf);
Q_ASSERT(ibufD->m_usage.testFlag(QRhiBuffer::IndexBuffer));
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::BindIndexBuffer;
cmd.args.bindIndexBuffer.buffer = ibufD->buffer;
cmd.args.bindIndexBuffer.offset = indexOffset;
cmd.args.bindIndexBuffer.type = indexFormat == QRhiCommandBuffer::IndexUInt16 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
- cbD->commands.append(cmd);
if (cbD->passNeedsResourceTracking) {
trackedRegisterBuffer(&passResTracker, ibufD, QRhiPassResourceTracker::BufIndexRead,
@@ -1238,20 +1232,19 @@ void QRhiGles2::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport)
QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass);
- QGles2CommandBuffer::Command cmd;
- cmd.cmd = QGles2CommandBuffer::Command::Viewport;
const std::array<float, 4> r = viewport.viewport();
// A negative width or height is an error. A negative x or y is not.
if (r[2] < 0.0f || r[3] < 0.0f)
return;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
+ cmd.cmd = QGles2CommandBuffer::Command::Viewport;
cmd.args.viewport.x = r[0];
cmd.args.viewport.y = r[1];
cmd.args.viewport.w = r[2];
cmd.args.viewport.h = r[3];
cmd.args.viewport.d0 = viewport.minDepth();
cmd.args.viewport.d1 = viewport.maxDepth();
- cbD->commands.append(cmd);
}
void QRhiGles2::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
@@ -1259,18 +1252,17 @@ void QRhiGles2::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass);
- QGles2CommandBuffer::Command cmd;
- cmd.cmd = QGles2CommandBuffer::Command::Scissor;
const std::array<int, 4> r = scissor.scissor();
// A negative width or height is an error. A negative x or y is not.
if (r[2] < 0 || r[3] < 0)
return;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
+ cmd.cmd = QGles2CommandBuffer::Command::Scissor;
cmd.args.scissor.x = r[0];
cmd.args.scissor.y = r[1];
cmd.args.scissor.w = r[2];
cmd.args.scissor.h = r[3];
- cbD->commands.append(cmd);
}
void QRhiGles2::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
@@ -1278,13 +1270,12 @@ void QRhiGles2::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass);
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::BlendConstants;
cmd.args.blendConstants.r = float(c.redF());
cmd.args.blendConstants.g = float(c.greenF());
cmd.args.blendConstants.b = float(c.blueF());
cmd.args.blendConstants.a = float(c.alphaF());
- cbD->commands.append(cmd);
}
void QRhiGles2::setStencilRef(QRhiCommandBuffer *cb, quint32 refValue)
@@ -1292,11 +1283,10 @@ void QRhiGles2::setStencilRef(QRhiCommandBuffer *cb, quint32 refValue)
QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass);
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::StencilRef;
cmd.args.stencilRef.ref = refValue;
cmd.args.stencilRef.ps = cbD->currentGraphicsPipeline;
- cbD->commands.append(cmd);
}
void QRhiGles2::draw(QRhiCommandBuffer *cb, quint32 vertexCount,
@@ -1305,14 +1295,13 @@ void QRhiGles2::draw(QRhiCommandBuffer *cb, quint32 vertexCount,
QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass);
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::Draw;
cmd.args.draw.ps = cbD->currentGraphicsPipeline;
cmd.args.draw.vertexCount = vertexCount;
cmd.args.draw.firstVertex = firstVertex;
cmd.args.draw.instanceCount = instanceCount;
cmd.args.draw.baseInstance = firstInstance;
- cbD->commands.append(cmd);
}
void QRhiGles2::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
@@ -1321,7 +1310,7 @@ void QRhiGles2::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass);
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::DrawIndexed;
cmd.args.drawIndexed.ps = cbD->currentGraphicsPipeline;
cmd.args.drawIndexed.indexCount = indexCount;
@@ -1329,7 +1318,6 @@ void QRhiGles2::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
cmd.args.drawIndexed.instanceCount = instanceCount;
cmd.args.drawIndexed.baseInstance = firstInstance;
cmd.args.drawIndexed.baseVertex = vertexOffset;
- cbD->commands.append(cmd);
}
void QRhiGles2::debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name)
@@ -1364,11 +1352,10 @@ const QRhiNativeHandles *QRhiGles2::nativeHandles(QRhiCommandBuffer *cb)
return nullptr;
}
-static void addBoundaryCommand(QGles2CommandBuffer *cbD, QGles2CommandBuffer::Command::Cmd type)
+static inline void addBoundaryCommand(QGles2CommandBuffer *cbD, QGles2CommandBuffer::Command::Cmd type)
{
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = type;
- cbD->commands.append(cmd);
}
void QRhiGles2::beginExternal(QRhiCommandBuffer *cb)
@@ -1388,10 +1375,9 @@ void QRhiGles2::beginExternal(QRhiCommandBuffer *cb)
if (cbD->recordingPass == QGles2CommandBuffer::ComputePass
&& !cbD->computePassState.writtenResources.isEmpty())
{
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::Barrier;
cmd.args.barrier.barriers = GL_ALL_BARRIER_BITS;
- cbD->commands.append(cmd);
}
executeCommandBuffer(cbD);
@@ -1551,10 +1537,9 @@ void QRhiGles2::trackedBufferBarrier(QGles2CommandBuffer *cbD, QGles2Buffer *buf
// correctly (prevAccess is overwritten so we won't have proper
// tracking across multiple passes) so setting all barrier bits will do
// for now.
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::Barrier;
cmd.args.barrier.barriers = GL_ALL_BARRIER_BITS;
- cbD->commands.append(cmd);
}
bufD->usageState.access = access;
@@ -1568,10 +1553,9 @@ void QRhiGles2::trackedImageBarrier(QGles2CommandBuffer *cbD, QGles2Texture *tex
return;
if (textureAccessIsWrite(prevAccess)) {
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::Barrier;
cmd.args.barrier.barriers = GL_ALL_BARRIER_BITS;
- cbD->commands.append(cmd);
}
texD->usageState.access = access;
@@ -1589,7 +1573,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
if (!subresDesc.image().isNull()) {
QImage img = subresDesc.image();
QSize size = img.size();
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::SubImage;
if (!subresDesc.sourceSize().isEmpty() || !subresDesc.sourceTopLeft().isNull()) {
const QPoint sp = subresDesc.sourceTopLeft();
@@ -1609,14 +1593,13 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
cmd.args.subImage.gltype = texD->gltype;
cmd.args.subImage.rowStartAlign = 4;
cmd.args.subImage.data = cbD->retainImage(img);
- cbD->commands.append(cmd);
} else if (!rawData.isEmpty() && isCompressed) {
if (!texD->compressedAtlasBuilt && (texD->flags() & QRhiTexture::UsedAsCompressedAtlas)) {
// Create on first upload since glCompressedTexImage2D cannot take nullptr data
quint32 byteSize = 0;
compressedFormatInfo(texD->m_format, texD->m_pixelSize, nullptr, &byteSize, nullptr);
QByteArray zeroBuf(byteSize, 0);
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::CompressedImage;
cmd.args.compressedImage.target = texD->target;
cmd.args.compressedImage.texture = texD->texture;
@@ -1627,14 +1610,13 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
cmd.args.compressedImage.h = texD->m_pixelSize.height();
cmd.args.compressedImage.size = byteSize;
cmd.args.compressedImage.data = cbD->retainData(zeroBuf);
- cbD->commands.append(cmd);
texD->compressedAtlasBuilt = true;
}
const QSize size = subresDesc.sourceSize().isEmpty() ? q->sizeForMipLevel(level, texD->m_pixelSize)
: subresDesc.sourceSize();
if (texD->specified || texD->compressedAtlasBuilt) {
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::CompressedSubImage;
cmd.args.compressedSubImage.target = texD->target;
cmd.args.compressedSubImage.texture = texD->texture;
@@ -1647,9 +1629,8 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
cmd.args.compressedSubImage.glintformat = texD->glintformat;
cmd.args.compressedSubImage.size = rawData.size();
cmd.args.compressedSubImage.data = cbD->retainData(rawData);
- cbD->commands.append(cmd);
} else {
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::CompressedImage;
cmd.args.compressedImage.target = texD->target;
cmd.args.compressedImage.texture = texD->texture;
@@ -1660,14 +1641,13 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
cmd.args.compressedImage.h = size.height();
cmd.args.compressedImage.size = rawData.size();
cmd.args.compressedImage.data = cbD->retainData(rawData);
- cbD->commands.append(cmd);
}
} else if (!rawData.isEmpty()) {
const QSize size = subresDesc.sourceSize().isEmpty() ? q->sizeForMipLevel(level, texD->m_pixelSize)
: subresDesc.sourceSize();
quint32 bpl = 0;
textureFormatInfo(texD->m_format, size, &bpl, nullptr);
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::SubImage;
cmd.args.subImage.target = texD->target;
cmd.args.subImage.texture = texD->texture;
@@ -1684,7 +1664,6 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
// row starts, but our raw data here does not.
cmd.args.subImage.rowStartAlign = (bpl & 3) ? 1 : 4;
cmd.args.subImage.data = cbD->retainData(rawData);
- cbD->commands.append(cmd);
} else {
qWarning("Invalid texture upload for %p layer=%d mip=%d", texD, layer, level);
}
@@ -1704,14 +1683,13 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
memcpy(bufD->data + u.offset, u.data.constData(), size_t(u.data.size()));
} else {
trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::BufferSubData;
cmd.args.bufferSubData.target = bufD->targetForDataOps;
cmd.args.bufferSubData.buffer = bufD->buffer;
cmd.args.bufferSubData.offset = u.offset;
cmd.args.bufferSubData.size = u.data.size();
cmd.args.bufferSubData.data = cbD->retainBufferData(u.data);
- cbD->commands.append(cmd);
}
} else if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::StaticUpload) {
QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, u.buf);
@@ -1721,14 +1699,13 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
memcpy(bufD->data + u.offset, u.data.constData(), size_t(u.data.size()));
} else {
trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::BufferSubData;
cmd.args.bufferSubData.target = bufD->targetForDataOps;
cmd.args.bufferSubData.buffer = bufD->buffer;
cmd.args.bufferSubData.offset = u.offset;
cmd.args.bufferSubData.size = u.data.size();
cmd.args.bufferSubData.data = cbD->retainBufferData(u.data);
- cbD->commands.append(cmd);
}
} else if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::Read) {
QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, u.buf);
@@ -1738,14 +1715,13 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
if (u.result->completed)
u.result->completed();
} else {
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::GetBufferSubData;
cmd.args.getBufferSubData.result = u.result;
cmd.args.getBufferSubData.target = bufD->targetForDataOps;
cmd.args.getBufferSubData.buffer = bufD->buffer;
cmd.args.getBufferSubData.offset = u.offset;
cmd.args.getBufferSubData.size = u.readSize;
- cbD->commands.append(cmd);
}
}
}
@@ -1780,7 +1756,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
const GLenum dstFaceTargetBase = dstD->m_flags.testFlag(QRhiTexture::CubeMap)
? GL_TEXTURE_CUBE_MAP_POSITIVE_X : dstD->target;
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::CopyTex;
cmd.args.copyTex.srcFaceTarget = srcFaceTargetBase + uint(u.desc.sourceLayer());
@@ -1798,10 +1774,8 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cmd.args.copyTex.w = copySize.width();
cmd.args.copyTex.h = copySize.height();
-
- cbD->commands.append(cmd);
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Read) {
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::ReadPixels;
cmd.args.readPixels.result = u.result;
QGles2Texture *texD = QRHI_RES(QGles2Texture, u.rb.texture());
@@ -1818,15 +1792,13 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cmd.args.readPixels.readTarget = faceTargetBase + uint(u.rb.layer());
cmd.args.readPixels.level = u.rb.level();
}
- cbD->commands.append(cmd);
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::GenMips) {
QGles2Texture *texD = QRHI_RES(QGles2Texture, u.dst);
trackedImageBarrier(cbD, texD, QGles2Texture::AccessFramebuffer);
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::GenMip;
cmd.args.genMip.target = texD->target;
cmd.args.genMip.texture = texD->texture;
- cbD->commands.append(cmd);
}
}
@@ -2166,7 +2138,8 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
bool enabledAttribArrays[TRACKED_ATTRIB_COUNT];
memset(enabledAttribArrays, 0, sizeof(enabledAttribArrays));
- for (const QGles2CommandBuffer::Command &cmd : qAsConst(cbD->commands)) {
+ for (auto it = cbD->commands.cbegin(), end = cbD->commands.cend(); it != end; ++it) {
+ const QGles2CommandBuffer::Command &cmd(*it);
switch (cmd.cmd) {
case QGles2CommandBuffer::Command::BeginFrame:
if (caps.coreProfile) {
@@ -3194,7 +3167,7 @@ QGles2RenderTargetData *QRhiGles2::enqueueBindFramebuffer(QRhiRenderTarget *rt,
QGles2RenderTargetData *rtD = nullptr;
QRhiPassResourceTracker &passResTracker(cbD->passResTrackers[cbD->currentPassResTrackerIndex]);
- QGles2CommandBuffer::Command fbCmd;
+ QGles2CommandBuffer::Command &fbCmd(cbD->commands.get());
fbCmd.cmd = QGles2CommandBuffer::Command::BindFramebuffer;
switch (rt->resourceType()) {
@@ -3250,7 +3223,6 @@ QGles2RenderTargetData *QRhiGles2::enqueueBindFramebuffer(QRhiRenderTarget *rt,
}
fbCmd.args.bindFramebuffer.srgb = rtD->srgbUpdateAndBlend;
- cbD->commands.append(fbCmd);
return rtD;
}
@@ -3259,10 +3231,9 @@ void QRhiGles2::enqueueBarriersForPass(QGles2CommandBuffer *cbD)
{
cbD->passResTrackers.append(QRhiPassResourceTracker());
cbD->currentPassResTrackerIndex = cbD->passResTrackers.count() - 1;
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::BarriersForPass;
cmd.args.barriersForPass.trackerIndex = cbD->currentPassResTrackerIndex;
- cbD->commands.append(cmd);
}
void QRhiGles2::beginPass(QRhiCommandBuffer *cb,
@@ -3285,7 +3256,7 @@ void QRhiGles2::beginPass(QRhiCommandBuffer *cb,
bool wantsColorClear, wantsDsClear;
QGles2RenderTargetData *rtD = enqueueBindFramebuffer(rt, cbD, &wantsColorClear, &wantsDsClear);
- QGles2CommandBuffer::Command clearCmd;
+ QGles2CommandBuffer::Command &clearCmd(cbD->commands.get());
clearCmd.cmd = QGles2CommandBuffer::Command::Clear;
clearCmd.args.clear.mask = 0;
if (rtD->colorAttCount && wantsColorClear)
@@ -3298,7 +3269,6 @@ void QRhiGles2::beginPass(QRhiCommandBuffer *cb,
clearCmd.args.clear.c[3] = float(colorClearValue.alphaF());
clearCmd.args.clear.d = depthStencilClearValue.depthClearValue();
clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue();
- cbD->commands.append(clearCmd);
cbD->recordingPass = QGles2CommandBuffer::RenderPass;
cbD->passNeedsResourceTracking = !flags.testFlag(QRhiCommandBuffer::DoNotTrackResourcesForCompute);
@@ -3325,7 +3295,7 @@ void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
qWarning("Resolve source (%dx%d) and target (%dx%d) size does not match",
rbD->pixelSize().width(), rbD->pixelSize().height(), size.width(), size.height());
}
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::BlitFromRenderbuffer;
cmd.args.blitFromRb.renderbuffer = rbD->renderbuffer;
cmd.args.blitFromRb.w = size.width();
@@ -3336,7 +3306,6 @@ void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
cmd.args.blitFromRb.target = faceTargetBase + uint(colorAtt.resolveLayer());
cmd.args.blitFromRb.texture = colorTexD->texture;
cmd.args.blitFromRb.dstLevel = colorAtt.resolveLevel();
- cbD->commands.append(cmd);
}
}
}
@@ -3388,10 +3357,9 @@ void QRhiGles2::setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *p
cbD->currentComputePipeline = ps;
cbD->currentPipelineGeneration = psD->generation;
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::BindComputePipeline;
cmd.args.bindComputePipeline.ps = ps;
- cbD->commands.append(cmd);
}
}
@@ -3478,19 +3446,17 @@ void QRhiGles2::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
}
if (barriers) {
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::Barrier;
cmd.args.barrier.barriers = barriers;
- cbD->commands.append(cmd);
}
}
- QGles2CommandBuffer::Command cmd;
+ QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::Dispatch;
cmd.args.dispatch.x = GLuint(x);
cmd.args.dispatch.y = GLuint(y);
cmd.args.dispatch.z = GLuint(z);
- cbD->commands.append(cmd);
}
static inline GLenum toGlShaderType(QRhiShaderStage::Type type)
diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h
index 6ce3786445..a231740c66 100644
--- a/src/gui/rhi/qrhigles2_p_p.h
+++ b/src/gui/rhi/qrhigles2_p_p.h
@@ -315,6 +315,9 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer
~QGles2CommandBuffer();
void destroy() override;
+ // keep at a reasonably low value otherwise sizeof Command explodes
+ static const int MAX_DYNAMIC_OFFSET_COUNT = 8;
+
struct Command {
enum Cmd {
BeginFrame,
@@ -348,12 +351,9 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer
};
Cmd cmd;
- // keep at a reasonably low value otherwise sizeof Command explodes
- static const int MAX_DYNAMIC_OFFSET_COUNT = 8;
-
// QRhi*/QGles2* references should be kept at minimum (so no
// QRhiTexture/Buffer/etc. pointers).
- union {
+ union Args {
struct {
float x, y, w, h;
float d0, d1;
@@ -526,7 +526,7 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer
ComputePass
};
- QVarLengthArray<Command, 1024> commands;
+ QRhiBackendCommandList<Command> commands;
QVarLengthArray<QRhiPassResourceTracker, 8> passResTrackers;
int currentPassResTrackerIndex;
@@ -614,7 +614,7 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer
return imageRetainPool.last().constBits();
}
void resetCommands() {
- commands.clear();
+ commands.reset();
dataRetainPool.clear();
bufferDataRetainPool.clear();
imageRetainPool.clear();
@@ -642,8 +642,6 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer
}
};
-Q_DECLARE_TYPEINFO(QGles2CommandBuffer::Command, Q_MOVABLE_TYPE);
-
inline bool operator==(const QGles2CommandBuffer::GraphicsPassState::StencilFace &a,
const QGles2CommandBuffer::GraphicsPassState::StencilFace &b)
{
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index fc539c03a9..f867781d8b 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -2204,10 +2204,9 @@ void QRhiVulkan::endAndEnqueueSecondaryCommandBuffer(VkCommandBuffer cb, QVkComm
if (err != VK_SUCCESS)
qWarning("Failed to end secondary command buffer: %d", err);
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::ExecuteSecondary;
cmd.args.executeSecondary.cb = cb;
- cbD->commands.append(cmd);
QRhiVulkan::DeferredReleaseEntry e;
e.type = QRhiVulkan::DeferredReleaseEntry::SecondaryCommandBuffer;
@@ -2291,13 +2290,12 @@ void QRhiVulkan::beginPass(QRhiCommandBuffer *cb,
}
rpBeginInfo.clearValueCount = uint32_t(cvs.count());
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::BeginRenderPass;
cmd.args.beginRenderPass.desc = rpBeginInfo;
cmd.args.beginRenderPass.clearValueIndex = cbD->pools.clearValue.count();
cmd.args.beginRenderPass.useSecondaryCb = cbD->passUsesSecondaryCb;
cbD->pools.clearValue.append(cvs.constData(), cvs.count());
- cbD->commands.append(cmd);
if (cbD->passUsesSecondaryCb)
cbD->activeSecondaryCbStack.append(startSecondaryCommandBuffer(rtD));
@@ -2315,9 +2313,8 @@ void QRhiVulkan::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourc
cbD->resetCachedState();
}
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::EndRenderPass;
- cbD->commands.append(cmd);
cbD->recordingPass = QVkCommandBuffer::NoPass;
cbD->currentTarget = nullptr;
@@ -2376,11 +2373,10 @@ void QRhiVulkan::setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *
if (cbD->passUsesSecondaryCb) {
df->vkCmdBindPipeline(cbD->activeSecondaryCbStack.last(), VK_PIPELINE_BIND_POINT_COMPUTE, psD->pipeline);
} else {
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::BindPipeline;
cmd.args.bindPipeline.bindPoint = VK_PIPELINE_BIND_POINT_COMPUTE;
cmd.args.bindPipeline.pipeline = psD->pipeline;
- cbD->commands.append(cmd);
}
cbD->currentGraphicsPipeline = nullptr;
@@ -2518,30 +2514,29 @@ void QRhiVulkan::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
}
df->vkCmdDispatch(secondaryCb, uint32_t(x), uint32_t(y), uint32_t(z));
} else {
- QVkCommandBuffer::Command cmd;
if (!imageBarriers.isEmpty()) {
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::ImageBarrier;
cmd.args.imageBarrier.srcStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
cmd.args.imageBarrier.dstStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
cmd.args.imageBarrier.count = imageBarriers.count();
cmd.args.imageBarrier.index = cbD->pools.imageBarrier.count();
cbD->pools.imageBarrier.append(imageBarriers.constData(), imageBarriers.count());
- cbD->commands.append(cmd);
}
if (!bufferBarriers.isEmpty()) {
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::BufferBarrier;
cmd.args.bufferBarrier.srcStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
cmd.args.bufferBarrier.dstStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
cmd.args.bufferBarrier.count = bufferBarriers.count();
cmd.args.bufferBarrier.index = cbD->pools.bufferBarrier.count();
cbD->pools.bufferBarrier.append(bufferBarriers.constData(), bufferBarriers.count());
- cbD->commands.append(cmd);
}
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::Dispatch;
cmd.args.dispatch.x = x;
cmd.args.dispatch.y = y;
cmd.args.dispatch.z = z;
- cbD->commands.append(cmd);
}
}
@@ -2741,14 +2736,13 @@ void QRhiVulkan::trackedBufferBarrier(QVkCommandBuffer *cbD, QVkBuffer *bufD, in
bufMemBarrier.buffer = bufD->buffers[slot];
bufMemBarrier.size = VK_WHOLE_SIZE;
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::BufferBarrier;
cmd.args.bufferBarrier.srcStageMask = s.stage;
cmd.args.bufferBarrier.dstStageMask = stage;
cmd.args.bufferBarrier.count = 1;
cmd.args.bufferBarrier.index = cbD->pools.bufferBarrier.count();
cbD->pools.bufferBarrier.append(bufMemBarrier);
- cbD->commands.append(cmd);
s.access = access;
s.stage = stage;
@@ -2784,14 +2778,13 @@ void QRhiVulkan::trackedImageBarrier(QVkCommandBuffer *cbD, QVkTexture *texD,
if (!srcStage)
srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::ImageBarrier;
cmd.args.imageBarrier.srcStageMask = srcStage;
cmd.args.imageBarrier.dstStageMask = stage;
cmd.args.imageBarrier.count = 1;
cmd.args.imageBarrier.index = cbD->pools.imageBarrier.count();
cbD->pools.imageBarrier.append(barrier);
- cbD->commands.append(cmd);
s.layout = layout;
s.access = access;
@@ -2820,14 +2813,13 @@ void QRhiVulkan::subresourceBarrier(QVkCommandBuffer *cbD, VkImage image,
barrier.dstAccessMask = dstAccess;
barrier.image = image;
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::ImageBarrier;
cmd.args.imageBarrier.srcStageMask = srcStage;
cmd.args.imageBarrier.dstStageMask = dstStage;
cmd.args.imageBarrier.count = 1;
cmd.args.imageBarrier.index = cbD->pools.imageBarrier.count();
cbD->pools.imageBarrier.append(barrier);
- cbD->commands.append(cmd);
}
VkDeviceSize QRhiVulkan::subresUploadByteSize(const QRhiTextureSubresourceUploadDescription &subresDesc) const
@@ -3000,12 +2992,11 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
copyInfo.dstOffset = VkDeviceSize(u.offset);
copyInfo.size = VkDeviceSize(u.data.size());
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::CopyBuffer;
cmd.args.copyBuffer.src = bufD->stagingBuffers[currentFrameSlot];
cmd.args.copyBuffer.dst = bufD->buffers[0];
cmd.args.copyBuffer.desc = copyInfo;
- cbD->commands.append(cmd);
// Where's the barrier for read-after-write? (assuming the common case
// of binding this buffer as vertex/index, or, less likely, as uniform
@@ -3080,12 +3071,11 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
copyInfo.srcOffset = VkDeviceSize(u.offset);
copyInfo.size = VkDeviceSize(u.readSize);
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::CopyBuffer;
cmd.args.copyBuffer.src = bufD->buffers[0];
cmd.args.copyBuffer.dst = readback.stagingBuf;
cmd.args.copyBuffer.desc = copyInfo;
- cbD->commands.append(cmd);
bufD->lastActiveFrameSlot = currentFrameSlot;
@@ -3155,7 +3145,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
trackedImageBarrier(cbD, utexD, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::CopyBufferToImage;
cmd.args.copyBufferToImage.src = utexD->stagingBuffers[currentFrameSlot];
cmd.args.copyBufferToImage.dst = utexD->image;
@@ -3163,7 +3153,6 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
cmd.args.copyBufferToImage.count = copyInfos.count();
cmd.args.copyBufferToImage.bufferImageCopyIndex = cbD->pools.bufferImageCopy.count();
cbD->pools.bufferImageCopy.append(copyInfos.constData(), copyInfos.count());
- cbD->commands.append(cmd);
// no reuse of staging, this is intentional
QRhiVulkan::DeferredReleaseEntry e;
@@ -3219,14 +3208,13 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
trackedImageBarrier(cbD, dstD, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::CopyImage;
cmd.args.copyImage.src = srcD->image;
cmd.args.copyImage.srcLayout = srcD->usageState.layout;
cmd.args.copyImage.dst = dstD->image;
cmd.args.copyImage.dstLayout = dstD->usageState.layout;
cmd.args.copyImage.desc = region;
- cbD->commands.append(cmd);
srcD->lastActiveFrameSlot = dstD->lastActiveFrameSlot = currentFrameSlot;
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Read) {
@@ -3300,13 +3288,12 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
if (texD) {
trackedImageBarrier(cbD, texD, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::CopyImageToBuffer;
cmd.args.copyImageToBuffer.src = texD->image;
cmd.args.copyImageToBuffer.srcLayout = texD->usageState.layout;
cmd.args.copyImageToBuffer.dst = readback.stagingBuf;
cmd.args.copyImageToBuffer.desc = copyDesc;
- cbD->commands.append(cmd);
} else {
// use the swapchain image
QVkSwapChain::ImageResources &imageRes(swapChainD->imageRes[swapChainD->currentImageIndex]);
@@ -3325,13 +3312,12 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
imageRes.lastUse = QVkSwapChain::ImageResources::ScImageUseTransferSource;
}
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::CopyImageToBuffer;
cmd.args.copyImageToBuffer.src = image;
cmd.args.copyImageToBuffer.srcLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
cmd.args.copyImageToBuffer.dst = readback.stagingBuf;
cmd.args.copyImageToBuffer.desc = copyDesc;
- cbD->commands.append(cmd);
}
activeTextureReadbacks.append(readback);
@@ -3394,7 +3380,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
region.dstOffsets[1].y = qMax(1, h >> 1);
region.dstOffsets[1].z = 1;
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::BlitImage;
cmd.args.blitImage.src = utexD->image;
cmd.args.blitImage.srcLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
@@ -3402,7 +3388,6 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
cmd.args.blitImage.dstLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
cmd.args.blitImage.filter = VK_FILTER_LINEAR;
cmd.args.blitImage.desc = region;
- cbD->commands.append(cmd);
w >>= 1;
h >>= 1;
@@ -3665,17 +3650,17 @@ void QRhiVulkan::enqueueTransitionPassResources(QVkCommandBuffer *cbD)
cbD->passResTrackers.append(QRhiPassResourceTracker());
cbD->currentPassResTrackerIndex = cbD->passResTrackers.count() - 1;
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::TransitionPassResources;
cmd.args.transitionResources.trackerIndex = cbD->passResTrackers.count() - 1;
- cbD->commands.append(cmd);
}
void QRhiVulkan::recordPrimaryCommandBuffer(QVkCommandBuffer *cbD)
{
Q_ASSERT(cbD->recordingPass == QVkCommandBuffer::NoPass);
- for (QVkCommandBuffer::Command &cmd : cbD->commands) {
+ for (auto it = cbD->commands.begin(), end = cbD->commands.end(); it != end; ++it) {
+ QVkCommandBuffer::Command &cmd(*it);
switch (cmd.cmd) {
case QVkCommandBuffer::Command::CopyBuffer:
df->vkCmdCopyBuffer(cbD->cb, cmd.args.copyBuffer.src, cmd.args.copyBuffer.dst,
@@ -4264,11 +4249,10 @@ void QRhiVulkan::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
if (cbD->passUsesSecondaryCb) {
df->vkCmdBindPipeline(cbD->activeSecondaryCbStack.last(), VK_PIPELINE_BIND_POINT_GRAPHICS, psD->pipeline);
} else {
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::BindPipeline;
cmd.args.bindPipeline.bindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
cmd.args.bindPipeline.pipeline = psD->pipeline;
- cbD->commands.append(cmd);
}
cbD->currentGraphicsPipeline = ps;
@@ -4461,7 +4445,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin
uint32_t(dynOfs.count()),
dynOfs.count() ? dynOfs.constData() : nullptr);
} else {
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::BindDescriptorSet;
cmd.args.bindDescriptorSet.bindPoint = gfxPsD ? VK_PIPELINE_BIND_POINT_GRAPHICS
: VK_PIPELINE_BIND_POINT_COMPUTE;
@@ -4470,7 +4454,6 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin
cmd.args.bindDescriptorSet.dynamicOffsetCount = dynOfs.count();
cmd.args.bindDescriptorSet.dynamicOffsetIndex = cbD->pools.dynamicOffset.count();
cbD->pools.dynamicOffset.append(dynOfs.constData(), dynOfs.count());
- cbD->commands.append(cmd);
}
if (gfxPsD) {
@@ -4531,7 +4514,7 @@ void QRhiVulkan::setVertexInput(QRhiCommandBuffer *cb,
df->vkCmdBindVertexBuffers(cbD->activeSecondaryCbStack.last(), uint32_t(startBinding),
uint32_t(bufs.count()), bufs.constData(), ofs.constData());
} else {
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::BindVertexBuffer;
cmd.args.bindVertexBuffer.startBinding = startBinding;
cmd.args.bindVertexBuffer.count = bufs.count();
@@ -4539,7 +4522,6 @@ void QRhiVulkan::setVertexInput(QRhiCommandBuffer *cb,
cbD->pools.vertexBuffer.append(bufs.constData(), bufs.count());
cmd.args.bindVertexBuffer.vertexBufferOffsetIndex = cbD->pools.vertexBufferOffset.count();
cbD->pools.vertexBufferOffset.append(ofs.constData(), ofs.count());
- cbD->commands.append(cmd);
}
}
@@ -4566,12 +4548,11 @@ void QRhiVulkan::setVertexInput(QRhiCommandBuffer *cb,
if (cbD->passUsesSecondaryCb) {
df->vkCmdBindIndexBuffer(cbD->activeSecondaryCbStack.last(), vkindexbuf, indexOffset, type);
} else {
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::BindIndexBuffer;
cmd.args.bindIndexBuffer.buf = vkindexbuf;
cmd.args.bindIndexBuffer.ofs = indexOffset;
cmd.args.bindIndexBuffer.type = type;
- cbD->commands.append(cmd);
}
trackedRegisterBuffer(&passResTracker, ibufD, slot,
@@ -4592,7 +4573,7 @@ void QRhiVulkan::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport
if (!qrhi_toTopLeftRenderTargetRect(outputSize, viewport.viewport(), &x, &y, &w, &h))
return;
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
VkViewport *vp = &cmd.args.setViewport.viewport;
vp->x = x;
vp->y = y;
@@ -4603,12 +4584,13 @@ void QRhiVulkan::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport
if (cbD->passUsesSecondaryCb) {
df->vkCmdSetViewport(cbD->activeSecondaryCbStack.last(), 0, 1, vp);
+ cbD->commands.unget();
} else {
cmd.cmd = QVkCommandBuffer::Command::SetViewport;
- cbD->commands.append(cmd);
}
if (!QRHI_RES(QVkGraphicsPipeline, cbD->currentGraphicsPipeline)->m_flags.testFlag(QRhiGraphicsPipeline::UsesScissor)) {
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
VkRect2D *s = &cmd.args.setScissor.scissor;
s->offset.x = int32_t(x);
s->offset.y = int32_t(y);
@@ -4616,9 +4598,9 @@ void QRhiVulkan::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport
s->extent.height = uint32_t(h);
if (cbD->passUsesSecondaryCb) {
df->vkCmdSetScissor(cbD->activeSecondaryCbStack.last(), 0, 1, s);
+ cbD->commands.unget();
} else {
cmd.cmd = QVkCommandBuffer::Command::SetScissor;
- cbD->commands.append(cmd);
}
}
}
@@ -4635,7 +4617,7 @@ void QRhiVulkan::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
if (!qrhi_toTopLeftRenderTargetRect(outputSize, scissor.scissor(), &x, &y, &w, &h))
return;
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
VkRect2D *s = &cmd.args.setScissor.scissor;
s->offset.x = x;
s->offset.y = y;
@@ -4644,9 +4626,9 @@ void QRhiVulkan::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
if (cbD->passUsesSecondaryCb) {
df->vkCmdSetScissor(cbD->activeSecondaryCbStack.last(), 0, 1, s);
+ cbD->commands.unget();
} else {
cmd.cmd = QVkCommandBuffer::Command::SetScissor;
- cbD->commands.append(cmd);
}
}
@@ -4659,13 +4641,12 @@ void QRhiVulkan::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
float constants[] = { float(c.redF()), float(c.greenF()), float(c.blueF()), float(c.alphaF()) };
df->vkCmdSetBlendConstants(cbD->activeSecondaryCbStack.last(), constants);
} else {
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::SetBlendConstants;
cmd.args.setBlendConstants.c[0] = float(c.redF());
cmd.args.setBlendConstants.c[1] = float(c.greenF());
cmd.args.setBlendConstants.c[2] = float(c.blueF());
cmd.args.setBlendConstants.c[3] = float(c.alphaF());
- cbD->commands.append(cmd);
}
}
@@ -4677,10 +4658,9 @@ void QRhiVulkan::setStencilRef(QRhiCommandBuffer *cb, quint32 refValue)
if (cbD->passUsesSecondaryCb) {
df->vkCmdSetStencilReference(cbD->activeSecondaryCbStack.last(), VK_STENCIL_FRONT_AND_BACK, refValue);
} else {
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::SetStencilRef;
cmd.args.setStencilRef.ref = refValue;
- cbD->commands.append(cmd);
}
}
@@ -4693,13 +4673,12 @@ void QRhiVulkan::draw(QRhiCommandBuffer *cb, quint32 vertexCount,
if (cbD->passUsesSecondaryCb) {
df->vkCmdDraw(cbD->activeSecondaryCbStack.last(), vertexCount, instanceCount, firstVertex, firstInstance);
} else {
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::Draw;
cmd.args.draw.vertexCount = vertexCount;
cmd.args.draw.instanceCount = instanceCount;
cmd.args.draw.firstVertex = firstVertex;
cmd.args.draw.firstInstance = firstInstance;
- cbD->commands.append(cmd);
}
}
@@ -4713,14 +4692,13 @@ void QRhiVulkan::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
df->vkCmdDrawIndexed(cbD->activeSecondaryCbStack.last(), indexCount, instanceCount,
firstIndex, vertexOffset, firstInstance);
} else {
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::DrawIndexed;
cmd.args.drawIndexed.indexCount = indexCount;
cmd.args.drawIndexed.instanceCount = instanceCount;
cmd.args.drawIndexed.firstIndex = firstIndex;
cmd.args.drawIndexed.vertexOffset = vertexOffset;
cmd.args.drawIndexed.firstInstance = firstInstance;
- cbD->commands.append(cmd);
}
}
@@ -4738,12 +4716,11 @@ void QRhiVulkan::debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name)
marker.pMarkerName = name.constData();
vkCmdDebugMarkerBegin(cbD->activeSecondaryCbStack.last(), &marker);
} else {
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::DebugMarkerBegin;
cmd.args.debugMarkerBegin.marker = marker;
cmd.args.debugMarkerBegin.markerNameIndex = cbD->pools.debugMarkerData.count();
cbD->pools.debugMarkerData.append(name);
- cbD->commands.append(cmd);
}
}
@@ -4756,9 +4733,8 @@ void QRhiVulkan::debugMarkEnd(QRhiCommandBuffer *cb)
if (cbD->recordingPass != QVkCommandBuffer::NoPass && cbD->passUsesSecondaryCb) {
vkCmdDebugMarkerEnd(cbD->activeSecondaryCbStack.last());
} else {
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::DebugMarkerEnd;
- cbD->commands.append(cmd);
}
}
@@ -4776,12 +4752,11 @@ void QRhiVulkan::debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg)
marker.pMarkerName = msg.constData();
vkCmdDebugMarkerInsert(cbD->activeSecondaryCbStack.last(), &marker);
} else {
- QVkCommandBuffer::Command cmd;
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QVkCommandBuffer::Command::DebugMarkerInsert;
cmd.args.debugMarkerInsert.marker = marker;
cmd.args.debugMarkerInsert.markerNameIndex = cbD->pools.debugMarkerData.count();
cbD->pools.debugMarkerData.append(msg);
- cbD->commands.append(cmd);
}
}
diff --git a/src/gui/rhi/qrhivulkan_p_p.h b/src/gui/rhi/qrhivulkan_p_p.h
index 5819e303c3..d3f42957b1 100644
--- a/src/gui/rhi/qrhivulkan_p_p.h
+++ b/src/gui/rhi/qrhivulkan_p_p.h
@@ -543,12 +543,13 @@ struct QVkCommandBuffer : public QRhiCommandBuffer
} executeSecondary;
} args;
};
- QVarLengthArray<Command, 1024> commands;
+
+ QRhiBackendCommandList<Command> commands;
QVarLengthArray<QRhiPassResourceTracker, 8> passResTrackers;
int currentPassResTrackerIndex;
void resetCommands() {
- commands.clear();
+ commands.reset();
resetPools();
passResTrackers.clear();
@@ -580,8 +581,6 @@ struct QVkCommandBuffer : public QRhiCommandBuffer
friend class QRhiVulkan;
};
-Q_DECLARE_TYPEINFO(QVkCommandBuffer::Command, Q_MOVABLE_TYPE);
-
struct QVkSwapChain : public QRhiSwapChain
{
QVkSwapChain(QRhiImplementation *rhi);