aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-03-03 13:17:40 +0100
committerAndy Nichols <andy.nichols@theqtcompany.com>2016-03-04 10:49:52 +0000
commit966d79f2421f2d0904a0ad0a7e600f3f2e818efd (patch)
tree82a1638396b02cc710ec6421602d2b3546699344
parent6c7fed47e30799276e675355c90d46348b40fdd2 (diff)
D3D12: Let there be smoothness
Rounded rectangles are now smooth and beautiful. Change-Id: I3ea61934be7c10ef01fa5c2b14dc28705a429b61 Reviewed-by: Andy Nichols <andy.nichols@theqtcompany.com>
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12material.cpp69
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12material_p.h17
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode.cpp11
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode_p.h3
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp9
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/shaders/shaders.pri13
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/shaders/smoothcolor.hlsl64
-rw-r--r--src/quick/scenegraph/qsgdefaultrectanglenode.cpp6
-rw-r--r--tests/manual/nodetypes/Rects.qml11
9 files changed, 188 insertions, 15 deletions
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material.cpp
index d5b5861280..69160fa6b2 100644
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material.cpp
+++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material.cpp
@@ -42,6 +42,8 @@
#include "vs_vertexcolor.hlslh"
#include "ps_vertexcolor.hlslh"
+#include "vs_smoothcolor.hlslh"
+#include "ps_smoothcolor.hlslh"
QT_BEGIN_NAMESPACE
@@ -160,4 +162,71 @@ QSGD3D12Material::UpdateResults QSGD3D12VertexColorMaterial::updatePipeline(cons
return r;
}
+QSGD3D12SmoothColorMaterial::QSGD3D12SmoothColorMaterial()
+{
+ setFlag(RequiresFullMatrixExceptTranslate, true);
+ setFlag(Blending, true);
+}
+
+QSGMaterialType QSGD3D12SmoothColorMaterial::mtype;
+
+QSGMaterialType *QSGD3D12SmoothColorMaterial::type() const
+{
+ return &QSGD3D12SmoothColorMaterial::mtype;
+}
+
+int QSGD3D12SmoothColorMaterial::compare(const QSGMaterial *other) const
+{
+ Q_ASSERT(other && type() == other->type());
+ return 0;
+}
+
+static const int SMOOTH_COLOR_CB_SIZE_0 = 16 * sizeof(float); // float4x4
+static const int SMOOTH_COLOR_CB_SIZE_1 = sizeof(float); // float
+static const int SMOOTH_COLOR_CB_SIZE_2 = 2 * sizeof(float); // float2
+static const int SMOOTH_COLOR_CB_SIZE = SMOOTH_COLOR_CB_SIZE_0 + SMOOTH_COLOR_CB_SIZE_1 + SMOOTH_COLOR_CB_SIZE_2;
+
+int QSGD3D12SmoothColorMaterial::constantBufferSize() const
+{
+ return QSGD3D12Engine::alignedConstantBufferSize(SMOOTH_COLOR_CB_SIZE);
+}
+
+void QSGD3D12SmoothColorMaterial::preparePipeline(QSGD3D12ShaderState *shaders)
+{
+ shaders->vs = g_VS_SmoothColor;
+ shaders->vsSize = sizeof(g_VS_SmoothColor);
+ shaders->ps = g_PS_SmoothColor;
+ shaders->psSize = sizeof(g_PS_SmoothColor);
+}
+
+QSGD3D12Material::UpdateResults QSGD3D12SmoothColorMaterial::updatePipeline(const RenderState &state,
+ QSGD3D12ShaderState *,
+ quint8 *constantBuffer)
+{
+ QSGD3D12Material::UpdateResults r = 0;
+ quint8 *p = constantBuffer;
+
+ if (state.isMatrixDirty()) {
+ memcpy(p, state.combinedMatrix().constData(), SMOOTH_COLOR_CB_SIZE_0);
+ r |= UpdatedConstantBuffer;
+ }
+ p += SMOOTH_COLOR_CB_SIZE_0;
+
+ if (state.isOpacityDirty()) {
+ const float opacity = state.opacity();
+ memcpy(p, &opacity, SMOOTH_COLOR_CB_SIZE_1);
+ r |= UpdatedConstantBuffer;
+ }
+ p += SMOOTH_COLOR_CB_SIZE_1;
+
+ if (state.isMatrixDirty()) {
+ const QRect viewport = state.viewportRect();
+ const float v[] = { 2.0f / viewport.width(), 2.0f / viewport.height() };
+ memcpy(p, v, SMOOTH_COLOR_CB_SIZE_2);
+ r |= UpdatedConstantBuffer;
+ }
+
+ return r;
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material_p.h
index d61b1e94dc..8821950f32 100644
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material_p.h
+++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material_p.h
@@ -128,6 +128,23 @@ private:
static QSGMaterialType mtype;
};
+class QSGD3D12SmoothColorMaterial : public QSGD3D12Material
+{
+public:
+ QSGD3D12SmoothColorMaterial();
+ QSGMaterialType *type() const override;
+ int compare(const QSGMaterial *other) const override;
+
+ virtual int constantBufferSize() const override;
+ void preparePipeline(QSGD3D12ShaderState *shaders) override;
+ UpdateResults updatePipeline(const RenderState &state,
+ QSGD3D12ShaderState *shaders,
+ quint8 *constantBuffer) override;
+
+private:
+ static QSGMaterialType mtype;
+};
+
QT_END_NAMESPACE
#endif // QSGD3D12MATERIAL_P_H
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode.cpp
index 4a537731ce..7548f5cbc0 100644
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode.cpp
+++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode.cpp
@@ -46,16 +46,11 @@ QSGD3D12RectangleNode::QSGD3D12RectangleNode()
setMaterial(&m_material);
}
-bool QSGD3D12RectangleNode::supportsAntialiasing() const
-{
- return false; // ###
-}
-
void QSGD3D12RectangleNode::updateMaterialAntialiasing()
{
- //if (m_antialiasing)
- // setMaterial(&m_smoothMaterial);
- //else
+ if (m_antialiasing)
+ setMaterial(&m_smoothMaterial);
+ else
setMaterial(&m_material);
}
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode_p.h
index dfabb4f832..efec76e112 100644
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode_p.h
+++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode_p.h
@@ -62,12 +62,11 @@ public:
QSGD3D12RectangleNode();
private:
- bool supportsAntialiasing() const;
void updateMaterialAntialiasing() override;
void updateMaterialBlending(QSGNode::DirtyState *state) override;
QSGD3D12VertexColorMaterial m_material;
- //QSGD3D12Material m_smoothMaterial;
+ QSGD3D12SmoothColorMaterial m_smoothMaterial;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp
index 0842c1bea8..589b363f59 100644
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp
+++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp
@@ -475,7 +475,14 @@ void QSGD3D12Renderer::renderElement(int elementIndex)
setupClipping(gn, elementIndex);
- // ### line width / point size ??
+ // ### Lines and points with sizes other than 1 have to be implemented in some other way. Just ignore for now.
+ if (g->drawingMode() == QSGGeometry::DrawLineStrip || g->drawingMode() == QSGGeometry::DrawLines) {
+ if (g->lineWidth() != 1.0f)
+ qWarning("QSGD3D12Renderer: Line widths other than 1 are not supported by this renderer");
+ } else if (g->drawingMode() == QSGGeometry::DrawPoints) {
+ if (g->lineWidth() != 1.0f)
+ qWarning("QSGD3D12Renderer: Point sprites are not supported by this renderer");
+ }
m_engine->setPipelineState(m_pipelineState);
diff --git a/src/quick/scenegraph/adaptations/d3d12/shaders/shaders.pri b/src/quick/scenegraph/adaptations/d3d12/shaders/shaders.pri
index e7ea6cdde5..0f80405162 100644
--- a/src/quick/scenegraph/adaptations/d3d12/shaders/shaders.pri
+++ b/src/quick/scenegraph/adaptations/d3d12/shaders/shaders.pri
@@ -18,8 +18,19 @@ stencilclip_pshader.header = ps_stencilclip.hlslh
stencilclip_pshader.entry = PS_StencilClip
stencilclip_pshader.type = ps_5_0
+smoothcolor_VSPS = $$PWD/smoothcolor.hlsl
+smoothcolor_vshader.input = smoothcolor_VSPS
+smoothcolor_vshader.header = vs_smoothcolor.hlslh
+smoothcolor_vshader.entry = VS_SmoothColor
+smoothcolor_vshader.type = vs_5_0
+smoothcolor_pshader.input = smoothcolor_VSPS
+smoothcolor_pshader.header = ps_smoothcolor.hlslh
+smoothcolor_pshader.entry = PS_SmoothColor
+smoothcolor_pshader.type = ps_5_0
+
HLSL_SHADERS = \
vertexcolor_vshader vertexcolor_pshader \
- stencilclip_vshader stencilclip_pshader
+ stencilclip_vshader stencilclip_pshader \
+ smoothcolor_vshader smoothcolor_pshader
load(hlsl_bytecode_header)
diff --git a/src/quick/scenegraph/adaptations/d3d12/shaders/smoothcolor.hlsl b/src/quick/scenegraph/adaptations/d3d12/shaders/smoothcolor.hlsl
new file mode 100644
index 0000000000..4f69eea60f
--- /dev/null
+++ b/src/quick/scenegraph/adaptations/d3d12/shaders/smoothcolor.hlsl
@@ -0,0 +1,64 @@
+struct VSInput
+{
+ float4 position : POSITION;
+ float4 color : COLOR;
+ float2 offset : TEXCOORD0;
+};
+
+cbuffer ConstantBuffer : register(b0)
+{
+ float4x4 mvp;
+ float opacity;
+ float2 pixelSize;
+};
+
+struct PSInput
+{
+ float4 position : SV_POSITION;
+ float4 color : COLOR;
+};
+
+PSInput VS_SmoothColor(VSInput input)
+{
+ PSInput result;
+
+ float4 pos = mul(mvp, input.position);
+
+ if (input.offset.x != 0.0) {
+ // In HLSL matrix packing is column-major by default (which is good) but the math is row-major (unlike GLSL).
+ float4 delta = float4(mvp._11, mvp._21, mvp._31, mvp._41) * input.offset.x;
+ float2 dir = delta.xy * pos.w - pos.xy * delta.w;
+ float2 ndir = 0.5 * pixelSize * normalize(dir / pixelSize);
+ dir -= ndir * delta.w * pos.w;
+ float numerator = dot(dir, ndir * pos.w * pos.w);
+ float scale = 0.0;
+ if (numerator < 0.0)
+ scale = 1.0;
+ else
+ scale = min(1.0, numerator / dot(dir, dir));
+ pos += scale * delta;
+ }
+
+ if (input.offset.y != 0.0) {
+ float4 delta = float4(mvp._12, mvp._22, mvp._32, mvp._42) * input.offset.y;
+ float2 dir = delta.xy * pos.w - pos.xy * delta.w;
+ float2 ndir = 0.5 * pixelSize * normalize(dir / pixelSize);
+ dir -= ndir * delta.w * pos.w;
+ float numerator = dot(dir, ndir * pos.w * pos.w);
+ float scale = 0.0;
+ if (numerator < 0.0)
+ scale = 1.0;
+ else
+ scale = min(1.0, numerator / dot(dir, dir));
+ pos += scale * delta;
+ }
+
+ result.position = pos;
+ result.color = input.color * opacity;
+ return result;
+}
+
+float4 PS_SmoothColor(PSInput input) : SV_TARGET
+{
+ return input.color;
+}
diff --git a/src/quick/scenegraph/qsgdefaultrectanglenode.cpp b/src/quick/scenegraph/qsgdefaultrectanglenode.cpp
index 9e78847667..e4a6648bbd 100644
--- a/src/quick/scenegraph/qsgdefaultrectanglenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultrectanglenode.cpp
@@ -96,9 +96,9 @@ namespace
const QSGGeometry::AttributeSet &smoothAttributeSet()
{
static QSGGeometry::Attribute data[] = {
- QSGGeometry::Attribute::create(0, 2, QSGGeometry::TypeFloat, true),
- QSGGeometry::Attribute::create(1, 4, QSGGeometry::TypeUnsignedByte, false),
- QSGGeometry::Attribute::create(2, 2, QSGGeometry::TypeFloat, false)
+ QSGGeometry::Attribute::createWithSemantic(0, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::POSITION),
+ QSGGeometry::Attribute::createWithSemantic(1, 4, QSGGeometry::TypeUnsignedByte, QSGGeometry::Attribute::COLOR),
+ QSGGeometry::Attribute::createWithSemantic(2, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::TEXCOORD)
};
static QSGGeometry::AttributeSet attrs = { 3, sizeof(SmoothVertex), data };
return attrs;
diff --git a/tests/manual/nodetypes/Rects.qml b/tests/manual/nodetypes/Rects.qml
index a6eeb375d4..0d3a8cd459 100644
--- a/tests/manual/nodetypes/Rects.qml
+++ b/tests/manual/nodetypes/Rects.qml
@@ -123,4 +123,15 @@ Item {
}
}
}
+
+ Rectangle {
+ anchors.right: parent.right
+ width: 100
+ height: 100
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "red" }
+ GradientStop { position: 0.33; color: "yellow" }
+ GradientStop { position: 1.0; color: "green" }
+ }
+ }
}