summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2020-09-28 13:05:38 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2020-09-29 21:24:32 +0200
commit868866cecd57e671d1b2826b59d3fa1c872b214c (patch)
tree1f94c9a3509b9ffae7e46b22e751aee65fc288a7
parent331c8cd5b40fc6ce4301fdde365c2f7c0b5c6445 (diff)
rhi: Improve layout compatibility test performance
Also bump the non-heap buffer size in the binding list to 16, in order to accommodate complex Quick3D materials with many associated texture maps. Change-Id: Id190e5f8304f5941cffc41a2605fce45dfeb72f0 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
-rw-r--r--src/gui/rhi/qrhi.cpp25
-rw-r--r--src/gui/rhi/qrhi_p.h5
-rw-r--r--src/gui/rhi/qrhi_p_p.h1
-rw-r--r--src/gui/rhi/qrhid3d11.cpp2
-rw-r--r--src/gui/rhi/qrhigles2.cpp2
-rw-r--r--src/gui/rhi/qrhimetal.mm2
-rw-r--r--src/gui/rhi/qrhinull.cpp6
-rw-r--r--src/gui/rhi/qrhivulkan.cpp2
8 files changed, 36 insertions, 9 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index a54d7ac405..21542930ac 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -2806,16 +2806,25 @@ bool QRhiShaderResourceBindings::isLayoutCompatible(const QRhiShaderResourceBind
if (!other)
return false;
- const int count = m_bindings.count();
- if (count != other->m_bindings.count())
- return false;
+ // This can become a hot code path. Therefore we do not iterate and call
+ // isLayoutCompatible() on m_bindings, but rather check a pre-calculated
+ // hash code and then, if the hash matched, do a uint array comparison
+ // (that's still more cache friendly).
- for (int i = 0; i < count; ++i) {
- if (!m_bindings[i].isLayoutCompatible(other->m_bindings.at(i)))
- return false;
- }
+ return m_layoutDescHash == other->m_layoutDescHash
+ && m_layoutDesc == other->m_layoutDesc;
+}
- return true;
+void QRhiImplementation::updateLayoutDesc(QRhiShaderResourceBindings *srb)
+{
+ srb->m_layoutDescHash = 0;
+ srb->m_layoutDesc.clear();
+ for (const QRhiShaderResourceBinding &b : qAsConst(srb->m_bindings)) {
+ const QRhiShaderResourceBinding::Data *d = b.data();
+ // must match QRhiShaderResourceBinding::isLayoutCompatible()
+ srb->m_layoutDescHash ^= uint(d->binding) ^ uint(d->stage) ^ uint(d->type);
+ srb->m_layoutDesc << uint(d->binding) << uint(d->stage) << uint(d->type);
+ }
}
/*!
diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h
index 1d0b6ebfab..d3e32f2723 100644
--- a/src/gui/rhi/qrhi_p.h
+++ b/src/gui/rhi/qrhi_p.h
@@ -1012,7 +1012,10 @@ public:
protected:
QRhiShaderResourceBindings(QRhiImplementation *rhi);
- QVarLengthArray<QRhiShaderResourceBinding, 8> m_bindings;
+ QVarLengthArray<QRhiShaderResourceBinding, 16> m_bindings;
+ uint m_layoutDescHash = 0;
+ QVarLengthArray<uint, 16 * 3> m_layoutDesc;
+ friend class QRhiImplementation;
#ifndef QT_NO_DEBUG_STREAM
friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiShaderResourceBindings &);
#endif
diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h
index 0128fd2d4e..51b3645b9d 100644
--- a/src/gui/rhi/qrhi_p_p.h
+++ b/src/gui/rhi/qrhi_p_p.h
@@ -211,6 +211,7 @@ public:
bool sanityCheckGraphicsPipeline(QRhiGraphicsPipeline *ps);
bool sanityCheckShaderResourceBindings(QRhiShaderResourceBindings *srb);
+ void updateLayoutDesc(QRhiShaderResourceBindings *srb);
QRhi *q;
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index 2dc5763bd9..1c7f3cd17a 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -3456,6 +3456,8 @@ bool QD3D11ShaderResourceBindings::create()
if (!rhiD->sanityCheckShaderResourceBindings(this))
return false;
+ rhiD->updateLayoutDesc(this);
+
std::copy(m_bindings.cbegin(), m_bindings.cend(), std::back_inserter(sortedBindings));
std::sort(sortedBindings.begin(), sortedBindings.end(),
[](const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b)
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index 3405465d54..95f4e02976 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -4307,6 +4307,8 @@ bool QGles2ShaderResourceBindings::create()
if (!rhiD->sanityCheckShaderResourceBindings(this))
return false;
+ rhiD->updateLayoutDesc(this);
+
generation += 1;
return true;
}
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index 7bcb6864d6..9058a7556a 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -3013,6 +3013,8 @@ bool QMetalShaderResourceBindings::create()
if (!rhiD->sanityCheckShaderResourceBindings(this))
return false;
+ rhiD->updateLayoutDesc(this);
+
std::copy(m_bindings.cbegin(), m_bindings.cend(), std::back_inserter(sortedBindings));
std::sort(sortedBindings.begin(), sortedBindings.end(),
[](const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b)
diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp
index 087559728d..e0eb110c0d 100644
--- a/src/gui/rhi/qrhinull.cpp
+++ b/src/gui/rhi/qrhinull.cpp
@@ -800,6 +800,12 @@ void QNullShaderResourceBindings::destroy()
bool QNullShaderResourceBindings::create()
{
+ QRHI_RES_RHI(QRhiNull);
+ if (!rhiD->sanityCheckShaderResourceBindings(this))
+ return false;
+
+ rhiD->updateLayoutDesc(this);
+
return true;
}
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index 7abfe37be1..73aa32f08b 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -6186,6 +6186,8 @@ bool QVkShaderResourceBindings::create()
if (!rhiD->sanityCheckShaderResourceBindings(this))
return false;
+ rhiD->updateLayoutDesc(this);
+
for (int i = 0; i < QVK_FRAMES_IN_FLIGHT; ++i)
descSets[i] = VK_NULL_HANDLE;