rhi: Further reduce copying in the command buffer
Change-Id: I2e2ff5f4b8aa91d0accb01108a5199b98c371455 Reviewed-by: Christian Strømme <christian.stromme@qt.io>
This commit is contained in:
parent
802d98d318
commit
0461c535fc
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user