summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-10-04 01:01:47 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-10-04 01:01:48 +0200
commit3a1613c2276a30ccf101e7349d89611cf5d86e6a (patch)
treea58ca18e938b88bb0952cbcd3c70252ad2eb2ae0 /src/gui
parent127ed7e6e0f8939861cce7349e28a1dec9a7d6ed (diff)
parenta978d21dac57697ae9557b99062bc804b005b9d4 (diff)
Merge remote-tracking branch 'origin/5.14' into 5.15
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/kernel/qevent.cpp14
-rw-r--r--src/gui/kernel/qguiapplication.cpp3
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp3
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp3
-rw-r--r--src/gui/rhi/qrhi.cpp44
-rw-r--r--src/gui/rhi/qrhi_p.h76
-rw-r--r--src/gui/rhi/qrhi_p_p.h5
-rw-r--r--src/gui/rhi/qrhid3d11.cpp71
-rw-r--r--src/gui/rhi/qrhigles2.cpp73
-rw-r--r--src/gui/rhi/qrhimetal.mm90
-rw-r--r--src/gui/rhi/qrhinull.cpp7
-rw-r--r--src/gui/rhi/qrhivulkan.cpp110
-rw-r--r--src/gui/rhi/qrhivulkan_p_p.h3
13 files changed, 298 insertions, 204 deletions
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index d41e3e5e3c..2b28052dd5 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -791,37 +791,44 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta
\obsolete
This constructor has been deprecated.
*/
-
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
: QWheelEvent(pos, globalPos, pixelDelta, angleDelta, qt4Delta, qt4Orientation,
buttons, modifiers, Qt::NoScrollPhase)
{}
+QT_WARNING_POP
/*!
\obsolete
This constructor has been deprecated.
*/
-
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase)
: QWheelEvent(pos, globalPos, pixelDelta, angleDelta, qt4Delta, qt4Orientation,
buttons, modifiers, phase, Qt::MouseEventNotSynthesized)
{}
+QT_WARNING_POP
/*!
\obsolete
This constructor has been deprecated.
*/
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase, Qt::MouseEventSource source)
: QWheelEvent(pos, globalPos, pixelDelta, angleDelta, qt4Delta, qt4Orientation,
buttons, modifiers, phase, source, false)
{}
+QT_WARNING_POP
/*!
\obsolete
@@ -3930,12 +3937,15 @@ QDebug operator<<(QDebug dbg, const QEvent *e)
case QEvent::Wheel: {
const QWheelEvent *we = static_cast<const QWheelEvent *>(e);
dbg << "QWheelEvent(" << we->phase();
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED // delta() and orientation()
if (!we->pixelDelta().isNull() || !we->angleDelta().isNull())
dbg << ", pixelDelta=" << we->pixelDelta() << ", angleDelta=" << we->angleDelta();
#if QT_DEPRECATED_SINCE(5, 14)
else if (int qt4Delta = we->delta())
dbg << ", delta=" << qt4Delta << ", orientation=" << we->orientation();
#endif
+QT_WARNING_POP
dbg << ')';
}
break;
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index c5d8cf9bf9..b50fe665c4 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -2247,8 +2247,11 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh
}
#if QT_DEPRECATED_SINCE(5, 14)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta, e->qt4Delta, e->qt4Orientation,
mouse_buttons, e->modifiers, e->phase, e->source, e->inverted);
+QT_WARNING_POP
#else
QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta,
mouse_buttons, e->modifiers, e->phase, e->inverted, e->source);
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
index c087326068..47394999c6 100644
--- a/src/gui/opengl/qopenglpaintengine.cpp
+++ b/src/gui/opengl/qopenglpaintengine.cpp
@@ -1474,6 +1474,8 @@ void QOpenGL2PaintEngineEx::renderHintsChanged()
#ifndef QT_OPENGL_ES_2
if (!QOpenGLContext::currentContext()->isOpenGLES()) {
Q_D(QOpenGL2PaintEngineEx);
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
if ((state()->renderHints & QPainter::Antialiasing)
#if QT_DEPRECATED_SINCE(5, 14)
|| (state()->renderHints & QPainter::HighQualityAntialiasing)
@@ -1482,6 +1484,7 @@ void QOpenGL2PaintEngineEx::renderHintsChanged()
d->funcs.glEnable(GL_MULTISAMPLE);
else
d->funcs.glDisable(GL_MULTISAMPLE);
+QT_WARNING_POP
}
#endif // QT_OPENGL_ES_2
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 447ecb358a..8c51981120 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -906,8 +906,11 @@ void QRasterPaintEngine::renderHintsChanged()
s->flags.antialiased = bool(s->renderHints & QPainter::Antialiasing);
#if QT_DEPRECATED_SINCE(5, 14)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
if (s->renderHints & QPainter::HighQualityAntialiasing)
s->flags.antialiased = true;
+QT_WARNING_POP
#endif
s->flags.bilinear = bool(s->renderHints & QPainter::SmoothPixmapTransform);
s->flags.legacy_rounding = !bool(s->renderHints & QPainter::Antialiasing) && bool(s->renderHints & QPainter::Qt4CompatiblePainting);
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index 08bafebdec..c8ec8c7410 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -563,7 +563,10 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
\value BaseInstance Indicates that instanced draw commands support the \c
firstInstance argument. When reported as not supported, the firstInstance
value is ignored and the instance ID starts from 0.
- */
+
+ \value TriangleFanTopology Indicates that QRhiGraphicsPipeline::setTopology()
+ supports QRhiGraphicsPipeline::TriangleFan.
+*/
/*!
\enum QRhi::BeginFrameFlag
@@ -1199,8 +1202,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 +1223,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,28 +1638,20 @@ 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)
+QRhiTextureUploadDescription::QRhiTextureUploadDescription(std::initializer_list<QRhiTextureUploadEntry> 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
\inmodule QtGui
@@ -3056,11 +3056,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);
@@ -3131,6 +3126,7 @@ QDebug operator<<(QDebug dbg, const QRhiShaderResourceBindings &srb)
\value Triangles (default)
\value TriangleStrip
+ \value TriangleFan (only available if QRhi::TriangleFanTopology is supported)
\value Lines
\value LineStrip
\value Points
@@ -4215,7 +4211,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..5b371af727 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);
@@ -973,6 +1017,7 @@ public:
enum Topology {
Triangles,
TriangleStrip,
+ TriangleFan,
Lines,
LineStrip,
Points
@@ -1382,7 +1427,8 @@ public:
WideLines,
VertexShaderPointSize,
BaseVertex,
- BaseInstance
+ BaseInstance,
+ TriangleFanTopology
};
enum BeginFrameFlag {
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..f011d68ada 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -469,6 +469,8 @@ bool QRhiD3D11::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::BaseInstance:
return true;
+ case QRhi::TriangleFanTopology:
+ return false;
default:
Q_UNREACHABLE();
return false;
@@ -742,13 +744,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 +1609,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 +2957,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 +2979,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 +3549,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..277cf12fd2 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -732,6 +732,8 @@ bool QRhiGles2::isFeatureSupported(QRhi::Feature feature) const
return caps.baseVertex;
case QRhi::BaseInstance:
return false; // not in ES 3.2, so won't bother
+ case QRhi::TriangleFanTopology:
+ return true;
default:
Q_UNREACHABLE();
return false;
@@ -1539,6 +1541,8 @@ static inline GLenum toGlTopology(QRhiGraphicsPipeline::Topology t)
return GL_TRIANGLES;
case QRhiGraphicsPipeline::TriangleStrip:
return GL_TRIANGLE_STRIP;
+ case QRhiGraphicsPipeline::TriangleFan:
+ return GL_TRIANGLE_FAN;
case QRhiGraphicsPipeline::Lines:
return GL_LINES;
case QRhiGraphicsPipeline::LineStrip:
@@ -1898,21 +1902,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 +1953,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 +2512,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 +2606,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 +3449,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 +3470,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 +3482,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..f9d9cdc01a 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -550,6 +550,8 @@ bool QRhiMetal::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::BaseInstance:
return true;
+ case QRhi::TriangleFanTopology:
+ return false;
default:
Q_UNREACHABLE();
return false;
@@ -1775,14 +1777,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 +2650,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 +2672,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 +3125,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..cb32aa08f3 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -568,6 +568,9 @@ bool QRhiVulkan::create(QRhi::Flags flags)
VmaAllocatorCreateInfo allocatorInfo;
memset(&allocatorInfo, 0, sizeof(allocatorInfo));
+ // A QRhi is supposed to be used from one single thread only. Disable
+ // the allocator's own mutexes. This gives a performance boost.
+ allocatorInfo.flags = VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT;
allocatorInfo.physicalDevice = physDev;
allocatorInfo.device = dev;
allocatorInfo.pVulkanFunctions = &afuncs;
@@ -1111,7 +1114,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 +1124,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 +1139,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 +1173,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 +1982,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,
@@ -3725,6 +3727,8 @@ bool QRhiVulkan::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::BaseInstance:
return true;
+ case QRhi::TriangleFanTopology:
+ return true;
default:
Q_UNREACHABLE();
return false;
@@ -4570,6 +4574,8 @@ static inline VkPrimitiveTopology toVkTopology(QRhiGraphicsPipeline::Topology t)
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
case QRhiGraphicsPipeline::TriangleStrip:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+ case QRhiGraphicsPipeline::TriangleFan:
+ return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
case QRhiGraphicsPipeline::Lines:
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
case QRhiGraphicsPipeline::LineStrip:
@@ -5487,7 +5493,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 +5514,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 +5542,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 +5589,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 +5607,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 +5838,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 +5861,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,