From f1c7814a55903dad5a5e77683bdcca5fc3805394 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 2 Oct 2019 10:58:44 +0200 Subject: [PATCH] rhi: Remove QVectors from the data description structs as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As usual, keep some QVector overloads around to allow Qt Quick to compile. Color attachments and vertex input bindings get an at(index) type of accessor, unlike any other of similar lists. This is because there the index is significant, and sequential iteration is not the only type of operation that is performed. Sometimes a lookup based on an index will be needed as well. Task-number: QTBUG-78883 Change-Id: I3882941f09e94ee2f179e0e9b8161551f0d5dae7 Reviewed-by: Christian Strømme Reviewed-by: Paul Olav Tvete --- src/gui/rhi/qrhi.cpp | 38 +++---- src/gui/rhi/qrhi_p.h | 72 +++++++++--- src/gui/rhi/qrhi_p_p.h | 5 +- src/gui/rhi/qrhid3d11.cpp | 69 ++++++------ src/gui/rhi/qrhigles2.cpp | 69 ++++++------ src/gui/rhi/qrhimetal.mm | 86 ++++++++------- src/gui/rhi/qrhinull.cpp | 7 +- src/gui/rhi/qrhivulkan.cpp | 103 +++++++++--------- src/gui/rhi/qrhivulkan_p_p.h | 3 +- .../compressedtexture_bc1.cpp | 6 +- tests/manual/rhi/mrt/mrt.cpp | 6 +- .../rhi/triquadcube/texturedcuberenderer.cpp | 8 +- 12 files changed, 265 insertions(+), 207 deletions(-) diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index 08bafebdec..e4f6da6d46 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -1199,8 +1199,7 @@ QDebug operator<<(QDebug dbg, const QRhiVertexInputAttribute &a) */ bool operator==(const QRhiVertexInputLayout &a, const QRhiVertexInputLayout &b) Q_DECL_NOTHROW { - return a.bindings() == b.bindings() - && a.attributes() == b.attributes(); + return a.m_bindings == b.m_bindings && a.m_attributes == b.m_attributes; } /*! @@ -1221,15 +1220,21 @@ bool operator!=(const QRhiVertexInputLayout &a, const QRhiVertexInputLayout &b) */ uint qHash(const QRhiVertexInputLayout &v, uint seed) Q_DECL_NOTHROW { - return qHash(v.bindings(), seed) + qHash(v.attributes(), seed); + return qHash(v.m_bindings, seed) + qHash(v.m_attributes, seed); } #ifndef QT_NO_DEBUG_STREAM +template +QDebug operator<<(QDebug dbg, const QVarLengthArray &vla) +{ + return QtPrivate::printSequentialContainer(dbg, "VLA", vla); +} + QDebug operator<<(QDebug dbg, const QRhiVertexInputLayout &v) { QDebugStateSaver saver(dbg); - dbg.nospace() << "QRhiVertexInputLayout(bindings=" << v.bindings() - << " attributes=" << v.attributes() + dbg.nospace() << "QRhiVertexInputLayout(bindings=" << v.m_bindings + << " attributes=" << v.m_attributes << ')'; return dbg; } @@ -1630,27 +1635,19 @@ QRhiTextureUploadDescription::QRhiTextureUploadDescription(const QRhiTextureUplo } /*! - Constructs a texture upload description with the specified list of \a entries. + Constructs a texture upload description with the specified \a list of entries. - \note \a entries can also contain multiple QRhiTextureUploadEntry elements + \note \a list can also contain multiple QRhiTextureUploadEntry elements with the the same layer and level. This makes sense when those uploads are partial, meaning their subresource description has a source size or image smaller than the subresource dimensions, and can be more efficient than issuing separate uploadTexture()'s. */ -QRhiTextureUploadDescription::QRhiTextureUploadDescription(const QVector &entries) - : m_entries(entries) +QRhiTextureUploadDescription::QRhiTextureUploadDescription(std::initializer_list list) + : m_entries(list) { } -/*! - Adds \a entry to the list of subresource uploads. - */ -void QRhiTextureUploadDescription::append(const QRhiTextureUploadEntry &entry) -{ - m_entries.append(entry); -} - /*! \class QRhiTextureCopyDescription \internal @@ -3056,11 +3053,6 @@ QDebug operator<<(QDebug dbg, const QRhiShaderResourceBinding &b) #endif #ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug dbg, const QVarLengthArray &bindings) -{ - return QtPrivate::printSequentialContainer(dbg, "Bindings", bindings); -} - QDebug operator<<(QDebug dbg, const QRhiShaderResourceBindings &srb) { QDebugStateSaver saver(dbg); @@ -4215,7 +4207,7 @@ void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, const void *da */ void QRhiResourceUpdateBatch::uploadTexture(QRhiTexture *tex, const QRhiTextureUploadDescription &desc) { - if (!desc.entries().isEmpty()) + if (desc.cbeginEntries() != desc.cendEntries()) d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::textureUpload(tex, desc)); } diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h index f8f922cfdb..95e9213cac 100644 --- a/src/gui/rhi/qrhi_p.h +++ b/src/gui/rhi/qrhi_p.h @@ -240,15 +240,42 @@ class Q_GUI_EXPORT QRhiVertexInputLayout public: QRhiVertexInputLayout() = default; - QVector bindings() const { return m_bindings; } - void setBindings(const QVector &v) { m_bindings = v; } + void setBindings(std::initializer_list list) { m_bindings = list; } + template + void setBindings(InputIterator first, InputIterator last) + { + m_bindings.clear(); + std::copy(first, last, std::back_inserter(m_bindings)); + } + void setBindings(const QVector &bindings) // compat., to be removed + { + setBindings(bindings.cbegin(), bindings.cend()); + } + const QRhiVertexInputBinding *cbeginBindings() const { return m_bindings.cbegin(); } + const QRhiVertexInputBinding *cendBindings() const { return m_bindings.cend(); } + const QRhiVertexInputBinding *bindingAt(int index) const { return &m_bindings.at(index); } - QVector attributes() const { return m_attributes; } - void setAttributes(const QVector &v) { m_attributes = v; } + void setAttributes(std::initializer_list list) { m_attributes = list; } + template + void setAttributes(InputIterator first, InputIterator last) + { + m_attributes.clear(); + std::copy(first, last, std::back_inserter(m_attributes)); + } + void setAttributes(const QVector &attributes) // compat., to be removed + { + setAttributes(attributes.cbegin(), attributes.cend()); + } + const QRhiVertexInputAttribute *cbeginAttributes() const { return m_attributes.cbegin(); } + const QRhiVertexInputAttribute *cendAttributes() const { return m_attributes.cend(); } private: - QVector m_bindings; - QVector m_attributes; + QVarLengthArray m_bindings; + QVarLengthArray m_attributes; + + friend Q_GUI_EXPORT bool operator==(const QRhiVertexInputLayout &a, const QRhiVertexInputLayout &b) Q_DECL_NOTHROW; + friend Q_GUI_EXPORT uint qHash(const QRhiVertexInputLayout &v, uint seed) Q_DECL_NOTHROW; + friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiVertexInputLayout &); }; Q_DECLARE_TYPEINFO(QRhiVertexInputLayout, Q_MOVABLE_TYPE); @@ -439,8 +466,16 @@ public: QRhiTextureRenderTargetDescription(const QRhiColorAttachment &colorAttachment, QRhiRenderBuffer *depthStencilBuffer); QRhiTextureRenderTargetDescription(const QRhiColorAttachment &colorAttachment, QRhiTexture *depthTexture); - QVector colorAttachments() const { return m_colorAttachments; } - void setColorAttachments(const QVector &att) { m_colorAttachments = att; } + void setColorAttachments(std::initializer_list list) { m_colorAttachments = list; } + template + void setColorAttachments(InputIterator first, InputIterator last) + { + m_colorAttachments.clear(); + std::copy(first, last, std::back_inserter(m_colorAttachments)); + } + const QRhiColorAttachment *cbeginColorAttachments() const { return m_colorAttachments.cbegin(); } + const QRhiColorAttachment *cendColorAttachments() const { return m_colorAttachments.cend(); } + const QRhiColorAttachment *colorAttachmentAt(int index) const { return &m_colorAttachments.at(index); } QRhiRenderBuffer *depthStencilBuffer() const { return m_depthStencilBuffer; } void setDepthStencilBuffer(QRhiRenderBuffer *renderBuffer) { m_depthStencilBuffer = renderBuffer; } @@ -449,7 +484,7 @@ public: void setDepthTexture(QRhiTexture *texture) { m_depthTexture = texture; } private: - QVector m_colorAttachments; + QVarLengthArray m_colorAttachments; QRhiRenderBuffer *m_depthStencilBuffer = nullptr; QRhiTexture *m_depthTexture = nullptr; }; @@ -516,14 +551,23 @@ class Q_GUI_EXPORT QRhiTextureUploadDescription public: QRhiTextureUploadDescription() = default; QRhiTextureUploadDescription(const QRhiTextureUploadEntry &entry); - QRhiTextureUploadDescription(const QVector &entries); + QRhiTextureUploadDescription(std::initializer_list list); + QRhiTextureUploadDescription(const QVector &entries) // compat., to be removed + : m_entries(entries.cbegin(), entries.cend()) + { } - QVector entries() const { return m_entries; } - void setEntries(const QVector &entries) { m_entries = entries; } - void append(const QRhiTextureUploadEntry &entry); + void setEntries(std::initializer_list list) { m_entries = list; } + template + void setEntries(InputIterator first, InputIterator last) + { + m_entries.clear(); + std::copy(first, last, std::back_inserter(m_entries)); + } + const QRhiTextureUploadEntry *cbeginEntries() const { return m_entries.cbegin(); } + const QRhiTextureUploadEntry *cendEntries() const { return m_entries.cend(); } private: - QVector m_entries; + QVarLengthArray m_entries; }; Q_DECLARE_TYPEINFO(QRhiTextureUploadDescription, Q_MOVABLE_TYPE); diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h index 822da528f1..80a95e2fcc 100644 --- a/src/gui/rhi/qrhi_p_p.h +++ b/src/gui/rhi/qrhi_p_p.h @@ -328,9 +328,8 @@ public: TextureOp op; op.type = Upload; op.upload.tex = tex; - const QVector &entries(desc.entries()); - for (const QRhiTextureUploadEntry &entry : entries) - op.upload.subresDesc[entry.layer()][entry.level()].append(entry.description()); + for (auto it = desc.cbeginEntries(), itEnd = desc.cendEntries(); it != itEnd; ++it) + op.upload.subresDesc[it->layer()][it->level()].append(it->description()); return op; } diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index b82a68f3dd..36c95f2306 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -742,13 +742,14 @@ void QRhiD3D11::setVertexInput(QRhiCommandBuffer *cb, cmd.cmd = QD3D11CommandBuffer::Command::BindVertexBuffers; cmd.args.bindVertexBuffers.startSlot = startBinding; cmd.args.bindVertexBuffers.slotCount = bindingCount; - const QVector inputBindings = - QRHI_RES(QD3D11GraphicsPipeline, cbD->currentGraphicsPipeline)->m_vertexInputLayout.bindings(); - for (int i = 0, ie = qMin(bindingCount, inputBindings.count()); i != ie; ++i) { + QD3D11GraphicsPipeline *psD = QRHI_RES(QD3D11GraphicsPipeline, cbD->currentGraphicsPipeline); + const QRhiVertexInputLayout &inputLayout(psD->m_vertexInputLayout); + const int inputBindingCount = inputLayout.cendBindings() - inputLayout.cbeginBindings(); + for (int i = 0, ie = qMin(bindingCount, inputBindingCount); i != ie; ++i) { QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, bindings[i].first); cmd.args.bindVertexBuffers.buffers[i] = bufD->buffer; cmd.args.bindVertexBuffers.offsets[i] = bindings[i].second; - cmd.args.bindVertexBuffers.strides[i] = inputBindings[i].stride(); + cmd.args.bindVertexBuffers.strides[i] = inputLayout.bindingAt(i)->stride(); } cbD->commands.append(cmd); } @@ -1606,9 +1607,10 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource if (cbD->currentTarget->resourceType() == QRhiResource::TextureRenderTarget) { QD3D11TextureRenderTarget *rtTex = QRHI_RES(QD3D11TextureRenderTarget, cbD->currentTarget); - const QVector colorAttachments = rtTex->m_desc.colorAttachments(); - for (int att = 0, attCount = colorAttachments.count(); att != attCount; ++att) { - const QRhiColorAttachment &colorAtt(colorAttachments[att]); + for (auto it = rtTex->m_desc.cbeginColorAttachments(), itEnd = rtTex->m_desc.cendColorAttachments(); + it != itEnd; ++it) + { + const QRhiColorAttachment &colorAtt(*it); if (!colorAtt.resolveTexture()) continue; @@ -2953,17 +2955,20 @@ bool QD3D11TextureRenderTarget::build() if (rtv[0] || dsv) release(); - const QVector colorAttachments = m_desc.colorAttachments(); - Q_ASSERT(!colorAttachments.isEmpty() || m_desc.depthTexture()); + const bool hasColorAttachments = m_desc.cbeginColorAttachments() != m_desc.cendColorAttachments(); + Q_ASSERT(hasColorAttachments || m_desc.depthTexture()); Q_ASSERT(!m_desc.depthStencilBuffer() || !m_desc.depthTexture()); const bool hasDepthStencil = m_desc.depthStencilBuffer() || m_desc.depthTexture(); QRHI_RES_RHI(QRhiD3D11); - d.colorAttCount = colorAttachments.count(); - for (int i = 0; i < d.colorAttCount; ++i) { - QRhiTexture *texture = colorAttachments[i].texture(); - QRhiRenderBuffer *rb = colorAttachments[i].renderBuffer(); + d.colorAttCount = 0; + int attIndex = 0; + for (auto it = m_desc.cbeginColorAttachments(), itEnd = m_desc.cendColorAttachments(); it != itEnd; ++it, ++attIndex) { + d.colorAttCount += 1; + const QRhiColorAttachment &colorAtt(*it); + QRhiTexture *texture = colorAtt.texture(); + QRhiRenderBuffer *rb = colorAtt.renderBuffer(); Q_ASSERT(texture || rb); if (texture) { QD3D11Texture *texD = QRHI_RES(QD3D11Texture, texture); @@ -2972,32 +2977,32 @@ bool QD3D11TextureRenderTarget::build() rtvDesc.Format = toD3DTextureFormat(texD->format(), texD->flags()); if (texD->flags().testFlag(QRhiTexture::CubeMap)) { rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = UINT(colorAttachments[i].level()); - rtvDesc.Texture2DArray.FirstArraySlice = UINT(colorAttachments[i].layer()); + rtvDesc.Texture2DArray.MipSlice = UINT(colorAtt.level()); + rtvDesc.Texture2DArray.FirstArraySlice = UINT(colorAtt.layer()); rtvDesc.Texture2DArray.ArraySize = 1; } else { if (texD->sampleDesc.Count > 1) { rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; } else { rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rtvDesc.Texture2D.MipSlice = UINT(colorAttachments[i].level()); + rtvDesc.Texture2D.MipSlice = UINT(colorAtt.level()); } } - HRESULT hr = rhiD->dev->CreateRenderTargetView(texD->tex, &rtvDesc, &rtv[i]); + HRESULT hr = rhiD->dev->CreateRenderTargetView(texD->tex, &rtvDesc, &rtv[attIndex]); if (FAILED(hr)) { qWarning("Failed to create rtv: %s", qPrintable(comErrorMessage(hr))); return false; } - ownsRtv[i] = true; - if (i == 0) { + ownsRtv[attIndex] = true; + if (attIndex == 0) { d.pixelSize = texD->pixelSize(); d.sampleCount = int(texD->sampleDesc.Count); } } else if (rb) { QD3D11RenderBuffer *rbD = QRHI_RES(QD3D11RenderBuffer, rb); - ownsRtv[i] = false; - rtv[i] = rbD->rtv; - if (i == 0) { + ownsRtv[attIndex] = false; + rtv[attIndex] = rbD->rtv; + if (attIndex == 0) { d.pixelSize = rbD->pixelSize(); d.sampleCount = int(rbD->sampleDesc.Count); } @@ -3542,22 +3547,22 @@ bool QD3D11GraphicsPipeline::build() d3dTopology = toD3DTopology(m_topology); if (!vsByteCode.isEmpty()) { - const QVector bindings = m_vertexInputLayout.bindings(); - const QVector attributes = m_vertexInputLayout.attributes(); QVarLengthArray inputDescs; - for (const QRhiVertexInputAttribute &attribute : attributes) { + for (auto it = m_vertexInputLayout.cbeginAttributes(), itEnd = m_vertexInputLayout.cendAttributes(); + it != itEnd; ++it) + { D3D11_INPUT_ELEMENT_DESC desc; memset(&desc, 0, sizeof(desc)); // the output from SPIRV-Cross uses TEXCOORD as the semantic desc.SemanticName = "TEXCOORD"; - desc.SemanticIndex = UINT(attribute.location()); - desc.Format = toD3DAttributeFormat(attribute.format()); - desc.InputSlot = UINT(attribute.binding()); - desc.AlignedByteOffset = attribute.offset(); - const QRhiVertexInputBinding &binding(bindings[attribute.binding()]); - if (binding.classification() == QRhiVertexInputBinding::PerInstance) { + desc.SemanticIndex = UINT(it->location()); + desc.Format = toD3DAttributeFormat(it->format()); + desc.InputSlot = UINT(it->binding()); + desc.AlignedByteOffset = it->offset(); + const QRhiVertexInputBinding *inputBinding = m_vertexInputLayout.bindingAt(it->binding()); + if (inputBinding->classification() == QRhiVertexInputBinding::PerInstance) { desc.InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA; - desc.InstanceDataStepRate = UINT(binding.instanceStepRate()); + desc.InstanceDataStepRate = UINT(inputBinding->instanceStepRate()); } else { desc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; } diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 190385d5de..17b40777b3 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -1898,21 +1898,22 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) { QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.bindVertexBuffer.ps); if (psD) { - const QVector bindings = psD->m_vertexInputLayout.bindings(); - const QVector attributes = psD->m_vertexInputLayout.attributes(); - for (const QRhiVertexInputAttribute &a : attributes) { - const int bindingIdx = a.binding(); + for (auto it = psD->m_vertexInputLayout.cbeginAttributes(), itEnd = psD->m_vertexInputLayout.cendAttributes(); + it != itEnd; ++it) + { + const int bindingIdx = it->binding(); if (bindingIdx != cmd.args.bindVertexBuffer.binding) continue; // we do not support more than one vertex buffer f->glBindBuffer(GL_ARRAY_BUFFER, cmd.args.bindVertexBuffer.buffer); - const int stride = int(bindings[bindingIdx].stride()); + const QRhiVertexInputBinding *inputBinding = psD->m_vertexInputLayout.bindingAt(bindingIdx); + const int stride = int(inputBinding->stride()); int size = 1; GLenum type = GL_FLOAT; bool normalize = false; - switch (a.format()) { + switch (it->format()) { case QRhiVertexInputAttribute::Float4: type = GL_FLOAT; size = 4; @@ -1948,16 +1949,13 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) break; } - const int locationIdx = a.location(); - quint32 ofs = a.offset() + cmd.args.bindVertexBuffer.offset; + const int locationIdx = it->location(); + quint32 ofs = it->offset() + cmd.args.bindVertexBuffer.offset; f->glVertexAttribPointer(GLuint(locationIdx), size, type, normalize, stride, reinterpret_cast(quintptr(ofs))); f->glEnableVertexAttribArray(GLuint(locationIdx)); - if (bindings[bindingIdx].classification() == QRhiVertexInputBinding::PerInstance - && caps.instancing) - { - f->glVertexAttribDivisor(GLuint(locationIdx), GLuint(bindings[bindingIdx].instanceStepRate())); - } + if (inputBinding->classification() == QRhiVertexInputBinding::PerInstance && caps.instancing) + f->glVertexAttribDivisor(GLuint(locationIdx), GLuint(inputBinding->instanceStepRate())); } } else { qWarning("No graphics pipeline active for setVertexInput; ignored"); @@ -2510,10 +2508,12 @@ QGles2RenderTargetData *QRhiGles2::enqueueBindFramebuffer(QRhiRenderTarget *rt, fbCmd.args.bindFramebuffer.fbo = rtTex->framebuffer; fbCmd.args.bindFramebuffer.colorAttCount = rtD->colorAttCount; - const QVector colorAttachments = rtTex->m_desc.colorAttachments(); - for (const QRhiColorAttachment &colorAttachment : colorAttachments) { - QGles2Texture *texD = QRHI_RES(QGles2Texture, colorAttachment.texture()); - QGles2Texture *resolveTexD = QRHI_RES(QGles2Texture, colorAttachment.resolveTexture()); + for (auto it = rtTex->m_desc.cbeginColorAttachments(), itEnd = rtTex->m_desc.cendColorAttachments(); + it != itEnd; ++it) + { + const QRhiColorAttachment &colorAtt(*it); + QGles2Texture *texD = QRHI_RES(QGles2Texture, colorAtt.texture()); + QGles2Texture *resolveTexD = QRHI_RES(QGles2Texture, colorAtt.resolveTexture()); if (texD) { trackedRegisterTexture(&passResTracker, texD, QRhiPassResourceTracker::TexColorOutput, @@ -2602,10 +2602,9 @@ void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource if (cbD->currentTarget->resourceType() == QRhiResource::TextureRenderTarget) { QGles2TextureRenderTarget *rtTex = QRHI_RES(QGles2TextureRenderTarget, cbD->currentTarget); - const QVector colorAttachments = rtTex->m_desc.colorAttachments(); - if (!colorAttachments.isEmpty()) { + if (rtTex->m_desc.cbeginColorAttachments() != rtTex->m_desc.cendColorAttachments()) { // handle only 1 color attachment and only (msaa) renderbuffer - const QRhiColorAttachment &colorAtt(colorAttachments[0]); + const QRhiColorAttachment &colorAtt(*rtTex->m_desc.cbeginColorAttachments()); if (colorAtt.resolveTexture()) { Q_ASSERT(colorAtt.renderBuffer()); QGles2RenderBuffer *rbD = QRHI_RES(QGles2RenderBuffer, colorAtt.renderBuffer()); @@ -3446,14 +3445,18 @@ bool QGles2TextureRenderTarget::build() if (framebuffer) release(); - const QVector colorAttachments = m_desc.colorAttachments(); - Q_ASSERT(!colorAttachments.isEmpty() || m_desc.depthTexture()); + const bool hasColorAttachments = m_desc.cbeginColorAttachments() != m_desc.cendColorAttachments(); + Q_ASSERT(hasColorAttachments || m_desc.depthTexture()); Q_ASSERT(!m_desc.depthStencilBuffer() || !m_desc.depthTexture()); const bool hasDepthStencil = m_desc.depthStencilBuffer() || m_desc.depthTexture(); - if (colorAttachments.count() > rhiD->caps.maxDrawBuffers) - qWarning("QGles2TextureRenderTarget: Too many color attachments (%d, max is %d)", - colorAttachments.count(), rhiD->caps.maxDrawBuffers); + if (hasColorAttachments) { + const int count = m_desc.cendColorAttachments() - m_desc.cbeginColorAttachments(); + if (count > rhiD->caps.maxDrawBuffers) { + qWarning("QGles2TextureRenderTarget: Too many color attachments (%d, max is %d)", + count, rhiD->caps.maxDrawBuffers); + } + } if (m_desc.depthTexture() && !rhiD->caps.depthTexture) qWarning("QGles2TextureRenderTarget: Depth texture is not supported and will be ignored"); @@ -3463,9 +3466,11 @@ bool QGles2TextureRenderTarget::build() rhiD->f->glGenFramebuffers(1, &framebuffer); rhiD->f->glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); - d.colorAttCount = colorAttachments.count(); - for (int i = 0; i < d.colorAttCount; ++i) { - const QRhiColorAttachment &colorAtt(colorAttachments[i]); + d.colorAttCount = 0; + int attIndex = 0; + for (auto it = m_desc.cbeginColorAttachments(), itEnd = m_desc.cendColorAttachments(); it != itEnd; ++it, ++attIndex) { + d.colorAttCount += 1; + const QRhiColorAttachment &colorAtt(*it); QRhiTexture *texture = colorAtt.texture(); QRhiRenderBuffer *renderBuffer = colorAtt.renderBuffer(); Q_ASSERT(texture || renderBuffer); @@ -3473,16 +3478,16 @@ bool QGles2TextureRenderTarget::build() QGles2Texture *texD = QRHI_RES(QGles2Texture, texture); Q_ASSERT(texD->texture && texD->specified); const GLenum faceTargetBase = texD->flags().testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target; - rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uint(i), faceTargetBase + uint(colorAtt.layer()), + rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uint(attIndex), faceTargetBase + uint(colorAtt.layer()), texD->texture, colorAtt.level()); - if (i == 0) { + if (attIndex == 0) { d.pixelSize = texD->pixelSize(); d.sampleCount = 1; } } else if (renderBuffer) { QGles2RenderBuffer *rbD = QRHI_RES(QGles2RenderBuffer, renderBuffer); - rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uint(i), GL_RENDERBUFFER, rbD->renderbuffer); - if (i == 0) { + rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uint(attIndex), GL_RENDERBUFFER, rbD->renderbuffer); + if (attIndex == 0) { d.pixelSize = rbD->pixelSize(); d.sampleCount = rbD->samples; } diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 4dc12f0691..344be44d48 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -1775,14 +1775,15 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb, cbD->d->currentPassRpDesc.depthAttachment.loadAction = MTLLoadActionLoad; cbD->d->currentPassRpDesc.stencilAttachment.loadAction = MTLLoadActionLoad; } - const QVector colorAttachments = rtTex->m_desc.colorAttachments(); - for (const QRhiColorAttachment &colorAttachment : colorAttachments) { - if (colorAttachment.texture()) - QRHI_RES(QMetalTexture, colorAttachment.texture())->lastActiveFrameSlot = currentFrameSlot; - else if (colorAttachment.renderBuffer()) - QRHI_RES(QMetalRenderBuffer, colorAttachment.renderBuffer())->lastActiveFrameSlot = currentFrameSlot; - if (colorAttachment.resolveTexture()) - QRHI_RES(QMetalTexture, colorAttachment.resolveTexture())->lastActiveFrameSlot = currentFrameSlot; + for (auto it = rtTex->m_desc.cbeginColorAttachments(), itEnd = rtTex->m_desc.cendColorAttachments(); + it != itEnd; ++it) + { + if (it->texture()) + QRHI_RES(QMetalTexture, it->texture())->lastActiveFrameSlot = currentFrameSlot; + else if (it->renderBuffer()) + QRHI_RES(QMetalRenderBuffer, it->renderBuffer())->lastActiveFrameSlot = currentFrameSlot; + if (it->resolveTexture()) + QRHI_RES(QMetalTexture, it->resolveTexture())->lastActiveFrameSlot = currentFrameSlot; } if (rtTex->m_desc.depthStencilBuffer()) QRHI_RES(QMetalRenderBuffer, rtTex->m_desc.depthStencilBuffer())->lastActiveFrameSlot = currentFrameSlot; @@ -2647,14 +2648,15 @@ void QMetalTextureRenderTarget::release() QRhiRenderPassDescriptor *QMetalTextureRenderTarget::newCompatibleRenderPassDescriptor() { - const QVector colorAttachments = m_desc.colorAttachments(); + const int colorAttachmentCount = m_desc.cendColorAttachments() - m_desc.cbeginColorAttachments(); QMetalRenderPassDescriptor *rpD = new QMetalRenderPassDescriptor(m_rhi); - rpD->colorAttachmentCount = colorAttachments.count(); + rpD->colorAttachmentCount = colorAttachmentCount; rpD->hasDepthStencil = m_desc.depthStencilBuffer() || m_desc.depthTexture(); - for (int i = 0, ie = colorAttachments.count(); i != ie; ++i) { - QMetalTexture *texD = QRHI_RES(QMetalTexture, colorAttachments[i].texture()); - QMetalRenderBuffer *rbD = QRHI_RES(QMetalRenderBuffer, colorAttachments[i].renderBuffer()); + for (int i = 0; i < colorAttachmentCount; ++i) { + const QRhiColorAttachment *colorAtt = m_desc.colorAttachmentAt(i); + QMetalTexture *texD = QRHI_RES(QMetalTexture, colorAtt->texture()); + QMetalRenderBuffer *rbD = QRHI_RES(QMetalRenderBuffer, colorAtt->renderBuffer()); rpD->colorFormat[i] = int(texD ? texD->d->format : rbD->d->format); } @@ -2668,39 +2670,41 @@ QRhiRenderPassDescriptor *QMetalTextureRenderTarget::newCompatibleRenderPassDesc bool QMetalTextureRenderTarget::build() { - const QVector colorAttachments = m_desc.colorAttachments(); - Q_ASSERT(!colorAttachments.isEmpty() || m_desc.depthTexture()); + const bool hasColorAttachments = m_desc.cbeginColorAttachments() != m_desc.cendColorAttachments(); + Q_ASSERT(hasColorAttachments || m_desc.depthTexture()); Q_ASSERT(!m_desc.depthStencilBuffer() || !m_desc.depthTexture()); const bool hasDepthStencil = m_desc.depthStencilBuffer() || m_desc.depthTexture(); - d->colorAttCount = colorAttachments.count(); - for (int i = 0; i < d->colorAttCount; ++i) { - QMetalTexture *texD = QRHI_RES(QMetalTexture, colorAttachments[i].texture()); - QMetalRenderBuffer *rbD = QRHI_RES(QMetalRenderBuffer, colorAttachments[i].renderBuffer()); + d->colorAttCount = 0; + int attIndex = 0; + for (auto it = m_desc.cbeginColorAttachments(), itEnd = m_desc.cendColorAttachments(); it != itEnd; ++it, ++attIndex) { + d->colorAttCount += 1; + QMetalTexture *texD = QRHI_RES(QMetalTexture, it->texture()); + QMetalRenderBuffer *rbD = QRHI_RES(QMetalRenderBuffer, it->renderBuffer()); Q_ASSERT(texD || rbD); id dst = nil; if (texD) { dst = texD->d->tex; - if (i == 0) { + if (attIndex == 0) { d->pixelSize = texD->pixelSize(); d->sampleCount = texD->samples; } } else if (rbD) { dst = rbD->d->tex; - if (i == 0) { + if (attIndex == 0) { d->pixelSize = rbD->pixelSize(); d->sampleCount = rbD->samples; } } QMetalRenderTargetData::ColorAtt colorAtt; colorAtt.tex = dst; - colorAtt.layer = colorAttachments[i].layer(); - colorAtt.level = colorAttachments[i].level(); - QMetalTexture *resTexD = QRHI_RES(QMetalTexture, colorAttachments[i].resolveTexture()); + colorAtt.layer = it->layer(); + colorAtt.level = it->level(); + QMetalTexture *resTexD = QRHI_RES(QMetalTexture, it->resolveTexture()); colorAtt.resolveTex = resTexD ? resTexD->d->tex : nil; - colorAtt.resolveLayer = colorAttachments[i].resolveLayer(); - colorAtt.resolveLevel = colorAttachments[i].resolveLevel(); - d->fb.colorAtt[i] = colorAtt; + colorAtt.resolveLayer = it->resolveLayer(); + colorAtt.resolveLevel = it->resolveLevel(); + d->fb.colorAtt[attIndex] = colorAtt; } d->dpr = 1; @@ -3119,22 +3123,24 @@ bool QMetalGraphicsPipeline::build() const int firstVertexBinding = QRHI_RES(QMetalShaderResourceBindings, m_shaderResourceBindings)->maxBinding + 1; MTLVertexDescriptor *inputLayout = [MTLVertexDescriptor vertexDescriptor]; - const QVector attributes = m_vertexInputLayout.attributes(); - for (const QRhiVertexInputAttribute &attribute : attributes) { - const uint loc = uint(attribute.location()); - inputLayout.attributes[loc].format = toMetalAttributeFormat(attribute.format()); - inputLayout.attributes[loc].offset = NSUInteger(attribute.offset()); - inputLayout.attributes[loc].bufferIndex = NSUInteger(firstVertexBinding + attribute.binding()); + for (auto it = m_vertexInputLayout.cbeginAttributes(), itEnd = m_vertexInputLayout.cendAttributes(); + it != itEnd; ++it) + { + const uint loc = uint(it->location()); + inputLayout.attributes[loc].format = toMetalAttributeFormat(it->format()); + inputLayout.attributes[loc].offset = NSUInteger(it->offset()); + inputLayout.attributes[loc].bufferIndex = NSUInteger(firstVertexBinding + it->binding()); } - const QVector bindings = m_vertexInputLayout.bindings(); - for (int i = 0, ie = bindings.count(); i != ie; ++i) { - const QRhiVertexInputBinding &binding(bindings[i]); - const uint layoutIdx = uint(firstVertexBinding + i); + int bindingIndex = 0; + for (auto it = m_vertexInputLayout.cbeginBindings(), itEnd = m_vertexInputLayout.cendBindings(); + it != itEnd; ++it, ++bindingIndex) + { + const uint layoutIdx = uint(firstVertexBinding + bindingIndex); inputLayout.layouts[layoutIdx].stepFunction = - binding.classification() == QRhiVertexInputBinding::PerInstance + it->classification() == QRhiVertexInputBinding::PerInstance ? MTLVertexStepFunctionPerInstance : MTLVertexStepFunctionPerVertex; - inputLayout.layouts[layoutIdx].stepRate = NSUInteger(binding.instanceStepRate()); - inputLayout.layouts[layoutIdx].stride = binding.stride(); + inputLayout.layouts[layoutIdx].stepRate = NSUInteger(it->instanceStepRate()); + inputLayout.layouts[layoutIdx].stride = it->stride(); } MTLRenderPipelineDescriptor *rpDesc = [[MTLRenderPipelineDescriptor alloc] init]; diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp index 60d620813b..487afd3ed1 100644 --- a/src/gui/rhi/qrhinull.cpp +++ b/src/gui/rhi/qrhinull.cpp @@ -628,10 +628,9 @@ QRhiRenderPassDescriptor *QNullTextureRenderTarget::newCompatibleRenderPassDescr bool QNullTextureRenderTarget::build() { d.rp = QRHI_RES(QNullRenderPassDescriptor, m_renderPassDesc); - const QVector colorAttachments = m_desc.colorAttachments(); - if (!colorAttachments.isEmpty()) { - QRhiTexture *tex = colorAttachments.first().texture(); - QRhiRenderBuffer *rb = colorAttachments.first().renderBuffer(); + if (m_desc.cbeginColorAttachments() != m_desc.cendColorAttachments()) { + QRhiTexture *tex = m_desc.cbeginColorAttachments()->texture(); + QRhiRenderBuffer *rb = m_desc.cbeginColorAttachments()->renderBuffer(); d.pixelSize = tex ? tex->pixelSize() : rb->pixelSize(); } else if (m_desc.depthStencilBuffer()) { d.pixelSize = m_desc.depthStencilBuffer()->pixelSize(); diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index 7e2e914af3..3a2c35b589 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -1111,7 +1111,8 @@ bool QRhiVulkan::createDefaultRenderPass(VkRenderPass *rp, bool hasDepthStencil, } bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp, - const QVector &colorAttachments, + const QRhiColorAttachment *firstColorAttachment, + const QRhiColorAttachment *lastColorAttachment, bool preserveColor, bool preserveDs, QRhiRenderBuffer *depthStencilBuffer, @@ -1120,13 +1121,12 @@ bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp, QVarLengthArray attDescs; QVarLengthArray colorRefs; QVarLengthArray resolveRefs; - const int colorAttCount = colorAttachments.count(); // attachment list layout is color (0-8), ds (0-1), resolve (0-8) - for (int i = 0; i < colorAttCount; ++i) { - QVkTexture *texD = QRHI_RES(QVkTexture, colorAttachments[i].texture()); - QVkRenderBuffer *rbD = QRHI_RES(QVkRenderBuffer, colorAttachments[i].renderBuffer()); + for (auto it = firstColorAttachment; it != lastColorAttachment; ++it) { + QVkTexture *texD = QRHI_RES(QVkTexture, it->texture()); + QVkRenderBuffer *rbD = QRHI_RES(QVkRenderBuffer, it->renderBuffer()); Q_ASSERT(texD || rbD); const VkFormat vkformat = texD ? texD->vkformat : rbD->vkformat; const VkSampleCountFlagBits samples = texD ? texD->samples : rbD->samples; @@ -1136,7 +1136,7 @@ bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp, attDesc.format = vkformat; attDesc.samples = samples; attDesc.loadOp = preserveColor ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR; - attDesc.storeOp = colorAttachments[i].resolveTexture() ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE; + attDesc.storeOp = it->resolveTexture() ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE; attDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; // this has to interact correctly with activateTextureRenderTarget(), hence leaving in COLOR_ATT @@ -1170,9 +1170,9 @@ bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp, } VkAttachmentReference dsRef = { uint32_t(attDescs.count() - 1), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; - for (int i = 0; i < colorAttCount; ++i) { - if (colorAttachments[i].resolveTexture()) { - QVkTexture *rtexD = QRHI_RES(QVkTexture, colorAttachments[i].resolveTexture()); + for (auto it = firstColorAttachment; it != lastColorAttachment; ++it) { + if (it->resolveTexture()) { + QVkTexture *rtexD = QRHI_RES(QVkTexture, it->resolveTexture()); if (rtexD->samples > VK_SAMPLE_COUNT_1_BIT) qWarning("Resolving into a multisample texture is not supported"); @@ -1979,11 +1979,10 @@ void QRhiVulkan::activateTextureRenderTarget(QVkCommandBuffer *cbD, QVkTextureRe rtD->lastActiveFrameSlot = currentFrameSlot; rtD->d.rp->lastActiveFrameSlot = currentFrameSlot; QRhiPassResourceTracker &passResTracker(cbD->passResTrackers[cbD->currentPassResTrackerIndex]); - const QVector colorAttachments = rtD->m_desc.colorAttachments(); - for (const QRhiColorAttachment &colorAttachment : colorAttachments) { - QVkTexture *texD = QRHI_RES(QVkTexture, colorAttachment.texture()); - QVkTexture *resolveTexD = QRHI_RES(QVkTexture, colorAttachment.resolveTexture()); - QVkRenderBuffer *rbD = QRHI_RES(QVkRenderBuffer, colorAttachment.renderBuffer()); + for (auto it = rtD->m_desc.cbeginColorAttachments(), itEnd = rtD->m_desc.cendColorAttachments(); it != itEnd; ++it) { + QVkTexture *texD = QRHI_RES(QVkTexture, it->texture()); + QVkTexture *resolveTexD = QRHI_RES(QVkTexture, it->resolveTexture()); + QVkRenderBuffer *rbD = QRHI_RES(QVkRenderBuffer, it->renderBuffer()); if (texD) { trackedRegisterTexture(&passResTracker, texD, QRhiPassResourceTracker::TexColorOutput, @@ -5487,7 +5486,8 @@ QRhiRenderPassDescriptor *QVkTextureRenderTarget::newCompatibleRenderPassDescrip QRHI_RES_RHI(QRhiVulkan); QVkRenderPassDescriptor *rp = new QVkRenderPassDescriptor(m_rhi); if (!rhiD->createOffscreenRenderPass(&rp->rp, - m_desc.colorAttachments(), + m_desc.cbeginColorAttachments(), + m_desc.cendColorAttachments(), m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents), m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents), m_desc.depthStencilBuffer(), @@ -5507,18 +5507,20 @@ bool QVkTextureRenderTarget::build() if (d.fb) release(); - const QVector colorAttachments = m_desc.colorAttachments(); - Q_ASSERT(!colorAttachments.isEmpty() || m_desc.depthTexture()); + const bool hasColorAttachments = m_desc.cbeginColorAttachments() != m_desc.cendColorAttachments(); + Q_ASSERT(hasColorAttachments || m_desc.depthTexture()); Q_ASSERT(!m_desc.depthStencilBuffer() || !m_desc.depthTexture()); const bool hasDepthStencil = m_desc.depthStencilBuffer() || m_desc.depthTexture(); QRHI_RES_RHI(QRhiVulkan); QVarLengthArray views; - d.colorAttCount = colorAttachments.count(); - for (int i = 0; i < d.colorAttCount; ++i) { - QVkTexture *texD = QRHI_RES(QVkTexture, colorAttachments[i].texture()); - QVkRenderBuffer *rbD = QRHI_RES(QVkRenderBuffer, colorAttachments[i].renderBuffer()); + d.colorAttCount = 0; + int attIndex = 0; + for (auto it = m_desc.cbeginColorAttachments(), itEnd = m_desc.cendColorAttachments(); it != itEnd; ++it, ++attIndex) { + d.colorAttCount += 1; + QVkTexture *texD = QRHI_RES(QVkTexture, it->texture()); + QVkRenderBuffer *rbD = QRHI_RES(QVkRenderBuffer, it->renderBuffer()); Q_ASSERT(texD || rbD); if (texD) { Q_ASSERT(texD->flags().testFlag(QRhiTexture::RenderTarget)); @@ -5533,24 +5535,24 @@ bool QVkTextureRenderTarget::build() viewInfo.components.b = VK_COMPONENT_SWIZZLE_B; viewInfo.components.a = VK_COMPONENT_SWIZZLE_A; viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - viewInfo.subresourceRange.baseMipLevel = uint32_t(colorAttachments[i].level()); + viewInfo.subresourceRange.baseMipLevel = uint32_t(it->level()); viewInfo.subresourceRange.levelCount = 1; - viewInfo.subresourceRange.baseArrayLayer = uint32_t(colorAttachments[i].layer()); + viewInfo.subresourceRange.baseArrayLayer = uint32_t(it->layer()); viewInfo.subresourceRange.layerCount = 1; - VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &rtv[i]); + VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &rtv[attIndex]); if (err != VK_SUCCESS) { qWarning("Failed to create render target image view: %d", err); return false; } - views.append(rtv[i]); - if (i == 0) { + views.append(rtv[attIndex]); + if (attIndex == 0) { d.pixelSize = texD->pixelSize(); d.sampleCount = texD->samples; } } else if (rbD) { Q_ASSERT(rbD->backingTexture); views.append(rbD->backingTexture->imageView); - if (i == 0) { + if (attIndex == 0) { d.pixelSize = rbD->pixelSize(); d.sampleCount = rbD->samples; } @@ -5580,9 +5582,10 @@ bool QVkTextureRenderTarget::build() } d.resolveAttCount = 0; - for (int i = 0; i < d.colorAttCount; ++i) { - if (colorAttachments[i].resolveTexture()) { - QVkTexture *resTexD = QRHI_RES(QVkTexture, colorAttachments[i].resolveTexture()); + attIndex = 0; + for (auto it = m_desc.cbeginColorAttachments(), itEnd = m_desc.cendColorAttachments(); it != itEnd; ++it, ++attIndex) { + if (it->resolveTexture()) { + QVkTexture *resTexD = QRHI_RES(QVkTexture, it->resolveTexture()); Q_ASSERT(resTexD->flags().testFlag(QRhiTexture::RenderTarget)); d.resolveAttCount += 1; @@ -5597,16 +5600,16 @@ bool QVkTextureRenderTarget::build() viewInfo.components.b = VK_COMPONENT_SWIZZLE_B; viewInfo.components.a = VK_COMPONENT_SWIZZLE_A; viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - viewInfo.subresourceRange.baseMipLevel = uint32_t(colorAttachments[i].resolveLevel()); + viewInfo.subresourceRange.baseMipLevel = uint32_t(it->resolveLevel()); viewInfo.subresourceRange.levelCount = 1; - viewInfo.subresourceRange.baseArrayLayer = uint32_t(colorAttachments[i].resolveLayer()); + viewInfo.subresourceRange.baseArrayLayer = uint32_t(it->resolveLayer()); viewInfo.subresourceRange.layerCount = 1; - VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &resrtv[i]); + VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &resrtv[attIndex]); if (err != VK_SUCCESS) { qWarning("Failed to create render target resolve image view: %d", err); return false; } - views.append(resrtv[i]); + views.append(resrtv[attIndex]); } } @@ -5828,22 +5831,21 @@ bool QVkGraphicsPipeline::build() pipelineInfo.stageCount = uint32_t(shaderStageCreateInfos.count()); pipelineInfo.pStages = shaderStageCreateInfos.constData(); - const QVector bindings = m_vertexInputLayout.bindings(); QVarLengthArray vertexBindings; QVarLengthArray nonOneStepRates; - for (int i = 0, ie = bindings.count(); i != ie; ++i) { - const QRhiVertexInputBinding &binding(bindings[i]); + int bindingIndex = 0; + for (auto it = m_vertexInputLayout.cbeginBindings(), itEnd = m_vertexInputLayout.cendBindings(); + it != itEnd; ++it, ++bindingIndex) + { VkVertexInputBindingDescription bindingInfo = { - uint32_t(i), - binding.stride(), - binding.classification() == QRhiVertexInputBinding::PerVertex + uint32_t(bindingIndex), + it->stride(), + it->classification() == QRhiVertexInputBinding::PerVertex ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE }; - if (binding.classification() == QRhiVertexInputBinding::PerInstance - && binding.instanceStepRate() != 1) - { + if (it->classification() == QRhiVertexInputBinding::PerInstance && it->instanceStepRate() != 1) { if (rhiD->vertexAttribDivisorAvailable) { - nonOneStepRates.append({ uint32_t(i), uint32_t(binding.instanceStepRate()) }); + nonOneStepRates.append({ uint32_t(bindingIndex), uint32_t(it->instanceStepRate()) }); } else { qWarning("QRhiVulkan: Instance step rates other than 1 not supported without " "VK_EXT_vertex_attribute_divisor on the device and " @@ -5852,14 +5854,15 @@ bool QVkGraphicsPipeline::build() } vertexBindings.append(bindingInfo); } - const QVector attributes = m_vertexInputLayout.attributes(); QVarLengthArray vertexAttributes; - for (const QRhiVertexInputAttribute &attribute : attributes) { + for (auto it = m_vertexInputLayout.cbeginAttributes(), itEnd = m_vertexInputLayout.cendAttributes(); + it != itEnd; ++it) + { VkVertexInputAttributeDescription attributeInfo = { - uint32_t(attribute.location()), - uint32_t(attribute.binding()), - toVkAttributeFormat(attribute.format()), - attribute.offset() + uint32_t(it->location()), + uint32_t(it->binding()), + toVkAttributeFormat(it->format()), + it->offset() }; vertexAttributes.append(attributeInfo); } diff --git a/src/gui/rhi/qrhivulkan_p_p.h b/src/gui/rhi/qrhivulkan_p_p.h index d83a338acd..7bd20b3671 100644 --- a/src/gui/rhi/qrhivulkan_p_p.h +++ b/src/gui/rhi/qrhivulkan_p_p.h @@ -732,7 +732,8 @@ public: VkSampleCountFlagBits samples, VkFormat colorFormat); bool createOffscreenRenderPass(VkRenderPass *rp, - const QVector &colorAttachments, + const QRhiColorAttachment *firstColorAttachment, + const QRhiColorAttachment *lastColorAttachment, bool preserveColor, bool preserveDs, QRhiRenderBuffer *depthStencilBuffer, diff --git a/tests/manual/rhi/compressedtexture_bc1/compressedtexture_bc1.cpp b/tests/manual/rhi/compressedtexture_bc1/compressedtexture_bc1.cpp index bb3722bec5..af454c2487 100644 --- a/tests/manual/rhi/compressedtexture_bc1/compressedtexture_bc1.cpp +++ b/tests/manual/rhi/compressedtexture_bc1/compressedtexture_bc1.cpp @@ -165,11 +165,13 @@ void Window::customRender() u->updateDynamicBuffer(d.ubuf, 64, 4, &flip); } if (!d.compressedData.isEmpty()) { - QRhiTextureUploadDescription desc; + QVarLengthArray descEntries; for (int i = 0; i < d.compressedData.count(); ++i) { QRhiTextureSubresourceUploadDescription image(d.compressedData[i].constData(), d.compressedData[i].size()); - desc.append({ 0, i, image }); + descEntries.append({ 0, i, image }); } + QRhiTextureUploadDescription desc; + desc.setEntries(descEntries.cbegin(), descEntries.cend()); u->uploadTexture(d.tex, desc); d.compressedData.clear(); } diff --git a/tests/manual/rhi/mrt/mrt.cpp b/tests/manual/rhi/mrt/mrt.cpp index dc72c7d194..dfec5bb1d1 100644 --- a/tests/manual/rhi/mrt/mrt.cpp +++ b/tests/manual/rhi/mrt/mrt.cpp @@ -143,10 +143,10 @@ void Window::customInit() } QRhiTextureRenderTargetDescription rtDesc; - QVector att; + QRhiColorAttachment att[ATTCOUNT]; for (int i = 0; i < ATTCOUNT; ++i) - att.append(QRhiColorAttachment(d.colData[i].tex)); - rtDesc.setColorAttachments(att); + att[i] = QRhiColorAttachment(d.colData[i].tex); + rtDesc.setColorAttachments(att, att + ATTCOUNT); d.rt = m_r->newTextureRenderTarget(rtDesc); d.releasePool << d.rt; d.rtRp = d.rt->newCompatibleRenderPassDescriptor(); diff --git a/tests/manual/rhi/triquadcube/texturedcuberenderer.cpp b/tests/manual/rhi/triquadcube/texturedcuberenderer.cpp index 3f15881e2d..8c5845d4fc 100644 --- a/tests/manual/rhi/triquadcube/texturedcuberenderer.cpp +++ b/tests/manual/rhi/triquadcube/texturedcuberenderer.cpp @@ -181,16 +181,18 @@ void TexturedCubeRenderer::queueResourceUpdates(QRhiResourceUpdateBatch *resourc if (!m_image.isNull()) { if (MIPMAP) { - QRhiTextureUploadDescription desc; + QVarLengthArray descEntries; if (!AUTOGENMIPMAP) { // the ghetto mipmap generator... for (int i = 0, ie = m_r->mipLevelsForSize(m_image.size()); i != ie; ++i) { QImage image = m_image.scaled(m_r->sizeForMipLevel(i, m_image.size())); - desc.append({ 0, i, image }); + descEntries.append({ 0, i, image }); } } else { - desc.append({ 0, 0, m_image }); + descEntries.append({ 0, 0, m_image }); } + QRhiTextureUploadDescription desc; + desc.setEntries(descEntries.cbegin(), descEntries.cend()); resourceUpdates->uploadTexture(m_tex, desc); if (AUTOGENMIPMAP) resourceUpdates->generateMips(m_tex);