diff options
author | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2016-04-28 15:49:26 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2016-04-29 09:36:43 +0000 |
commit | 3169744ab415268a9b6ff544d1bd49031ef3c08a (patch) | |
tree | 18362e5a8dd62ab940e82a9f055be50c75432866 | |
parent | cb1033fd603a438041a16ba55547d77133ad1e79 (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.cpp | 4 | ||||
-rw-r--r-- | src/plugins/scenegraph/d3d12/qsgd3d12layer.cpp | 16 | ||||
-rw-r--r-- | src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquickgenericshadereffect.cpp | 48 | ||||
-rw-r--r-- | src/quick/items/qquickgenericshadereffect_p.h | 2 | ||||
-rw-r--r-- | src/quick/items/qquickshadereffect.cpp | 67 | ||||
-rw-r--r-- | src/quick/items/qquickshadereffect_p.h | 4 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgadaptationlayer_p.h | 4 | ||||
-rw-r--r-- | tests/manual/nodetypes/Effects.qml | 119 | ||||
-rw-r--r-- | tests/manual/nodetypes/hlslcompile.bat | 6 | ||||
-rw-r--r-- | tests/manual/nodetypes/nodetypes.pro | 3 | ||||
-rw-r--r-- | tests/manual/nodetypes/nodetypes.qrc | 2 | ||||
-rw-r--r-- | tests/manual/nodetypes/ps_shadow1.cso | bin | 0 -> 1600 bytes | |||
-rw-r--r-- | tests/manual/nodetypes/ps_shadow2.cso | bin | 0 -> 1436 bytes | |||
-rw-r--r-- | tests/manual/nodetypes/shadow1.hlsl | 18 | ||||
-rw-r--r-- | tests/manual/nodetypes/shadow2.hlsl | 22 | ||||
-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 Binary files differnew file mode 100644 index 0000000000..b6fbe3f3c2 --- /dev/null +++ b/tests/manual/nodetypes/ps_shadow1.cso diff --git a/tests/manual/nodetypes/ps_shadow2.cso b/tests/manual/nodetypes/ps_shadow2.cso Binary files differnew file mode 100644 index 0000000000..ab8cb63f34 --- /dev/null +++ b/tests/manual/nodetypes/ps_shadow2.cso 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 |