summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick3d/imports/render/qt3dquick3drenderplugin.cpp1
-rw-r--r--src/render/materialsystem/qshaderprogram.cpp44
-rw-r--r--src/render/materialsystem/qshaderprogram.h11
-rw-r--r--src/render/materialsystem/qshaderprogram_p.h2
-rw-r--r--src/render/materialsystem/shader.cpp13
-rw-r--r--src/render/materialsystem/shader_p.h4
-rw-r--r--tests/auto/render/qshaderprogram/tst_qshaderprogram.cpp65
-rw-r--r--tests/auto/render/shader/tst_shader.cpp48
8 files changed, 185 insertions, 3 deletions
diff --git a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp
index e47d28f7c..8acd71715 100644
--- a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp
+++ b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp
@@ -187,6 +187,7 @@ void Qt3DQuick3DRenderPlugin::registerTypes(const char *uri)
Qt3DRender::Quick::registerExtendedType<Qt3DRender::QRenderPass, Qt3DRender::Render::Quick::Quick3DRenderPass>("QRenderPass", "Qt3D.Render/RenderPass", uri, 2, 0, "RenderPass");
qmlRegisterType<Qt3DRender::QShaderProgram>(uri, 2, 0, "ShaderProgram");
qmlRegisterType<Qt3DRender::QShaderProgram, 9>(uri, 2, 9, "ShaderProgram");
+ qmlRegisterType<Qt3DRender::QShaderProgram, 15>(uri, 2, 15, "ShaderProgram");
qmlRegisterType<Qt3DRender::QShaderProgramBuilder>(uri, 2, 10, "ShaderProgramBuilder");
qmlRegisterType<Qt3DRender::QShaderProgramBuilder, 13>(uri, 2, 13, "ShaderProgramBuilder");
qmlRegisterUncreatableType<Qt3DRender::QShaderData>(uri, 2, 0, "QShaderData", "Quick3D should instantiate Quick3DShaderData only");
diff --git a/src/render/materialsystem/qshaderprogram.cpp b/src/render/materialsystem/qshaderprogram.cpp
index c4e14ea2c..49117dd98 100644
--- a/src/render/materialsystem/qshaderprogram.cpp
+++ b/src/render/materialsystem/qshaderprogram.cpp
@@ -332,6 +332,17 @@
\value Error An error occurred while compiling the shader
*/
+/*!
+ \enum QShaderProgram::Format
+
+ This enum identifies the format of the shader code used.
+
+ \value GLSL OpenGL
+ \value SPIRV Vulkan, OpenGL 5
+
+ \since 5.15
+*/
+
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
@@ -339,6 +350,7 @@ namespace Qt3DRender {
QShaderProgramPrivate::QShaderProgramPrivate()
: QNodePrivate()
, m_status(QShaderProgram::NotReady)
+ , m_format(QShaderProgram::GLSL)
{
}
@@ -617,7 +629,7 @@ QString QShaderProgram::log() const
}
/*!
- \qmlproperty string ShaderProgram::status
+ \qmlproperty enumeration ShaderProgram::status
Holds the status of the current shader program.
*/
@@ -635,6 +647,35 @@ QShaderProgram::Status QShaderProgram::status() const
return d->m_status;
}
+void QShaderProgram::setFormat(QShaderProgram::Format format)
+{
+ Q_D(QShaderProgram);
+ if (format != d->m_format) {
+ d->m_format = format;
+ emit formatChanged(format);
+ }
+}
+
+/*!
+ \qmlproperty enumeration ShaderProgram::format
+ \since 5.15
+
+ Holds the format of the code provided on the ShaderProgram.
+ The default is ShaderProgram.GLSL
+*/
+/*!
+ \property QShaderProgram::format
+ \since 5.15
+
+ Holds the format of the code provided on the ShaderProgram.
+ The default is ShaderProgram.GLSL
+*/
+QShaderProgram::Format QShaderProgram::format() const
+{
+ Q_D(const QShaderProgram);
+ return d->m_format;
+}
+
QByteArray QShaderProgramPrivate::deincludify(const QString &filePath)
{
QFile f(filePath);
@@ -699,6 +740,7 @@ Qt3DCore::QNodeCreatedChangeBasePtr QShaderProgram::createNodeCreationChange() c
data.geometryShaderCode = d->m_geometryShaderCode;
data.fragmentShaderCode = d->m_fragmentShaderCode;
data.computeShaderCode = d->m_computeShaderCode;
+ data.format = d->m_format;
return creationChange;
}
diff --git a/src/render/materialsystem/qshaderprogram.h b/src/render/materialsystem/qshaderprogram.h
index 49c1076e5..1fc40a216 100644
--- a/src/render/materialsystem/qshaderprogram.h
+++ b/src/render/materialsystem/qshaderprogram.h
@@ -60,6 +60,7 @@ class Q_3DRENDERSHARED_EXPORT QShaderProgram : public Qt3DCore::QNode
Q_PROPERTY(QByteArray computeShaderCode READ computeShaderCode WRITE setComputeShaderCode NOTIFY computeShaderCodeChanged)
Q_PROPERTY(QString log READ log NOTIFY logChanged REVISION 9)
Q_PROPERTY(Status status READ status NOTIFY statusChanged REVISION 9)
+ Q_PROPERTY(Format format READ format WRITE setFormat NOTIFY formatChanged REVISION 15)
public:
explicit QShaderProgram(Qt3DCore::QNode *parent = nullptr);
@@ -82,6 +83,12 @@ public:
};
Q_ENUM(Status) // LCOV_EXCL_LINE
+ enum Format {
+ GLSL = 0,
+ SPIRV
+ };
+ Q_ENUM(Format) // LCOV_EXCL_LINE
+
// Source code in-line
QByteArray vertexShaderCode() const;
QByteArray tessellationControlShaderCode() const;
@@ -96,6 +103,9 @@ public:
QString log() const;
Status status() const;
+ void setFormat(Format format);
+ Format format() const;
+
Q_INVOKABLE static QByteArray loadSource(const QUrl &sourceUrl);
public Q_SLOTS:
@@ -115,6 +125,7 @@ Q_SIGNALS:
void computeShaderCodeChanged(const QByteArray &computeShaderCode);
void logChanged(const QString &log);
void statusChanged(Status status);
+ void formatChanged(Format format);
protected:
explicit QShaderProgram(QShaderProgramPrivate &dd, Qt3DCore::QNode *parent = nullptr);
diff --git a/src/render/materialsystem/qshaderprogram_p.h b/src/render/materialsystem/qshaderprogram_p.h
index f09b2a30e..d377ef039 100644
--- a/src/render/materialsystem/qshaderprogram_p.h
+++ b/src/render/materialsystem/qshaderprogram_p.h
@@ -72,6 +72,7 @@ public:
QByteArray m_computeShaderCode;
QString m_log;
QShaderProgram::Status m_status;
+ QShaderProgram::Format m_format;
void setLog(const QString &log);
void setStatus(QShaderProgram::Status status);
@@ -88,6 +89,7 @@ struct QShaderProgramData
QByteArray geometryShaderCode;
QByteArray fragmentShaderCode;
QByteArray computeShaderCode;
+ QShaderProgram::Format format;
};
} // namespace Qt3DRender
diff --git a/src/render/materialsystem/shader.cpp b/src/render/materialsystem/shader.cpp
index 00d9d334f..d0069bb4a 100644
--- a/src/render/materialsystem/shader.cpp
+++ b/src/render/materialsystem/shader.cpp
@@ -86,6 +86,7 @@ Shader::Shader()
: BackendNode(ReadWrite)
, m_requiresFrontendSync(false)
, m_status(QShaderProgram::NotReady)
+ , m_format(QShaderProgram::GLSL)
, m_dirty(false)
{
m_shaderCode.resize(static_cast<int>(QShaderProgram::Compute) + 1);
@@ -99,6 +100,7 @@ void Shader::cleanup()
{
QBackendNode::setEnabled(false);
m_status = QShaderProgram::NotReady;
+ m_format = QShaderProgram::GLSL;
m_log.clear();
m_dirty = false;
}
@@ -121,6 +123,7 @@ void Shader::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
if (code != m_shaderCode.value(shaderType))
setShaderCode(shaderType, code);
}
+ setFormat(node->format());
}
void Shader::setShaderCode(QShaderProgram::ShaderType type, const QByteArray &code)
@@ -135,6 +138,16 @@ void Shader::setShaderCode(QShaderProgram::ShaderType type, const QByteArray &co
markDirty(AbstractRenderer::ShadersDirty);
}
+void Shader::setFormat(QShaderProgram::Format format)
+{
+ if (format == m_format)
+ return;
+ m_format = format;
+ m_dirty = true;
+ setStatus(QShaderProgram::NotReady);
+ markDirty(AbstractRenderer::ShadersDirty);
+}
+
QVector<QByteArray> Shader::shaderCode() const
{
return m_shaderCode;
diff --git a/src/render/materialsystem/shader_p.h b/src/render/materialsystem/shader_p.h
index 8b1941d2c..23d57f25d 100644
--- a/src/render/materialsystem/shader_p.h
+++ b/src/render/materialsystem/shader_p.h
@@ -105,6 +105,9 @@ public:
inline QString log() const { return m_log; }
inline QShaderProgram::Status status() const { return m_status; }
+
+ void setFormat(QShaderProgram::Format format);
+ QShaderProgram::Format format() const { return m_format; }
bool isDirty() const { return m_dirty; }
void unsetDirty() { m_dirty = false; }
@@ -117,6 +120,7 @@ private:
QString m_log;
QShaderProgram::Status m_status;
bool m_requiresFrontendSync;
+ QShaderProgram::Format m_format;
bool m_dirty;
void initializeFromReference(const Shader &other);
diff --git a/tests/auto/render/qshaderprogram/tst_qshaderprogram.cpp b/tests/auto/render/qshaderprogram/tst_qshaderprogram.cpp
index 18dd1306a..15be26e8e 100644
--- a/tests/auto/render/qshaderprogram/tst_qshaderprogram.cpp
+++ b/tests/auto/render/qshaderprogram/tst_qshaderprogram.cpp
@@ -45,6 +45,13 @@ class tst_QShaderProgram : public Qt3DRender::QShaderProgram
{
Q_OBJECT
+public:
+ tst_QShaderProgram()
+ : Qt3DRender::QShaderProgram()
+ {
+ qRegisterMetaType<Qt3DRender::QShaderProgram::Format>("Format");
+ }
+
private Q_SLOTS:
void checkDefaultConstruction()
@@ -61,6 +68,7 @@ private Q_SLOTS:
QCOMPARE(shaderProgram.computeShaderCode(), QByteArray());
QCOMPARE(shaderProgram.log(), QString());
QCOMPARE(shaderProgram.status(), Qt3DRender::QShaderProgram::NotReady);
+ QCOMPARE(shaderProgram.format(), Qt3DRender::QShaderProgram::GLSL);
}
void checkPropertyChanges()
@@ -182,6 +190,25 @@ private Q_SLOTS:
QCOMPARE(shaderProgram.computeShaderCode(), newValue);
QCOMPARE(spy.count(), 0);
}
+ {
+ // WHEN
+ QSignalSpy spy(&shaderProgram, SIGNAL(formatChanged(Format)));
+ const QShaderProgram::Format newValue = QShaderProgram::SPIRV;
+ shaderProgram.setFormat(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(shaderProgram.format(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ shaderProgram.setFormat(newValue);
+
+ // THEN
+ QCOMPARE(shaderProgram.format(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
}
void checkCreationData()
@@ -195,6 +222,7 @@ private Q_SLOTS:
shaderProgram.setGeometryShaderCode(QByteArrayLiteral("Geometry"));
shaderProgram.setFragmentShaderCode(QByteArrayLiteral("Fragment"));
shaderProgram.setComputeShaderCode(QByteArrayLiteral("Compute"));
+ shaderProgram.setFormat(QShaderProgram::SPIRV);
// WHEN
QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
@@ -217,6 +245,7 @@ private Q_SLOTS:
QCOMPARE(shaderProgram.geometryShaderCode(), cloneData.geometryShaderCode);
QCOMPARE(shaderProgram.fragmentShaderCode(), cloneData.fragmentShaderCode);
QCOMPARE(shaderProgram.computeShaderCode(), cloneData.computeShaderCode);
+ QCOMPARE(shaderProgram.format(), cloneData.format);
QCOMPARE(shaderProgram.id(), creationChangeData->subjectId());
QCOMPARE(shaderProgram.isEnabled(), true);
QCOMPARE(shaderProgram.isEnabled(), creationChangeData->isNodeEnabled());
@@ -532,6 +561,42 @@ private Q_SLOTS:
// THEN
QVERIFY(mainContent.indexOf(includedContent) == 0);
}
+
+ void checkFormatPropertyUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QShaderProgram shaderProgram;
+ arbiter.setArbiterOnNode(&shaderProgram);
+
+ QSignalSpy spy(&shaderProgram, SIGNAL(formatChanged(Format)));
+
+ // THEN
+ QVERIFY(spy.isValid());
+
+ {
+ // WHEN
+ shaderProgram.setFormat(QShaderProgram::SPIRV);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(arbiter.events.size(), 0);
+
+ spy.clear();
+ }
+
+ {
+ // WHEN
+ shaderProgram.setFormat(QShaderProgram::SPIRV);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+ }
+
};
QTEST_MAIN(tst_QShaderProgram)
diff --git a/tests/auto/render/shader/tst_shader.cpp b/tests/auto/render/shader/tst_shader.cpp
index 3f0714907..a1f837010 100644
--- a/tests/auto/render/shader/tst_shader.cpp
+++ b/tests/auto/render/shader/tst_shader.cpp
@@ -42,15 +42,17 @@ private slots:
void cleanupLeavesACoherentState();
void dealWithPropertyChanges_data();
void dealWithPropertyChanges();
+ void dealWithFormatChanges();
void checkSetRendererDirtyOnInitialization();
void allowToChangeShaderCode_data();
void allowToChangeShaderCode();
};
-Qt3DRender::QShaderProgram *createFrontendShader()
+Qt3DRender::QShaderProgram *createFrontendShader(Qt3DRender::QShaderProgram::Format format = Qt3DRender::QShaderProgram::GLSL)
{
Qt3DRender::QShaderProgram *shader = new Qt3DRender::QShaderProgram();
+ shader->setFormat(format);
shader->setVertexShaderCode(QByteArrayLiteral(
"#version 150"\
@@ -80,6 +82,7 @@ void tst_RenderShader::hasCoherentInitialState()
Qt3DRender::Render::Shader *shader = new Qt3DRender::Render::Shader();
QCOMPARE(shader->status(), Qt3DRender::QShaderProgram::NotReady);
+ QCOMPARE(shader->format(), Qt3DRender::QShaderProgram::GLSL);
QVERIFY(shader->log().isEmpty());
QCOMPARE(shader->isDirty(), false);
}
@@ -97,11 +100,12 @@ void tst_RenderShader::matchesFrontendPeer()
for (int i = Qt3DRender::QShaderProgram::Vertex; i <= Qt3DRender::QShaderProgram::Compute; ++i)
QCOMPARE(backend.shaderCode()[i],
frontend->shaderCode(static_cast<Qt3DRender::QShaderProgram::ShaderType>(i)));
+ QCOMPARE(backend.format(), frontend->format());
}
void tst_RenderShader::cleanupLeavesACoherentState()
{
- QScopedPointer<Qt3DRender::QShaderProgram> frontend(createFrontendShader());
+ QScopedPointer<Qt3DRender::QShaderProgram> frontend(createFrontendShader(Qt3DRender::QShaderProgram::SPIRV));
TestRenderer renderer;
Qt3DRender::Render::Shader shader;
@@ -112,6 +116,7 @@ void tst_RenderShader::cleanupLeavesACoherentState()
QCOMPARE(shader.isDirty(), false);
QCOMPARE(shader.status(), Qt3DRender::QShaderProgram::NotReady);
+ QCOMPARE(shader.format(), Qt3DRender::QShaderProgram::GLSL);
}
void tst_RenderShader::dealWithPropertyChanges_data()
@@ -176,6 +181,45 @@ void tst_RenderShader::dealWithPropertyChanges()
QCOMPARE(backend.isDirty(), true);
}
+void tst_RenderShader::dealWithFormatChanges()
+{
+ // GIVEN
+ Qt3DRender::Render::Shader backend;
+ Qt3DRender::QShaderProgram shader;
+ TestRenderer renderer;
+ backend.setRenderer(&renderer);
+ simulateInitializationSync(&shader, &backend);
+
+ // WHEN
+ shader.setFormat(Qt3DRender::QShaderProgram::GLSL);
+ backend.syncFromFrontEnd(&shader, false);
+
+ // THEN
+ QCOMPARE(backend.format(), Qt3DRender::QShaderProgram::GLSL);
+ QCOMPARE(backend.isDirty(), false);
+ QCOMPARE(renderer.dirtyBits(), 0);
+
+ // WHEN
+ shader.setFormat(Qt3DRender::QShaderProgram::SPIRV);
+ backend.syncFromFrontEnd(&shader, false);
+
+ // THEN
+ QCOMPARE(backend.format(), Qt3DRender::QShaderProgram::SPIRV);
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ QCOMPARE(backend.isDirty(), true);
+
+ renderer.resetDirty();
+ backend.unsetDirty();
+
+ // WHEN
+ shader.setFormat(Qt3DRender::QShaderProgram::SPIRV);
+ backend.syncFromFrontEnd(&shader, false);
+
+ // THEN
+ QCOMPARE(backend.isDirty(), false);
+ QCOMPARE(renderer.dirtyBits(), 0);
+}
+
void tst_RenderShader::checkSetRendererDirtyOnInitialization()
{
// GIVEN