summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2021-09-02 15:27:22 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2021-09-03 17:14:59 +0200
commit69065160048335b8f5e2e3d0ba254a2065c51c5d (patch)
tree865e572355c1f860562b2b4badadfe01639e6fe2
parentc104af4c44dcbe9be23f2cc0259d39fe4f2d1c70 (diff)
rhi: Add a way to tell an srb that only the resources have changed
Until now, after updating the bindings one had to always rebuild the srb, which can be heavy esp. on Vulkan (release old objects, create new layout object, descriptor sets). When updating the binding list in a way that it is fully isLayoutCompatible() == true with the previous list, this is an overkill. Internally, most notably in setShaderResources(), we already should have everything in place in all backends to recognize if the entries in the binding list refer to QRhiBuffer/Texture/Sampler objects that are different than before, and so apart from adding an alternative to create() in the API there is not much else needed here. Pick-to: 6.2 Change-Id: I2efdd4fd0b24c7ebba694a975ed83509744b044b Reviewed-by: Andy Nichols <andy.nichols@qt.io>
-rw-r--r--src/gui/rhi/qrhi_p.h9
-rw-r--r--src/gui/rhi/qrhid3d11.cpp15
-rw-r--r--src/gui/rhi/qrhid3d11_p_p.h1
-rw-r--r--src/gui/rhi/qrhigles2.cpp6
-rw-r--r--src/gui/rhi/qrhigles2_p_p.h1
-rw-r--r--src/gui/rhi/qrhimetal.mm15
-rw-r--r--src/gui/rhi/qrhimetal_p_p.h1
-rw-r--r--src/gui/rhi/qrhinull.cpp5
-rw-r--r--src/gui/rhi/qrhinull_p_p.h1
-rw-r--r--src/gui/rhi/qrhivulkan.cpp15
-rw-r--r--src/gui/rhi/qrhivulkan_p_p.h1
11 files changed, 70 insertions, 0 deletions
diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h
index 1f05b7da8a..1e570e8818 100644
--- a/src/gui/rhi/qrhi_p.h
+++ b/src/gui/rhi/qrhi_p.h
@@ -1039,6 +1039,13 @@ public:
virtual bool create() = 0;
+ enum UpdateFlag {
+ BindingsAreSorted = 0x01
+ };
+ Q_DECLARE_FLAGS(UpdateFlags, UpdateFlag)
+
+ virtual void updateResources(UpdateFlags flags = {}) = 0;
+
protected:
static const int BINDING_PREALLOC = 12;
static const int LAYOUT_DESC_FIELD_COUNT = 4;
@@ -1052,6 +1059,8 @@ protected:
#endif
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiShaderResourceBindings::UpdateFlags)
+
#ifndef QT_NO_DEBUG_STREAM
Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiShaderResourceBindings &);
#endif
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index bdbb6f538b..b2bc631569 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -3622,6 +3622,21 @@ bool QD3D11ShaderResourceBindings::create()
return true;
}
+void QD3D11ShaderResourceBindings::updateResources(UpdateFlags flags)
+{
+ sortedBindings.clear();
+ std::copy(m_bindings.cbegin(), m_bindings.cend(), std::back_inserter(sortedBindings));
+ if (!flags.testFlag(BindingsAreSorted)) {
+ std::sort(sortedBindings.begin(), sortedBindings.end(),
+ [](const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b)
+ {
+ return a.data()->binding < b.data()->binding;
+ });
+ }
+
+ generation += 1;
+}
+
QD3D11GraphicsPipeline::QD3D11GraphicsPipeline(QRhiImplementation *rhi)
: QRhiGraphicsPipeline(rhi)
{
diff --git a/src/gui/rhi/qrhid3d11_p_p.h b/src/gui/rhi/qrhid3d11_p_p.h
index 0695259612..63705ccd0e 100644
--- a/src/gui/rhi/qrhid3d11_p_p.h
+++ b/src/gui/rhi/qrhid3d11_p_p.h
@@ -213,6 +213,7 @@ struct QD3D11ShaderResourceBindings : public QRhiShaderResourceBindings
~QD3D11ShaderResourceBindings();
void destroy() override;
bool create() override;
+ void updateResources(UpdateFlags flags) override;
bool hasDynamicOffset = false;
QVarLengthArray<QRhiShaderResourceBinding, 8> sortedBindings;
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index e611bde2f3..3e2e2ea2c8 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -4992,6 +4992,12 @@ bool QGles2ShaderResourceBindings::create()
return true;
}
+void QGles2ShaderResourceBindings::updateResources(UpdateFlags flags)
+{
+ Q_UNUSED(flags);
+ generation += 1;
+}
+
QGles2GraphicsPipeline::QGles2GraphicsPipeline(QRhiImplementation *rhi)
: QRhiGraphicsPipeline(rhi)
{
diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h
index d55a32fefe..ae5c90be24 100644
--- a/src/gui/rhi/qrhigles2_p_p.h
+++ b/src/gui/rhi/qrhigles2_p_p.h
@@ -251,6 +251,7 @@ struct QGles2ShaderResourceBindings : public QRhiShaderResourceBindings
~QGles2ShaderResourceBindings();
void destroy() override;
bool create() override;
+ void updateResources(UpdateFlags flags) override;
bool hasDynamicOffset = false;
uint generation = 0;
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index c817d8bae3..254f09ae08 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -3179,6 +3179,21 @@ bool QMetalShaderResourceBindings::create()
return true;
}
+void QMetalShaderResourceBindings::updateResources(UpdateFlags flags)
+{
+ sortedBindings.clear();
+ std::copy(m_bindings.cbegin(), m_bindings.cend(), std::back_inserter(sortedBindings));
+ if (!flags.testFlag(BindingsAreSorted)) {
+ std::sort(sortedBindings.begin(), sortedBindings.end(),
+ [](const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b)
+ {
+ return a.data()->binding < b.data()->binding;
+ });
+ }
+
+ generation += 1;
+}
+
QMetalGraphicsPipeline::QMetalGraphicsPipeline(QRhiImplementation *rhi)
: QRhiGraphicsPipeline(rhi),
d(new QMetalGraphicsPipelineData)
diff --git a/src/gui/rhi/qrhimetal_p_p.h b/src/gui/rhi/qrhimetal_p_p.h
index eed9afc9f1..2aafde7c0d 100644
--- a/src/gui/rhi/qrhimetal_p_p.h
+++ b/src/gui/rhi/qrhimetal_p_p.h
@@ -195,6 +195,7 @@ struct QMetalShaderResourceBindings : public QRhiShaderResourceBindings
~QMetalShaderResourceBindings();
void destroy() override;
bool create() override;
+ void updateResources(UpdateFlags flags) override;
QVarLengthArray<QRhiShaderResourceBinding, 8> sortedBindings;
int maxBinding = -1;
diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp
index cfcbf09d91..4706b37461 100644
--- a/src/gui/rhi/qrhinull.cpp
+++ b/src/gui/rhi/qrhinull.cpp
@@ -902,6 +902,11 @@ bool QNullShaderResourceBindings::create()
return true;
}
+void QNullShaderResourceBindings::updateResources(UpdateFlags flags)
+{
+ Q_UNUSED(flags);
+}
+
QNullGraphicsPipeline::QNullGraphicsPipeline(QRhiImplementation *rhi)
: QRhiGraphicsPipeline(rhi)
{
diff --git a/src/gui/rhi/qrhinull_p_p.h b/src/gui/rhi/qrhinull_p_p.h
index ddc75d7716..5905047fda 100644
--- a/src/gui/rhi/qrhinull_p_p.h
+++ b/src/gui/rhi/qrhinull_p_p.h
@@ -155,6 +155,7 @@ struct QNullShaderResourceBindings : public QRhiShaderResourceBindings
~QNullShaderResourceBindings();
void destroy() override;
bool create() override;
+ void updateResources(UpdateFlags flags) override;
};
struct QNullGraphicsPipeline : public QRhiGraphicsPipeline
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index 20e7c2f626..43619d4299 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -6625,6 +6625,21 @@ bool QVkShaderResourceBindings::create()
return true;
}
+void QVkShaderResourceBindings::updateResources(UpdateFlags flags)
+{
+ sortedBindings.clear();
+ std::copy(m_bindings.cbegin(), m_bindings.cend(), std::back_inserter(sortedBindings));
+ if (!flags.testFlag(BindingsAreSorted)) {
+ std::sort(sortedBindings.begin(), sortedBindings.end(),
+ [](const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b)
+ {
+ return a.data()->binding < b.data()->binding;
+ });
+ }
+
+ generation += 1;
+}
+
QVkGraphicsPipeline::QVkGraphicsPipeline(QRhiImplementation *rhi)
: QRhiGraphicsPipeline(rhi)
{
diff --git a/src/gui/rhi/qrhivulkan_p_p.h b/src/gui/rhi/qrhivulkan_p_p.h
index af647bb508..52473891d1 100644
--- a/src/gui/rhi/qrhivulkan_p_p.h
+++ b/src/gui/rhi/qrhivulkan_p_p.h
@@ -252,6 +252,7 @@ struct QVkShaderResourceBindings : public QRhiShaderResourceBindings
~QVkShaderResourceBindings();
void destroy() override;
bool create() override;
+ void updateResources(UpdateFlags flags) override;
QVarLengthArray<QRhiShaderResourceBinding, 8> sortedBindings;
bool hasSlottedResource = false;