aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-04-28 15:49:26 +0200
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-04-29 09:36:43 +0000
commit3169744ab415268a9b6ff544d1bd49031ef3c08a (patch)
tree18362e5a8dd62ab940e82a9f055be50c75432866
parentcb1033fd603a438041a16ba55547d77133ad1e79 (diff)
D3D12: Fix 'ShaderEffect in a ShaderEffectSource as property value'
Import (and clean up) the dropshadow from the shadereffects example. This is very useful since it tests a lot more paths and cases than the wobble. To overcome the issue of not having some of functionality available before the item is added to a window, make QQuickGenericShaderEffect smarter and enhance the documentation. The handling of vertical mirroring is revised. The GLSL and HLSL version of the dropshadow shaders produce correct, identical output now. Change-Id: I94800997bfba781140d80720eb6f340cda480747 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp4
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12layer.cpp16
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp2
-rw-r--r--src/quick/items/qquickgenericshadereffect.cpp48
-rw-r--r--src/quick/items/qquickgenericshadereffect_p.h2
-rw-r--r--src/quick/items/qquickshadereffect.cpp67
-rw-r--r--src/quick/items/qquickshadereffect_p.h4
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer_p.h4
-rw-r--r--tests/manual/nodetypes/Effects.qml119
-rw-r--r--tests/manual/nodetypes/hlslcompile.bat6
-rw-r--r--tests/manual/nodetypes/nodetypes.pro3
-rw-r--r--tests/manual/nodetypes/nodetypes.qrc2
-rw-r--r--tests/manual/nodetypes/ps_shadow1.csobin0 -> 1600 bytes
-rw-r--r--tests/manual/nodetypes/ps_shadow2.csobin0 -> 1436 bytes
-rw-r--r--tests/manual/nodetypes/shadow1.hlsl18
-rw-r--r--tests/manual/nodetypes/shadow2.hlsl22
-rw-r--r--tests/manual/nodetypes/wobble.hlsl (renamed from tests/manual/nodetypes/effects.hlsl)0
17 files changed, 268 insertions, 49 deletions
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp
index 1fa443abec..62acb8d679 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp
@@ -1538,6 +1538,10 @@ void QSGD3D12EnginePrivate::finalizePipeline(const QSGD3D12PipelineState &pipeli
D3D12_ROOT_SIGNATURE_DESC desc;
desc.NumParameters = rootParamCount;
desc.pParameters = rootParams;
+ // Mixing up samplers and resource views in QSGD3D12TextureView means
+ // that the number of static samplers has to match the number of
+ // textures. This is not really ideal in general but works for Quick's use cases.
+ // The shaders can still choose to declare and use fewer samplers, if they want to.
desc.NumStaticSamplers = pipelineState.shaders.rootSig.textureViews.count();
D3D12_STATIC_SAMPLER_DESC staticSamplers[8];
int sdIdx = 0;
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12layer.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12layer.cpp
index 6e6b4854b3..ef2f923d5b 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12layer.cpp
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12layer.cpp
@@ -92,12 +92,10 @@ bool QSGD3D12Layer::hasMipmaps() const
QRectF QSGD3D12Layer::normalizedTextureSubRect() const
{
- // (0, 0) is the top-left corner, unlike OpenGL. Hence the inversion of
- // m_mirrorVertical, as opposed to the GL version.
return QRectF(m_mirrorHorizontal ? 1 : 0,
- m_mirrorVertical ? 1 : 0,
+ m_mirrorVertical ? 0 : 1,
m_mirrorHorizontal ? -1 : 1,
- m_mirrorVertical ? -1 : 1);
+ m_mirrorVertical ? 1 : -1);
}
void QSGD3D12Layer::bind()
@@ -339,10 +337,16 @@ void QSGD3D12Layer::updateContent()
m_renderer->setDeviceRect(m_size);
m_renderer->setViewportRect(m_size);
+
+ // Note that the handling of vertical mirroring differs from OpenGL here
+ // due to y running top-bottom with D3D as opposed to bottom-top with GL.
+ // The common parts of Quick follow OpenGL so vertical mirroring is
+ // typically enabled.
QRectF mirrored(m_mirrorHorizontal ? m_rect.right() : m_rect.left(),
- m_mirrorVertical ? m_rect.bottom() : m_rect.top(),
+ m_mirrorVertical ? m_rect.top() : m_rect.bottom(),
m_mirrorHorizontal ? -m_rect.width() : m_rect.width(),
- m_mirrorVertical ? -m_rect.height() : m_rect.height());
+ m_mirrorVertical ? m_rect.height() : -m_rect.height());
+
m_renderer->setProjectionMatrixToRect(mirrored);
m_renderer->setClearColor(Qt::transparent);
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp
index 36f5cf26be..856b49d2ac 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp
@@ -520,7 +520,7 @@ QSGD3D12ShaderEffectNode::QSGD3D12ShaderEffectNode(QSGD3D12RenderContext *rc, QS
QRectF QSGD3D12ShaderEffectNode::normalizedTextureSubRect() const
{
- return QRectF(0, 1, 1, -1); // ###
+ return QRectF(0, 0, 1, 1);
}
void QSGD3D12ShaderEffectNode::sync(SyncData *syncData)
diff --git a/src/quick/items/qquickgenericshadereffect.cpp b/src/quick/items/qquickgenericshadereffect.cpp
index ae34a65a2f..49ed25f799 100644
--- a/src/quick/items/qquickgenericshadereffect.cpp
+++ b/src/quick/items/qquickgenericshadereffect.cpp
@@ -61,6 +61,7 @@ QQuickGenericShaderEffect::QQuickGenericShaderEffect(QQuickShaderEffect *item, Q
, m_mgr(nullptr)
, m_dirty(0)
{
+ connect(m_item, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(itemWindowChanged(QQuickWindow*)));
}
QQuickGenericShaderEffect::~QQuickGenericShaderEffect()
@@ -76,7 +77,11 @@ QQuickGenericShaderEffect::~QQuickGenericShaderEffect()
void QQuickGenericShaderEffect::setFragmentShader(const QByteArray &src)
{
- if (m_fragShader.constData() == src.constData())
+ // Compare the actual values since they are often just filenames.
+ // Optimizing by comparing constData() is a bad idea since seemingly static
+ // strings in QML may in fact have different addresses when a binding
+ // triggers assigning the "same" value to the property.
+ if (m_fragShader == src)
return;
m_fragShader = src;
@@ -91,7 +96,7 @@ void QQuickGenericShaderEffect::setFragmentShader(const QByteArray &src)
void QQuickGenericShaderEffect::setVertexShader(const QByteArray &src)
{
- if (m_vertShader.constData() == src.constData())
+ if (m_vertShader == src)
return;
m_vertShader = src;
@@ -192,7 +197,7 @@ QQuickShaderEffect::Status QQuickGenericShaderEffect::status() const
{
QSGGuiThreadShaderEffectManager *mgr = shaderEffectManager();
if (!mgr)
- return QQuickShaderEffect::Error;
+ return QQuickShaderEffect::Uncompiled;
return QQuickShaderEffect::Status(mgr->status());
}
@@ -201,7 +206,7 @@ QQuickShaderEffect::ShaderType QQuickGenericShaderEffect::shaderType() const
{
QSGGuiThreadShaderEffectManager *mgr = shaderEffectManager();
if (!mgr)
- return QQuickShaderEffect::HLSL;
+ return QQuickShaderEffect::ShaderType(0);
return QQuickShaderEffect::ShaderType(mgr->shaderType());
}
@@ -210,7 +215,7 @@ QQuickShaderEffect::ShaderCompilationType QQuickGenericShaderEffect::shaderCompi
{
QSGGuiThreadShaderEffectManager *mgr = shaderEffectManager();
if (!mgr)
- return QQuickShaderEffect::OfflineCompilation;
+ return QQuickShaderEffect::ShaderCompilationType(0);
return QQuickShaderEffect::ShaderCompilationType(mgr->shaderCompilationType());
}
@@ -219,7 +224,7 @@ QQuickShaderEffect::ShaderSourceType QQuickGenericShaderEffect::shaderSourceType
{
QSGGuiThreadShaderEffectManager *mgr = shaderEffectManager();
if (!mgr)
- return QQuickShaderEffect::ShaderByteCode;
+ return QQuickShaderEffect::ShaderSourceType(0);
return QQuickShaderEffect::ShaderSourceType(mgr->shaderSourceType());
}
@@ -348,20 +353,41 @@ QSGGuiThreadShaderEffectManager *QQuickGenericShaderEffect::shaderEffectManager(
if (w && w->isSceneGraphInitialized()) {
m_mgr = QQuickWindowPrivate::get(w)->context->sceneGraphContext()->createGuiThreadShaderEffectManager();
if (m_mgr) {
- QObject::connect(m_mgr, SIGNAL(logAndStatusChanged()), m_item, SIGNAL(logChanged()));
- QObject::connect(m_mgr, SIGNAL(logAndStatusChanged()), m_item, SIGNAL(statusChanged()));
- QObject::connect(m_mgr, SIGNAL(textureChanged()), this, SLOT(markGeometryDirtyAndUpdateIfSupportsAtlas()));
+ connect(m_mgr, SIGNAL(logAndStatusChanged()), m_item, SIGNAL(logChanged()));
+ connect(m_mgr, SIGNAL(logAndStatusChanged()), m_item, SIGNAL(statusChanged()));
+ connect(m_mgr, SIGNAL(textureChanged()), this, SLOT(markGeometryDirtyAndUpdateIfSupportsAtlas()));
}
} else if (!w) {
- qWarning("ShaderEffect: Backend specifics cannot be queried until the item has a window");
+ // Wait until itemWindowChanged() gets called. Return null for now.
} else {
- qWarning("ShaderEffect: Backend specifics cannot be queried until the scenegraph has initialized");
+ // Have window, but no scenegraph -> ensure the signal is connected. Return null for now.
+ const_cast<QQuickGenericShaderEffect *>(this)->itemWindowChanged(w);
}
}
return m_mgr;
}
+void QQuickGenericShaderEffect::itemWindowChanged(QQuickWindow *w)
+{
+ if (w) {
+ if (w->isSceneGraphInitialized())
+ backendChanged();
+ else
+ connect(w, SIGNAL(sceneGraphInitialized()), this, SLOT(backendChanged()), Qt::UniqueConnection);
+ }
+}
+
+void QQuickGenericShaderEffect::backendChanged()
+{
+ disconnect(m_item->window(), SIGNAL(sceneGraphInitialized()), this, SLOT(backendChanged()));
+ emit m_item->logChanged();
+ emit m_item->statusChanged();
+ emit m_item->shaderTypeChanged();
+ emit m_item->shaderCompilationTypeChanged();
+ emit m_item->shaderSourceTypeChanged();
+}
+
void QQuickGenericShaderEffect::disconnectSignals(Shader shaderType)
{
for (auto &sm : m_signalMappers[shaderType]) {
diff --git a/src/quick/items/qquickgenericshadereffect_p.h b/src/quick/items/qquickgenericshadereffect_p.h
index 5f6652ec32..2af7d1156a 100644
--- a/src/quick/items/qquickgenericshadereffect_p.h
+++ b/src/quick/items/qquickgenericshadereffect_p.h
@@ -105,6 +105,8 @@ private slots:
void sourceDestroyed(QObject *object);
void markGeometryDirtyAndUpdate();
void markGeometryDirtyAndUpdateIfSupportsAtlas();
+ void itemWindowChanged(QQuickWindow *w);
+ void backendChanged();
private:
QSGGuiThreadShaderEffectManager *shaderEffectManager() const;
diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp
index 36fc7ef3c8..560c49fb7c 100644
--- a/src/quick/items/qquickshadereffect.cpp
+++ b/src/quick/items/qquickshadereffect.cpp
@@ -321,6 +321,12 @@ QT_BEGIN_NAMESPACE
\endcode
\endtable
+ \note With OpenGL the \c y coordinate runs from bottom to top whereas with
+ Direct 3D it goes top to bottom. For shader effect sources Qt Quick hides
+ the difference by treating QtQuick::ShaderEffectSource::textureMirroring as
+ appropriate, meaning texture coordinates in HLSL version of the shaders
+ will not need any adjustments compared to the equivalent GLSL code.
+
\section1 ShaderEffect and Item Layers
The ShaderEffect type can be combined with \l {Item Layers} {layered items}.
@@ -644,12 +650,23 @@ QQuickShaderEffect::Status QQuickShaderEffect::status() const
}
/*!
- \qmlproperty QtQuick::ShaderEffect::ShaderType QtQuick::ShaderEffect::shaderType
+ \qmlproperty enumeration QtQuick::ShaderEffect::shaderType
This property contains the shading language supported by the current Qt
Quick backend the application is using.
- With OpenGL the value is GLSL.
+ \list
+ \li ShaderEffect.UnknownShadingLanguage - Not yet known due to no window and scenegraph associated
+ \li ShaderEffect.GLSL - GLSL or GLSL ES
+ \li ShaderEffect.HLSL - HLSL
+ \endlist
+
+ \note The value is only up-to-date once the item is associated with a
+ window and the window's scenegraph has initialized. Bindings relying on the
+ value have to keep this in mind since the value may change from
+ ShaderEffect.UnknownShadingLanguage to the actual value after component
+ initialization is complete. This is particularly relevant for ShaderEffect
+ items inside ShaderEffectSource items set as property values.
\since 5.8
\since QtQuick 2.8
@@ -667,14 +684,26 @@ QQuickShaderEffect::ShaderType QQuickShaderEffect::shaderType() const
}
/*!
- \qmlproperty QtQuick::ShaderEffect::ShaderCompilationType QtQuick::ShaderEffect::shaderCompilationType
+ \qmlproperty enumeration QtQuick::ShaderEffect::shaderCompilationType
This property contains a bitmask of the shader compilation approaches
supported by the current Qt Quick backend the application is using.
- With OpenGL the value is RuntimeCompilation, which corresponds to the
- traditional way of using ShaderEffect. Non-OpenGL backends are expected to
- focus more on OfflineCompilation, however.
+ \list
+ \li ShaderEffect.RuntimeCompilation
+ \li ShaderEffect.OfflineCompilation
+ \endlist
+
+ With OpenGL the value is ShaderEffect.RuntimeCompilation, which corresponds
+ to the traditional way of using ShaderEffect. Non-OpenGL backends are
+ expected to focus more on ShaderEffect.OfflineCompilation, however.
+
+ \note The value is only up-to-date once the item is associated with a
+ window and the window's scenegraph has initialized. Bindings relying on the
+ value have to keep this in mind since the value may change from \c 0 to the
+ actual bitmask after component initialization is complete. This is
+ particularly relevant for ShaderEffect items inside ShaderEffectSource
+ items set as property values.
\since 5.8
\since QtQuick 2.8
@@ -692,16 +721,30 @@ QQuickShaderEffect::ShaderCompilationType QQuickShaderEffect::shaderCompilationT
}
/*!
- \qmlproperty QtQuick::ShaderEffect::ShaderSourceType QtQuick::ShaderEffect::shaderSourceType
+ \qmlproperty enumeration QtQuick::ShaderEffect::shaderSourceType
This property contains a bitmask of the supported ways of providing shader
sources.
- With OpenGL the value is ShaderSourceString, which corresponds to the
- traditional way of inlining GLSL source code into QML. Other, non-OpenGL Qt
- Quick backends may however decide not to support inlined shader sources, or
- even shader sources at all. In this case shaders are expected to be
- pre-compiled into formats like SPIR-V or D3D shader bytecode.
+ \list
+ \li ShaderEffect.ShaderSourceString
+ \li ShaderEffect.ShaderSourceFile
+ \li ShaderEffect.ShaderByteCode
+ \endlist
+
+ With OpenGL the value is ShaderEffect.ShaderSourceString, which corresponds
+ to the traditional way of inlining GLSL source code into QML. Other,
+ non-OpenGL Qt Quick backends may however decide not to support inlined
+ shader sources, or even shader sources at all. In this case shaders are
+ expected to be pre-compiled into formats like SPIR-V or D3D shader
+ bytecode.
+
+ \note The value is only up-to-date once the item is associated with a
+ window and the window's scenegraph has initialized. Bindings relying on the
+ value have to keep this in mind since the value may change from \c 0 to the
+ actual bitmask after component initialization is complete. This is
+ particularly relevant for ShaderEffect items inside ShaderEffectSource
+ items set as property values.
\since 5.8
\since QtQuick 2.8
diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h
index 390703350f..0410514c36 100644
--- a/src/quick/items/qquickshadereffect_p.h
+++ b/src/quick/items/qquickshadereffect_p.h
@@ -90,9 +90,9 @@ public:
Q_ENUM(Status)
enum ShaderType {
+ UnknownShadingLanguage,
GLSL,
- HLSL,
- Metal
+ HLSL
};
Q_ENUM(ShaderType)
diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index 09690acf56..296068e78b 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -230,9 +230,9 @@ class Q_QUICK_PRIVATE_EXPORT QSGGuiThreadShaderEffectManager : public QObject
public:
// Enum values must match ShaderEffect.
enum ShaderType {
+ UnknownShadingLanguage,
GLSL,
- HLSL,
- Metal
+ HLSL
};
enum ShaderCompilationType {
RuntimeCompilation = 0x01,
diff --git a/tests/manual/nodetypes/Effects.qml b/tests/manual/nodetypes/Effects.qml
index 8af9a5eb95..4503c49df1 100644
--- a/tests/manual/nodetypes/Effects.qml
+++ b/tests/manual/nodetypes/Effects.qml
@@ -47,26 +47,39 @@ Item {
anchors.margins: 10
anchors.fill: parent
Image {
- id: image
+ id: image1
source: "qrc:/qt.png"
}
ShaderEffectSource {
- id: effectSource
- sourceItem: image
+ id: effectSource1
+ sourceItem: image1
hideSource: true
}
- ShaderEffect {
- width: image.width
- height: image.height
+ ShaderEffect { // wobble
+ id: eff
+ width: image1.width
+ height: image1.height
anchors.centerIn: parent
- property variant source: effectSource
+ property variant source: effectSource1
property real amplitude: 0.04 * 0.2
property real frequency: 20
property real time: 0
NumberAnimation on time { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 600 }
+ property bool customVertexShader: false // the effect is fine with the default vs, but toggle this to test
+
+ property string glslVertexShader:
+ "uniform highp mat4 qt_Matrix;" +
+ "attribute highp vec4 qt_Vertex;" +
+ "attribute highp vec2 qt_MultiTexCoord0;" +
+ "varying highp vec2 qt_TexCoord0;" +
+ "void main() {" +
+ " qt_TexCoord0 = qt_MultiTexCoord0;" +
+ " gl_Position = qt_Matrix * qt_Vertex;" +
+ "}"
+
property string glslFragmentShader:
"uniform sampler2D source;" +
"uniform highp float amplitude;" +
@@ -82,11 +95,93 @@ Item {
property string hlslVertexShaderByteCode: "qrc:/vs_wobble.cso"
property string hlslPixelShaderByteCode: "qrc:/ps_wobble.cso"
- // This effect does not need a custom vertex shader but have one with HLSL just to test that path as well.
- vertexShader: shaderType === ShaderEffect.GLSL ? ""
- : (shaderType === ShaderEffect.HLSL ? hlslVertexShaderByteCode : "")
- fragmentShader: shaderType === ShaderEffect.GLSL ? glslFragmentShader
- : (shaderType === ShaderEffect.HLSL ? hlslPixelShaderByteCode : "")
+ vertexShader: customVertexShader ? (shaderType === ShaderEffect.HLSL ? hlslVertexShaderByteCode : (shaderType === ShaderEffect.GLSL ? glslVertexShader : "")) : ""
+
+ fragmentShader: shaderType === ShaderEffect.HLSL ? hlslPixelShaderByteCode : (shaderType === ShaderEffect.GLSL ? glslFragmentShader : "")
+ }
+
+ Image {
+ id: image2
+ source: "qrc:/face-smile.png"
+ }
+ ShaderEffectSource {
+ id: effectSource2
+ sourceItem: image2
+ hideSource: true
+ }
+ ShaderEffect { // dropshadow
+ id: eff2
+ width: image2.width
+ height: image2.height
+ scale: 2
+ x: 40
+ y: 40
+
+ property variant source: effectSource2
+
+ property string glslShaderPass1: "
+ uniform lowp float qt_Opacity;
+ uniform sampler2D source;
+ uniform highp vec2 delta;
+ varying highp vec2 qt_TexCoord0;
+ void main() {
+ gl_FragColor = (0.0538 * texture2D(source, qt_TexCoord0 - 3.182 * delta)
+ + 0.3229 * texture2D(source, qt_TexCoord0 - 1.364 * delta)
+ + 0.2466 * texture2D(source, qt_TexCoord0)
+ + 0.3229 * texture2D(source, qt_TexCoord0 + 1.364 * delta)
+ + 0.0538 * texture2D(source, qt_TexCoord0 + 3.182 * delta)) * qt_Opacity;
+ }"
+ property string glslShaderPass2: "
+ uniform lowp float qt_Opacity;
+ uniform highp vec2 offset;
+ uniform sampler2D source;
+ uniform sampler2D shadow;
+ uniform highp float darkness;
+ uniform highp vec2 delta;
+ varying highp vec2 qt_TexCoord0;
+ void main() {
+ lowp vec4 fg = texture2D(source, qt_TexCoord0);
+ lowp vec4 bg = texture2D(shadow, qt_TexCoord0 + delta);
+ gl_FragColor = (fg + vec4(0., 0., 0., darkness * bg.a) * (1. - fg.a)) * qt_Opacity;
+ }"
+
+ property variant shadow: ShaderEffectSource {
+ sourceItem: ShaderEffect {
+ width: eff2.width
+ height: eff2.height
+ property variant delta: Qt.size(0.0, 1.0 / height)
+ property variant source: ShaderEffectSource {
+ sourceItem: ShaderEffect {
+ id: innerEff
+ width: eff2.width
+ height: eff2.height
+ property variant delta: Qt.size(1.0 / width, 0.0)
+ property variant source: effectSource2
+ fragmentShader: shaderType === ShaderEffect.HLSL ? "qrc:/ps_shadow1.cso" : (shaderType === ShaderEffect.GLSL ? eff2.glslShaderPass1 : "")
+ }
+ }
+ fragmentShader: shaderType === ShaderEffect.HLSL ? "qrc:/ps_shadow1.cso" : (shaderType === ShaderEffect.GLSL ? eff2.glslShaderPass1: "")
+ }
+ }
+ property real angle: 0
+ property variant offset: Qt.point(5.0 * Math.cos(angle), 5.0 * Math.sin(angle))
+ NumberAnimation on angle { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 6000 }
+ property variant delta: Qt.size(offset.x / width, offset.y / height)
+ property real darkness: 0.5
+ fragmentShader: shaderType === ShaderEffect.HLSL ? "qrc:/ps_shadow2.cso" : (shaderType === ShaderEffect.GLSL ? glslShaderPass2 : "")
+ }
+
+ Column {
+ anchors.bottom: parent.bottom
+ Text {
+ color: "yellow"
+ font.pointSize: 24
+ text: "Shader effect is " + (eff.shaderType === ShaderEffect.HLSL ? "HLSL" : (eff.shaderType === ShaderEffect.GLSL ? "GLSL" : "UNKNOWN")) + " based";
+ }
+ Text {
+ // check the inner shader effect's properties as those only get updated later on, once a window gets associated
+ text: innerEff.shaderType + " " + innerEff.shaderCompilationType + " " + innerEff.shaderSourceType
+ }
}
}
}
diff --git a/tests/manual/nodetypes/hlslcompile.bat b/tests/manual/nodetypes/hlslcompile.bat
index 8f7ca86069..b24824e324 100644
--- a/tests/manual/nodetypes/hlslcompile.bat
+++ b/tests/manual/nodetypes/hlslcompile.bat
@@ -1,2 +1,4 @@
-fxc /E VS_Wobble /T vs_5_0 /Fo vs_wobble.cso effects.hlsl
-fxc /E PS_Wobble /T ps_5_0 /Fo ps_wobble.cso effects.hlsl
+fxc /E VS_Wobble /T vs_5_0 /Fo vs_wobble.cso wobble.hlsl
+fxc /E PS_Wobble /T ps_5_0 /Fo ps_wobble.cso wobble.hlsl
+fxc /E PS_Shadow1 /T ps_5_0 /Fo ps_shadow1.cso shadow1.hlsl
+fxc /E PS_Shadow2 /T ps_5_0 /Fo ps_shadow2.cso shadow2.hlsl
diff --git a/tests/manual/nodetypes/nodetypes.pro b/tests/manual/nodetypes/nodetypes.pro
index 51a6ac3e5a..43b79323a8 100644
--- a/tests/manual/nodetypes/nodetypes.pro
+++ b/tests/manual/nodetypes/nodetypes.pro
@@ -5,4 +5,5 @@ SOURCES += nodetypes.cpp
RESOURCES += nodetypes.qrc
OTHER_FILES += main.qml Rects.qml LotsOfRects.qml \
- Images.qml Text.qml Animators.qml Layers.qml Effects.qml effects.hlsl
+ Images.qml Text.qml Animators.qml Layers.qml Effects.qml \
+ wobble.hlsl shadow1.hlsl shadow2.hlsl
diff --git a/tests/manual/nodetypes/nodetypes.qrc b/tests/manual/nodetypes/nodetypes.qrc
index f6c007e3f3..64bd503319 100644
--- a/tests/manual/nodetypes/nodetypes.qrc
+++ b/tests/manual/nodetypes/nodetypes.qrc
@@ -13,5 +13,7 @@
<file>shadow.png</file>
<file>vs_wobble.cso</file>
<file>ps_wobble.cso</file>
+ <file>ps_shadow1.cso</file>
+ <file>ps_shadow2.cso</file>
</qresource>
</RCC>
diff --git a/tests/manual/nodetypes/ps_shadow1.cso b/tests/manual/nodetypes/ps_shadow1.cso
new file mode 100644
index 0000000000..b6fbe3f3c2
--- /dev/null
+++ b/tests/manual/nodetypes/ps_shadow1.cso
Binary files differ
diff --git a/tests/manual/nodetypes/ps_shadow2.cso b/tests/manual/nodetypes/ps_shadow2.cso
new file mode 100644
index 0000000000..ab8cb63f34
--- /dev/null
+++ b/tests/manual/nodetypes/ps_shadow2.cso
Binary files differ
diff --git a/tests/manual/nodetypes/shadow1.hlsl b/tests/manual/nodetypes/shadow1.hlsl
new file mode 100644
index 0000000000..ff3f4b6fd5
--- /dev/null
+++ b/tests/manual/nodetypes/shadow1.hlsl
@@ -0,0 +1,18 @@
+cbuffer ConstantBuffer : register(b0)
+{
+ float4x4 qt_Matrix;
+ float qt_Opacity;
+ float2 delta;
+};
+
+Texture2D source : register(t0);
+SamplerState sourceSampler : register(s0);
+
+float4 PS_Shadow1(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET
+{
+ return (0.0538 * source.Sample(sourceSampler, coord - 3.182 * delta)
+ + 0.3229 * source.Sample(sourceSampler, coord - 1.364 * delta)
+ + 0.2466 * source.Sample(sourceSampler, coord)
+ + 0.3229 * source.Sample(sourceSampler, coord + 1.364 * delta)
+ + 0.0538 * source.Sample(sourceSampler, coord + 3.182 * delta)) * qt_Opacity;
+}
diff --git a/tests/manual/nodetypes/shadow2.hlsl b/tests/manual/nodetypes/shadow2.hlsl
new file mode 100644
index 0000000000..eaa30cd988
--- /dev/null
+++ b/tests/manual/nodetypes/shadow2.hlsl
@@ -0,0 +1,22 @@
+cbuffer ConstantBuffer : register(b0)
+{
+ float4x4 qt_Matrix;
+ float qt_Opacity;
+ float2 offset;
+ float darkness;
+ float2 delta;
+};
+
+Texture2D source : register(t0);
+Texture2D shadow : register(t1);
+SamplerState samp : register(s0);
+// Use the same sampler for both textures. In fact the engine will create an extra static sampler
+// in any case (to match the number of textures) due to some internals, but that won't hurt, the
+// shader works either way.
+
+float4 PS_Shadow2(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET
+{
+ float4 fg = source.Sample(samp, coord);
+ float4 bg = shadow.Sample(samp, coord + delta);
+ return (fg + float4(0.0, 0.0, 0.0, darkness * bg.a) * (1.0 - fg.a)) * qt_Opacity;
+}
diff --git a/tests/manual/nodetypes/effects.hlsl b/tests/manual/nodetypes/wobble.hlsl
index 203dbda7f2..203dbda7f2 100644
--- a/tests/manual/nodetypes/effects.hlsl
+++ b/tests/manual/nodetypes/wobble.hlsl