diff options
author | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2016-03-03 13:17:40 +0100 |
---|---|---|
committer | Andy Nichols <andy.nichols@theqtcompany.com> | 2016-03-04 10:49:52 +0000 |
commit | 966d79f2421f2d0904a0ad0a7e600f3f2e818efd (patch) | |
tree | 82a1638396b02cc710ec6421602d2b3546699344 | |
parent | 6c7fed47e30799276e675355c90d46348b40fdd2 (diff) |
D3D12: Let there be smoothness
Rounded rectangles are now smooth and beautiful.
Change-Id: I3ea61934be7c10ef01fa5c2b14dc28705a429b61
Reviewed-by: Andy Nichols <andy.nichols@theqtcompany.com>
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" } + } + } } |