summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2019-10-02 10:58:44 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2019-10-03 09:37:48 +0200
commitf1c7814a55903dad5a5e77683bdcca5fc3805394 (patch)
tree3de4f3da1506349d7ed06cc4d6593bfd499383ba /src
parent1a8f4a3c8fa30265e7f184373c738dbc3574663a (diff)
rhi: Remove QVectors from the data description structs as well
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 <christian.stromme@qt.io> Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/gui/rhi/qrhi.cpp38
-rw-r--r--src/gui/rhi/qrhi_p.h72
-rw-r--r--src/gui/rhi/qrhi_p_p.h5
-rw-r--r--src/gui/rhi/qrhid3d11.cpp69
-rw-r--r--src/gui/rhi/qrhigles2.cpp69
-rw-r--r--src/gui/rhi/qrhimetal.mm88
-rw-r--r--src/gui/rhi/qrhinull.cpp7
-rw-r--r--src/gui/rhi/qrhivulkan.cpp103
-rw-r--r--src/gui/rhi/qrhivulkan_p_p.h3
9 files changed, 254 insertions, 200 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<typename T, int N>
+QDebug operator<<(QDebug dbg, const QVarLengthArray<T, N> &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,25 +1635,17 @@ 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<QRhiTextureUploadEntry> &entries)
- : m_entries(entries)
-{
-}
-
-/*!
- Adds \a entry to the list of subresource uploads.
- */
-void QRhiTextureUploadDescription::append(const QRhiTextureUploadEntry &entry)
+QRhiTextureUploadDescription::QRhiTextureUploadDescription(std::initializer_list<QRhiTextureUploadEntry> list)
+ : m_entries(list)
{
- m_entries.append(entry);
}
/*!
@@ -3056,11 +3053,6 @@ QDebug operator<<(QDebug dbg, const QRhiShaderResourceBinding &b)
#endif
#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug dbg, const QVarLengthArray<QRhiShaderResourceBinding, 8> &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<QRhiVertexInputBinding> bindings() const { return m_bindings; }
- void setBindings(const QVector<QRhiVertexInputBinding> &v) { m_bindings = v; }
+ void setBindings(std::initializer_list<QRhiVertexInputBinding> list) { m_bindings = list; }
+ template<typename InputIterator>
+ void setBindings(InputIterator first, InputIterator last)
+ {
+ m_bindings.clear();
+ std::copy(first, last, std::back_inserter(m_bindings));
+ }
+ void setBindings(const QVector<QRhiVertexInputBinding> &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<QRhiVertexInputAttribute> attributes() const { return m_attributes; }
- void setAttributes(const QVector<QRhiVertexInputAttribute> &v) { m_attributes = v; }
+ void setAttributes(std::initializer_list<QRhiVertexInputAttribute> list) { m_attributes = list; }
+ template<typename InputIterator>
+ void setAttributes(InputIterator first, InputIterator last)
+ {
+ m_attributes.clear();
+ std::copy(first, last, std::back_inserter(m_attributes));
+ }
+ void setAttributes(const QVector<QRhiVertexInputAttribute> &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<QRhiVertexInputBinding> m_bindings;
- QVector<QRhiVertexInputAttribute> m_attributes;
+ QVarLengthArray<QRhiVertexInputBinding, 8> m_bindings;
+ QVarLengthArray<QRhiVertexInputAttribute, 8> 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<QRhiColorAttachment> colorAttachments() const { return m_colorAttachments; }
- void setColorAttachments(const QVector<QRhiColorAttachment> &att) { m_colorAttachments = att; }
+ void setColorAttachments(std::initializer_list<QRhiColorAttachment> list) { m_colorAttachments = list; }
+ template<typename InputIterator>
+ 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<QRhiColorAttachment> m_colorAttachments;
+ QVarLengthArray<QRhiColorAttachment, 8> 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<QRhiTextureUploadEntry> &entries);
+ QRhiTextureUploadDescription(std::initializer_list<QRhiTextureUploadEntry> list);
+ QRhiTextureUploadDescription(const QVector<QRhiTextureUploadEntry> &entries) // compat., to be removed
+ : m_entries(entries.cbegin(), entries.cend())
+ { }
- QVector<QRhiTextureUploadEntry> entries() const { return m_entries; }
- void setEntries(const QVector<QRhiTextureUploadEntry> &entries) { m_entries = entries; }
- void append(const QRhiTextureUploadEntry &entry);
+ void setEntries(std::initializer_list<QRhiTextureUploadEntry> list) { m_entries = list; }
+ template<typename InputIterator>
+ 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<QRhiTextureUploadEntry> m_entries;
+ QVarLengthArray<QRhiTextureUploadEntry, 16> 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<QRhiTextureUploadEntry> &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<QRhiVertexInputBinding> 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<QRhiColorAttachment> 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<QRhiColorAttachment> 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<QRhiVertexInputBinding> bindings = m_vertexInputLayout.bindings();
- const QVector<QRhiVertexInputAttribute> attributes = m_vertexInputLayout.attributes();
QVarLengthArray<D3D11_INPUT_ELEMENT_DESC, 4> 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<location> 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<QRhiVertexInputBinding> bindings = psD->m_vertexInputLayout.bindings();
- const QVector<QRhiVertexInputAttribute> 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<const GLvoid *>(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<QRhiColorAttachment> 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<QRhiColorAttachment> 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<QRhiColorAttachment> 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<QRhiColorAttachment> 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<QRhiColorAttachment> 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<QRhiColorAttachment> 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<MTLTexture> 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<QRhiVertexInputAttribute> 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());
- }
- const QVector<QRhiVertexInputBinding> 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);
+ 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());
+ }
+ 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<QRhiColorAttachment> 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<QRhiColorAttachment> &colorAttachments,
+ const QRhiColorAttachment *firstColorAttachment,
+ const QRhiColorAttachment *lastColorAttachment,
bool preserveColor,
bool preserveDs,
QRhiRenderBuffer *depthStencilBuffer,
@@ -1120,13 +1121,12 @@ bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp,
QVarLengthArray<VkAttachmentDescription, 8> attDescs;
QVarLengthArray<VkAttachmentReference, 8> colorRefs;
QVarLengthArray<VkAttachmentReference, 8> 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<QRhiColorAttachment> 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<QRhiColorAttachment> 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<VkImageView, 8> 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<QRhiVertexInputBinding> bindings = m_vertexInputLayout.bindings();
QVarLengthArray<VkVertexInputBindingDescription, 4> vertexBindings;
QVarLengthArray<VkVertexInputBindingDivisorDescriptionEXT> 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<QRhiVertexInputAttribute> attributes = m_vertexInputLayout.attributes();
QVarLengthArray<VkVertexInputAttributeDescription, 4> 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<QRhiColorAttachment> &colorAttachments,
+ const QRhiColorAttachment *firstColorAttachment,
+ const QRhiColorAttachment *lastColorAttachment,
bool preserveColor,
bool preserveDs,
QRhiRenderBuffer *depthStencilBuffer,