aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-04-12 13:41:35 +0200
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-04-13 09:22:24 +0000
commit8c68adb073cb48dfd873ce66793bd5e990af68d0 (patch)
treecebfe7ce6263e8f2e39c6c59bfb2d42ee1e28453 /src/quick
parentb943809c41cda9c01f26ba02ece4b6690b528d48 (diff)
Convert d3d12 backend into a plugin
Change-Id: I4300ba81800e44c0b5e2a86e72b1cf96434c323d Reviewed-by: Andy Nichols <andy.nichols@theqtcompany.com>
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/scenegraph/adaptations/adaptations.pri1
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/d3d12.pri40
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation.cpp76
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation_p.h78
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12builtinmaterials.cpp655
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12builtinmaterials_p.h236
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12context.cpp100
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12context_p.h76
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine.cpp2740
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p.h357
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p_p.h421
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphcache.cpp184
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphcache_p.h88
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphnode.cpp90
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphnode_p.h74
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12imagenode.cpp123
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12imagenode_p.h82
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer.cpp329
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer_p.h117
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12material.cpp106
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12material_p.h125
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode.cpp72
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode_p.h74
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext.cpp101
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext_p.h78
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp710
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer_p.h127
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop.cpp1101
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop_p.h129
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture.cpp134
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture_p.h90
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/shaders/mipmapgen.hlsl60
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/shaders/shaders.pri101
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/shaders/smoothcolor.hlsl64
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/shaders/smoothtexture.hlsl77
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/shaders/stencilclip.hlsl26
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/shaders/textmask.hlsl104
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/shaders/texture.hlsl33
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/shaders/vertexcolor.hlsl32
-rw-r--r--src/quick/scenegraph/qsgbasicglyphnode_p.h2
-rw-r--r--src/quick/scenegraph/qsgcontextplugin.cpp6
41 files changed, 1 insertions, 9218 deletions
diff --git a/src/quick/scenegraph/adaptations/adaptations.pri b/src/quick/scenegraph/adaptations/adaptations.pri
index a3738d6b82..40fa739e15 100644
--- a/src/quick/scenegraph/adaptations/adaptations.pri
+++ b/src/quick/scenegraph/adaptations/adaptations.pri
@@ -1,2 +1 @@
include(software/software.pri)
-config_d3d12: include(d3d12/d3d12.pri)
diff --git a/src/quick/scenegraph/adaptations/d3d12/d3d12.pri b/src/quick/scenegraph/adaptations/d3d12/d3d12.pri
deleted file mode 100644
index 1a24f84756..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/d3d12.pri
+++ /dev/null
@@ -1,40 +0,0 @@
-SOURCES += \
- $$PWD/qsgd3d12adaptation.cpp \
- $$PWD/qsgd3d12renderloop.cpp \
- $$PWD/qsgd3d12renderer.cpp \
- $$PWD/qsgd3d12context.cpp \
- $$PWD/qsgd3d12rendercontext.cpp \
- $$PWD/qsgd3d12rectanglenode.cpp \
- $$PWD/qsgd3d12material.cpp \
- $$PWD/qsgd3d12builtinmaterials.cpp \
- $$PWD/qsgd3d12texture.cpp \
- $$PWD/qsgd3d12imagenode.cpp \
- $$PWD/qsgd3d12glyphnode.cpp \
- $$PWD/qsgd3d12glyphcache.cpp \
- $$PWD/qsgd3d12layer.cpp
-
-NO_PCH_SOURCES += \
- $$PWD/qsgd3d12engine.cpp
-
-HEADERS += \
- $$PWD/qsgd3d12adaptation_p.h \
- $$PWD/qsgd3d12renderloop_p.h \
- $$PWD/qsgd3d12renderer_p.h \
- $$PWD/qsgd3d12context_p.h \
- $$PWD/qsgd3d12rendercontext_p.h \
- $$PWD/qsgd3d12engine_p.h \
- $$PWD/qsgd3d12engine_p_p.h \
- $$PWD/qsgd3d12rectanglenode_p.h \
- $$PWD/qsgd3d12material_p.h \
- $$PWD/qsgd3d12builtinmaterials_p.h \
- $$PWD/qsgd3d12texture_p.h \
- $$PWD/qsgd3d12imagenode_p.h \
- $$PWD/qsgd3d12glyphnode_p.h \
- $$PWD/qsgd3d12glyphcache_p.h \
- $$PWD/qsgd3d12layer_p.h
-
-LIBS += -ldxgi -ld3d12
-
-DEFINES += QSG_D3D12
-
-include($$PWD/shaders/shaders.pri)
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation.cpp
deleted file mode 100644
index ba1a88d34a..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12adaptation_p.h"
-#include "qsgd3d12renderloop_p.h"
-#include "qsgd3d12context_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QSGD3D12Adaptation::QSGD3D12Adaptation(QObject *parent)
- : QSGContextPlugin(parent)
-{
-}
-
-QStringList QSGD3D12Adaptation::keys() const
-{
- return QStringList() << QLatin1String("d3d12");
-}
-
-QSGContext *QSGD3D12Adaptation::create(const QString &) const
-{
- if (!contextInstance)
- contextInstance = new QSGD3D12Context;
-
- return contextInstance;
-}
-
-QSGContextFactoryInterface::Flags QSGD3D12Adaptation::flags(const QString &) const
-{
- return QSGContextFactoryInterface::SupportsShaderEffectV2;
-}
-
-QSGRenderLoop *QSGD3D12Adaptation::createWindowManager()
-{
- return new QSGD3D12RenderLoop;
-}
-
-QSGD3D12Context *QSGD3D12Adaptation::contextInstance = nullptr;
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation_p.h
deleted file mode 100644
index dbb408975d..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation_p.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12ADAPTATION_P_H
-#define QSGD3D12ADAPTATION_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qsgcontextplugin_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12Context;
-class QSGContext;
-class QSGRenderLoop;
-
-class QSGD3D12Adaptation : public QSGContextPlugin
-{
-public:
- QSGD3D12Adaptation(QObject *parent = 0);
-
- QStringList keys() const override;
- QSGContext *create(const QString &key) const override;
- QSGContextFactoryInterface::Flags flags(const QString &key) const override;
- QSGRenderLoop *createWindowManager() override;
-
-private:
- static QSGD3D12Context *contextInstance;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12ADAPTATION_P_H
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12builtinmaterials.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12builtinmaterials.cpp
deleted file mode 100644
index ab0c98a8cd..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12builtinmaterials.cpp
+++ /dev/null
@@ -1,655 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12builtinmaterials_p.h"
-#include "qsgd3d12rendercontext_p.h"
-#include <QQuickWindow>
-
-#include "vs_vertexcolor.hlslh"
-#include "ps_vertexcolor.hlslh"
-#include "vs_smoothcolor.hlslh"
-#include "ps_smoothcolor.hlslh"
-#include "vs_texture.hlslh"
-#include "ps_texture.hlslh"
-#include "vs_smoothtexture.hlslh"
-#include "ps_smoothtexture.hlslh"
-#include "vs_textmask.hlslh"
-#include "ps_textmask24.hlslh"
-#include "ps_textmask32.hlslh"
-#include "ps_textmask8.hlslh"
-#include "vs_styledtext.hlslh"
-#include "ps_styledtext.hlslh"
-#include "vs_outlinedtext.hlslh"
-#include "ps_outlinedtext.hlslh"
-
-QT_BEGIN_NAMESPACE
-
-// NB! In HLSL constant buffer data is packed into 4-byte boundaries and, more
-// importantly, it is packed so that it does not cross a 16-byte (float4)
-// boundary. Hence the need for padding in some cases.
-
-QSGMaterialType QSGD3D12VertexColorMaterial::mtype;
-
-QSGMaterialType *QSGD3D12VertexColorMaterial::type() const
-{
- return &QSGD3D12VertexColorMaterial::mtype;
-}
-
-int QSGD3D12VertexColorMaterial::compare(const QSGMaterial *other) const
-{
- Q_ASSERT(other && type() == other->type());
- // As the vertex color material has all its state in the vertex attributes
- // defined by the geometry, all such materials will be equal.
- return 0;
-}
-
-static const int VERTEX_COLOR_CB_SIZE_0 = 16 * sizeof(float); // float4x4
-static const int VERTEX_COLOR_CB_SIZE_1 = sizeof(float); // float
-static const int VERTEX_COLOR_CB_SIZE = VERTEX_COLOR_CB_SIZE_0 + VERTEX_COLOR_CB_SIZE_1;
-
-int QSGD3D12VertexColorMaterial::constantBufferSize() const
-{
- return QSGD3D12Engine::alignedConstantBufferSize(VERTEX_COLOR_CB_SIZE);
-}
-
-void QSGD3D12VertexColorMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
-{
- pipelineState->shaders.vs = g_VS_VertexColor;
- pipelineState->shaders.vsSize = sizeof(g_VS_VertexColor);
- pipelineState->shaders.ps = g_PS_VertexColor;
- pipelineState->shaders.psSize = sizeof(g_PS_VertexColor);
-}
-
-QSGD3D12Material::UpdateResults QSGD3D12VertexColorMaterial::updatePipeline(const RenderState &state,
- QSGD3D12PipelineState *,
- ExtraState *,
- quint8 *constantBuffer)
-{
- QSGD3D12Material::UpdateResults r = 0;
- quint8 *p = constantBuffer;
-
- if (state.isMatrixDirty()) {
- memcpy(p, state.combinedMatrix().constData(), VERTEX_COLOR_CB_SIZE_0);
- r |= UpdatedConstantBuffer;
- }
- p += VERTEX_COLOR_CB_SIZE_0;
-
- if (state.isOpacityDirty()) {
- const float opacity = state.opacity();
- memcpy(p, &opacity, VERTEX_COLOR_CB_SIZE_1);
- r |= UpdatedConstantBuffer;
- }
-
- 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(QSGD3D12PipelineState *pipelineState)
-{
- pipelineState->shaders.vs = g_VS_SmoothColor;
- pipelineState->shaders.vsSize = sizeof(g_VS_SmoothColor);
- pipelineState->shaders.ps = g_PS_SmoothColor;
- pipelineState->shaders.psSize = sizeof(g_PS_SmoothColor);
-}
-
-QSGD3D12Material::UpdateResults QSGD3D12SmoothColorMaterial::updatePipeline(const RenderState &state,
- QSGD3D12PipelineState *,
- ExtraState *,
- 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;
-}
-
-QSGMaterialType QSGD3D12TextureMaterial::mtype;
-
-QSGMaterialType *QSGD3D12TextureMaterial::type() const
-{
- return &QSGD3D12TextureMaterial::mtype;
-}
-
-int QSGD3D12TextureMaterial::compare(const QSGMaterial *other) const
-{
- Q_ASSERT(other && type() == other->type());
- const QSGD3D12TextureMaterial *o = static_cast<const QSGD3D12TextureMaterial *>(other);
- if (int diff = m_texture->textureId() - o->texture()->textureId())
- return diff;
- return int(m_filtering) - int(o->m_filtering);
-}
-
-static const int TEXTURE_CB_SIZE_0 = 16 * sizeof(float); // float4x4
-static const int TEXTURE_CB_SIZE_1 = sizeof(float); // float
-static const int TEXTURE_CB_SIZE = TEXTURE_CB_SIZE_0 + TEXTURE_CB_SIZE_1;
-
-int QSGD3D12TextureMaterial::constantBufferSize() const
-{
- return QSGD3D12Engine::alignedConstantBufferSize(TEXTURE_CB_SIZE);
-}
-
-void QSGD3D12TextureMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
-{
- pipelineState->shaders.vs = g_VS_Texture;
- pipelineState->shaders.vsSize = sizeof(g_VS_Texture);
- pipelineState->shaders.ps = g_PS_Texture;
- pipelineState->shaders.psSize = sizeof(g_PS_Texture);
-
- pipelineState->shaders.rootSig.textureViews.resize(1);
-}
-
-QSGD3D12Material::UpdateResults QSGD3D12TextureMaterial::updatePipeline(const RenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *,
- quint8 *constantBuffer)
-{
- QSGD3D12Material::UpdateResults r = 0;
- quint8 *p = constantBuffer;
-
- if (state.isMatrixDirty()) {
- memcpy(p, state.combinedMatrix().constData(), TEXTURE_CB_SIZE_0);
- r |= UpdatedConstantBuffer;
- }
- p += TEXTURE_CB_SIZE_0;
-
- if (state.isOpacityDirty()) {
- const float opacity = state.opacity();
- memcpy(p, &opacity, TEXTURE_CB_SIZE_1);
- r |= UpdatedConstantBuffer;
- }
-
- Q_ASSERT(m_texture);
- m_texture->setFiltering(m_filtering);
- m_texture->setMipmapFiltering(m_mipmap_filtering);
- m_texture->setHorizontalWrapMode(m_horizontal_wrap);
- m_texture->setVerticalWrapMode(m_vertical_wrap);
-
- QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[0]);
- if (m_filtering == QSGTexture::Linear)
- tv.filter = m_mipmap_filtering == QSGTexture::Linear
- ? QSGD3D12TextureView::FilterLinear : QSGD3D12TextureView::FilterMinMagLinearMipNearest;
- else
- tv.filter = m_mipmap_filtering == QSGTexture::Linear
- ? QSGD3D12TextureView::FilterMinMagNearestMipLinear : QSGD3D12TextureView::FilterNearest;
- tv.addressModeHoriz = m_horizontal_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap;
- tv.addressModeVert = m_vertical_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap;
-
- m_texture->bind();
-
- return r;
-}
-
-QSGD3D12SmoothTextureMaterial::QSGD3D12SmoothTextureMaterial()
-{
- setFlag(RequiresFullMatrixExceptTranslate, true);
- setFlag(Blending, true);
-}
-
-QSGMaterialType QSGD3D12SmoothTextureMaterial::mtype;
-
-QSGMaterialType *QSGD3D12SmoothTextureMaterial::type() const
-{
- return &QSGD3D12SmoothTextureMaterial::mtype;
-}
-
-int QSGD3D12SmoothTextureMaterial::compare(const QSGMaterial *other) const
-{
- Q_ASSERT(other && type() == other->type());
- const QSGD3D12SmoothTextureMaterial *o = static_cast<const QSGD3D12SmoothTextureMaterial *>(other);
- if (int diff = m_texture->textureId() - o->texture()->textureId())
- return diff;
- return int(m_filtering) - int(o->m_filtering);
-}
-
-static const int SMOOTH_TEXTURE_CB_SIZE_0 = 16 * sizeof(float); // float4x4
-static const int SMOOTH_TEXTURE_CB_SIZE_1 = sizeof(float); // float
-static const int SMOOTH_TEXTURE_CB_SIZE_2 = 2 * sizeof(float); // float2
-static const int SMOOTH_TEXTURE_CB_SIZE = SMOOTH_TEXTURE_CB_SIZE_0 + SMOOTH_TEXTURE_CB_SIZE_1 + SMOOTH_TEXTURE_CB_SIZE_2;
-
-int QSGD3D12SmoothTextureMaterial::constantBufferSize() const
-{
- return QSGD3D12Engine::alignedConstantBufferSize(SMOOTH_TEXTURE_CB_SIZE);
-}
-
-void QSGD3D12SmoothTextureMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
-{
- pipelineState->shaders.vs = g_VS_SmoothTexture;
- pipelineState->shaders.vsSize = sizeof(g_VS_SmoothTexture);
- pipelineState->shaders.ps = g_PS_SmoothTexture;
- pipelineState->shaders.psSize = sizeof(g_PS_SmoothTexture);
-
- pipelineState->shaders.rootSig.textureViews.resize(1);
-}
-
-QSGD3D12Material::UpdateResults QSGD3D12SmoothTextureMaterial::updatePipeline(const RenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *,
- quint8 *constantBuffer)
-{
- QSGD3D12Material::UpdateResults r = 0;
- quint8 *p = constantBuffer;
-
- if (state.isMatrixDirty()) {
- memcpy(p, state.combinedMatrix().constData(), SMOOTH_TEXTURE_CB_SIZE_0);
- r |= UpdatedConstantBuffer;
- }
- p += SMOOTH_TEXTURE_CB_SIZE_0;
-
- if (state.isOpacityDirty()) {
- const float opacity = state.opacity();
- memcpy(p, &opacity, SMOOTH_TEXTURE_CB_SIZE_1);
- r |= UpdatedConstantBuffer;
- }
- p += SMOOTH_TEXTURE_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_TEXTURE_CB_SIZE_2);
- r |= UpdatedConstantBuffer;
- }
-
- Q_ASSERT(m_texture);
- m_texture->setFiltering(m_filtering);
- m_texture->setMipmapFiltering(m_mipmap_filtering);
- m_texture->setHorizontalWrapMode(m_horizontal_wrap);
- m_texture->setVerticalWrapMode(m_vertical_wrap);
-
- QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[0]);
- if (m_filtering == QSGTexture::Linear)
- tv.filter = m_mipmap_filtering == QSGTexture::Linear
- ? QSGD3D12TextureView::FilterLinear : QSGD3D12TextureView::FilterMinMagLinearMipNearest;
- else
- tv.filter = m_mipmap_filtering == QSGTexture::Linear
- ? QSGD3D12TextureView::FilterMinMagNearestMipLinear : QSGD3D12TextureView::FilterNearest;
- tv.addressModeHoriz = m_horizontal_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap;
- tv.addressModeVert = m_vertical_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap;
-
- m_texture->bind();
-
- return r;
-}
-
-static inline float qsg_device_pixel_ratio(QSGD3D12Engine *engine)
-{
- // ### offscreen render target support will need changes
- return engine->windowDevicePixelRatio();
-}
-
-static inline QVector4D qsg_premultiply(const QVector4D &c, float globalOpacity)
-{
- float o = c.w() * globalOpacity;
- return QVector4D(c.x() * o, c.y() * o, c.z() * o, o);
-}
-
-static inline int qsg_colorDiff(const QVector4D &a, const QVector4D &b)
-{
- if (a.x() != b.x())
- return a.x() > b.x() ? 1 : -1;
- if (a.y() != b.y())
- return a.y() > b.y() ? 1 : -1;
- if (a.z() != b.z())
- return a.z() > b.z() ? 1 : -1;
- if (a.w() != b.w())
- return a.w() > b.w() ? 1 : -1;
- return 0;
-}
-
-QSGD3D12TextMaterial::QSGD3D12TextMaterial(StyleType styleType, QSGD3D12RenderContext *rc,
- const QRawFont &font, QFontEngine::GlyphFormat glyphFormat)
- : m_styleType(styleType),
- m_font(font),
- m_rc(rc)
-{
- setFlag(Blending, true);
-
- QRawFontPrivate *fontD = QRawFontPrivate::get(m_font);
- if (QFontEngine *fontEngine = fontD->fontEngine) {
- if (glyphFormat == QFontEngine::Format_None)
- glyphFormat = fontEngine->glyphFormat != QFontEngine::Format_None
- ? fontEngine->glyphFormat : QFontEngine::Format_A32;
-
- QSGD3D12Engine *d3dengine = rc->engine();
- const float devicePixelRatio = qsg_device_pixel_ratio(d3dengine);
- QTransform glyphCacheTransform = QTransform::fromScale(devicePixelRatio, devicePixelRatio);
- if (!fontEngine->supportsTransformation(glyphCacheTransform))
- glyphCacheTransform = QTransform();
-
- m_glyphCache = fontEngine->glyphCache(d3dengine, glyphFormat, glyphCacheTransform);
- if (!m_glyphCache || int(m_glyphCache->glyphFormat()) != glyphFormat) {
- m_glyphCache = new QSGD3D12GlyphCache(d3dengine, glyphFormat, glyphCacheTransform);
- fontEngine->setGlyphCache(d3dengine, m_glyphCache.data());
- rc->registerFontengineForCleanup(fontEngine);
- }
- }
-}
-
-QSGMaterialType QSGD3D12TextMaterial::mtype[QSGD3D12TextMaterial::NTextMaterialTypes];
-
-QSGMaterialType *QSGD3D12TextMaterial::type() const
-{
- // Format_A32 has special blend settings and therefore two materials with
- // the same style but different formats where one is A32 are treated as
- // different. This way the renderer can manage the pipeline state properly.
- const int matStyle = m_styleType * 2;
- const int matFormat = glyphCache()->glyphFormat() != QFontEngine::Format_A32 ? 0 : 1;
- return &QSGD3D12TextMaterial::mtype[matStyle + matFormat];
-}
-
-int QSGD3D12TextMaterial::compare(const QSGMaterial *other) const
-{
- Q_ASSERT(other && type() == other->type());
- const QSGD3D12TextMaterial *o = static_cast<const QSGD3D12TextMaterial *>(other);
- if (m_styleType != o->m_styleType)
- return m_styleType - o->m_styleType;
- if (m_glyphCache != o->m_glyphCache)
- return m_glyphCache.data() < o->m_glyphCache.data() ? -1 : 1;
- if (m_styleShift != o->m_styleShift)
- return m_styleShift.y() - o->m_styleShift.y();
- int styleColorDiff = qsg_colorDiff(m_styleColor, o->m_styleColor);
- if (styleColorDiff)
- return styleColorDiff;
- return qsg_colorDiff(m_color, o->m_color);
-}
-
-static const int TEXT_CB_SIZE_0 = 16 * sizeof(float); // float4x4 mvp
-static const int TEXT_CB_SIZE_1 = 2 * sizeof(float); // float2 textureScale
-static const int TEXT_CB_SIZE_2 = sizeof(float); // float dpr
-static const int TEXT_CB_SIZE_3 = sizeof(float); // float color
-static const int TEXT_CB_SIZE_4 = 4 * sizeof(float); // float4 colorVec
-static const int TEXT_CB_SIZE_5 = 2 * sizeof(float); // float2 shift
-static const int TEXT_CB_SIZE_5_PADDING = 2 * sizeof(float); // float2 padding (the next float4 would cross the 16-byte boundary)
-static const int TEXT_CB_SIZE_6 = 4 * sizeof(float); // float4 styleColor
-static const int TEXT_CB_SIZE = TEXT_CB_SIZE_0 + TEXT_CB_SIZE_1 + TEXT_CB_SIZE_2 + TEXT_CB_SIZE_3
- + TEXT_CB_SIZE_4 + TEXT_CB_SIZE_5 + TEXT_CB_SIZE_5_PADDING + TEXT_CB_SIZE_6;
-
-int QSGD3D12TextMaterial::constantBufferSize() const
-{
- return QSGD3D12Engine::alignedConstantBufferSize(TEXT_CB_SIZE);
-}
-
-void QSGD3D12TextMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
-{
- if (m_styleType == Normal) {
- pipelineState->shaders.vs = g_VS_TextMask;
- pipelineState->shaders.vsSize = sizeof(g_VS_TextMask);
- switch (glyphCache()->glyphFormat()) {
- case QFontEngine::Format_A32:
- pipelineState->shaders.ps = g_PS_TextMask24;
- pipelineState->shaders.psSize = sizeof(g_PS_TextMask24);
- break;
- case QFontEngine::Format_ARGB:
- pipelineState->shaders.ps = g_PS_TextMask32;
- pipelineState->shaders.psSize = sizeof(g_PS_TextMask32);
- break;
- default:
- pipelineState->shaders.ps = g_PS_TextMask8;
- pipelineState->shaders.psSize = sizeof(g_PS_TextMask8);
- break;
- }
- } else if (m_styleType == Outlined) {
- pipelineState->shaders.vs = g_VS_OutlinedText;
- pipelineState->shaders.vsSize = sizeof(g_VS_OutlinedText);
- pipelineState->shaders.ps = g_PS_OutlinedText;
- pipelineState->shaders.psSize = sizeof(g_PS_OutlinedText);
- } else {
- pipelineState->shaders.vs = g_VS_StyledText;
- pipelineState->shaders.vsSize = sizeof(g_VS_StyledText);
- pipelineState->shaders.ps = g_PS_StyledText;
- pipelineState->shaders.psSize = sizeof(g_PS_StyledText);
- }
-
- pipelineState->shaders.rootSig.textureViews.resize(1);
-}
-
-QSGD3D12Material::UpdateResults QSGD3D12TextMaterial::updatePipeline(const RenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *extraState,
- quint8 *constantBuffer)
-{
- QSGD3D12Material::UpdateResults r = 0;
- quint8 *p = constantBuffer;
-
- if (glyphCache()->glyphFormat() == QFontEngine::Format_A32) {
- // can freely change the state due to the way type() works
- pipelineState->blend = QSGD3D12PipelineState::BlendColor;
- extraState->blendFactor = m_color;
- r |= UpdatedBlendFactor; // must be set always as this affects the command list
- }
-
- if (state.isMatrixDirty()) {
- memcpy(p, state.combinedMatrix().constData(), TEXT_CB_SIZE_0);
- r |= UpdatedConstantBuffer;
- }
- p += TEXT_CB_SIZE_0;
-
- if (state.isCachedMaterialDataDirty() || m_lastGlyphCacheSize != glyphCache()->currentSize()) {
- m_lastGlyphCacheSize = glyphCache()->currentSize();
- const float textureScale[2] = { 1.0f / m_lastGlyphCacheSize.width(),
- 1.0f / m_lastGlyphCacheSize.height() };
- memcpy(p, textureScale, TEXT_CB_SIZE_1);
- r |= UpdatedConstantBuffer;
- }
- p += TEXT_CB_SIZE_1;
-
- const float dpr = qsg_device_pixel_ratio(m_rc->engine());
- if (m_lastDpr != dpr) {
- m_lastDpr = dpr;
- memcpy(p, &dpr, TEXT_CB_SIZE_2);
- r |= UpdatedConstantBuffer;
- }
- p += TEXT_CB_SIZE_2;
-
- if (state.isOpacityDirty() || m_lastColor != m_color) {
- m_lastColor = m_color;
- if (glyphCache()->glyphFormat() == QFontEngine::Format_A32) {
- const QVector4D color = qsg_premultiply(m_color, state.opacity());
- const float alpha = color.w();
- memcpy(p, &alpha, TEXT_CB_SIZE_3);
- } else if (glyphCache()->glyphFormat() == QFontEngine::Format_ARGB) {
- const float opacity = m_color.w() * state.opacity();
- memcpy(p, &opacity, TEXT_CB_SIZE_3);
- } else {
- const QVector4D color = qsg_premultiply(m_color, state.opacity());
- const float f[4] = { color.x(), color.y(), color.z(), color.w() };
- memcpy(p + TEXT_CB_SIZE_3, f, TEXT_CB_SIZE_4);
- }
- r |= UpdatedConstantBuffer;
- }
- p += TEXT_CB_SIZE_3 + TEXT_CB_SIZE_4;
-
- if (m_styleType == Styled && (state.isCachedMaterialDataDirty() || m_lastStyleShift != m_styleShift)) {
- m_lastStyleShift = m_styleShift;
- const float f[2] = { m_styleShift.x(), m_styleShift.y() };
- memcpy(p, f, TEXT_CB_SIZE_5);
- r |= UpdatedConstantBuffer;
- }
- p += TEXT_CB_SIZE_5 + TEXT_CB_SIZE_5_PADDING;
-
- if ((m_styleType == Styled || m_styleType == Outlined)
- && (state.isOpacityDirty() || m_lastStyleColor != m_styleColor)) {
- m_lastStyleColor = m_styleColor;
- const QVector4D color = qsg_premultiply(m_styleColor, state.opacity());
- const float f[4] = { color.x(), color.y(), color.z(), color.w() };
- memcpy(p, f, TEXT_CB_SIZE_6);
- r |= UpdatedConstantBuffer;
- }
-
- QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[0]);
- tv.filter = QSGD3D12TextureView::FilterNearest;
- tv.addressModeHoriz = QSGD3D12TextureView::AddressClamp;
- tv.addressModeVert = QSGD3D12TextureView::AddressClamp;
-
- glyphCache()->activateTexture();
-
- return r;
-}
-
-void QSGD3D12TextMaterial::populate(const QPointF &p,
- const QVector<quint32> &glyphIndexes,
- const QVector<QPointF> &glyphPositions,
- QSGGeometry *geometry,
- QRectF *boundingRect,
- QPointF *baseLine,
- const QMargins &margins)
-{
- Q_ASSERT(m_font.isValid());
- QVector<QFixedPoint> fixedPointPositions;
- const int glyphPositionsSize = glyphPositions.size();
- fixedPointPositions.reserve(glyphPositionsSize);
- for (int i=0; i < glyphPositionsSize; ++i)
- fixedPointPositions.append(QFixedPoint::fromPointF(glyphPositions.at(i)));
-
- QSGD3D12GlyphCache *cache = glyphCache();
- QRawFontPrivate *fontD = QRawFontPrivate::get(m_font);
- cache->populate(fontD->fontEngine, glyphIndexes.size(), glyphIndexes.constData(),
- fixedPointPositions.data());
- cache->fillInPendingGlyphs();
-
- int margin = fontD->fontEngine->glyphMargin(cache->glyphFormat());
-
- float glyphCacheScaleX = cache->transform().m11();
- float glyphCacheScaleY = cache->transform().m22();
- float glyphCacheInverseScaleX = 1.0 / glyphCacheScaleX;
- float glyphCacheInverseScaleY = 1.0 / glyphCacheScaleY;
-
- Q_ASSERT(geometry->indexType() == QSGGeometry::TypeUnsignedShort);
- geometry->allocate(glyphIndexes.size() * 4, glyphIndexes.size() * 6);
- QVector4D *vp = reinterpret_cast<QVector4D *>(geometry->vertexDataAsTexturedPoint2D());
- Q_ASSERT(geometry->sizeOfVertex() == sizeof(QVector4D));
- ushort *ip = geometry->indexDataAsUShort();
-
- QPointF position(p.x(), p.y() - m_font.ascent());
- bool supportsSubPixelPositions = fontD->fontEngine->supportsSubPixelPositions();
- for (int i = 0; i < glyphIndexes.size(); ++i) {
- QFixed subPixelPosition;
- if (supportsSubPixelPositions)
- subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(glyphPositions.at(i).x()));
-
- QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphIndexes.at(i), subPixelPosition);
- const QTextureGlyphCache::Coord &c = cache->coords.value(glyph);
-
- QPointF glyphPosition = glyphPositions.at(i) + position;
- float x = (qFloor(glyphPosition.x() * glyphCacheScaleX) * glyphCacheInverseScaleX)
- + (c.baseLineX * glyphCacheInverseScaleX) - margin;
- float y = (qRound(glyphPosition.y() * glyphCacheScaleY) * glyphCacheInverseScaleY)
- - (c.baseLineY * glyphCacheInverseScaleY) - margin;
-
- float w = c.w * glyphCacheInverseScaleX;
- float h = c.h * glyphCacheInverseScaleY;
-
- *boundingRect |= QRectF(x + margin, y + margin, w, h);
-
- float cx1 = x - margins.left();
- float cx2 = x + w + margins.right();
- float cy1 = y - margins.top();
- float cy2 = y + h + margins.bottom();
-
- float tx1 = c.x - margins.left();
- float tx2 = c.x + c.w + margins.right();
- float ty1 = c.y - margins.top();
- float ty2 = c.y + c.h + margins.bottom();
-
- if (baseLine->isNull())
- *baseLine = glyphPosition;
-
- vp[4 * i + 0] = QVector4D(cx1, cy1, tx1, ty1);
- vp[4 * i + 1] = QVector4D(cx2, cy1, tx2, ty1);
- vp[4 * i + 2] = QVector4D(cx1, cy2, tx1, ty2);
- vp[4 * i + 3] = QVector4D(cx2, cy2, tx2, ty2);
-
- int o = i * 4;
- ip[6 * i + 0] = o + 0;
- ip[6 * i + 1] = o + 2;
- ip[6 * i + 2] = o + 3;
- ip[6 * i + 3] = o + 3;
- ip[6 * i + 4] = o + 1;
- ip[6 * i + 5] = o + 0;
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12builtinmaterials_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12builtinmaterials_p.h
deleted file mode 100644
index 8a475ddb77..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12builtinmaterials_p.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12BUILTINMATERIALS_P_H
-#define QSGD3D12BUILTINMATERIALS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qsgd3d12material_p.h"
-#include "qsgd3d12glyphcache_p.h"
-#include <private/qsgtexture_p.h>
-#include <QRawFont>
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12RenderContext;
-
-class QSGD3D12VertexColorMaterial : public QSGD3D12Material
-{
-public:
- QSGMaterialType *type() const override;
- int compare(const QSGMaterial *other) const override;
-
- virtual int constantBufferSize() const override;
- void preparePipeline(QSGD3D12PipelineState *pipelineState) override;
- UpdateResults updatePipeline(const RenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *extraState,
- quint8 *constantBuffer) override;
-
-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(QSGD3D12PipelineState *pipelineState) override;
- UpdateResults updatePipeline(const RenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *extraState,
- quint8 *constantBuffer) override;
-
-private:
- static QSGMaterialType mtype;
-};
-
-class QSGD3D12TextureMaterial : public QSGD3D12Material
-{
-public:
- QSGMaterialType *type() const override;
- int compare(const QSGMaterial *other) const override;
-
- virtual int constantBufferSize() const override;
- void preparePipeline(QSGD3D12PipelineState *pipelineState) override;
- UpdateResults updatePipeline(const RenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *extraState,
- quint8 *constantBuffer) override;
-
- void setTexture(QSGTexture *texture) { m_texture = texture; }
- QSGTexture *texture() const { return m_texture; }
-
- void setMipmapFiltering(QSGTexture::Filtering filter) { m_mipmap_filtering = filter; }
- QSGTexture::Filtering mipmapFiltering() const { return m_mipmap_filtering; }
-
- void setFiltering(QSGTexture::Filtering filter) { m_filtering = filter; }
- QSGTexture::Filtering filtering() const { return m_filtering; }
-
- void setHorizontalWrapMode(QSGTexture::WrapMode hwrap) { m_horizontal_wrap = hwrap; }
- QSGTexture::WrapMode horizontalWrapMode() const { return m_horizontal_wrap; }
-
- void setVerticalWrapMode(QSGTexture::WrapMode vwrap) { m_vertical_wrap = vwrap; }
- QSGTexture::WrapMode verticalWrapMode() const { return m_vertical_wrap; }
-
-private:
- static QSGMaterialType mtype;
-
- QSGTexture *m_texture = nullptr;
- QSGTexture::Filtering m_filtering = QSGTexture::Nearest;
- QSGTexture::Filtering m_mipmap_filtering = QSGTexture::None;
- QSGTexture::WrapMode m_horizontal_wrap = QSGTexture::ClampToEdge;
- QSGTexture::WrapMode m_vertical_wrap = QSGTexture::ClampToEdge;
-};
-
-class QSGD3D12SmoothTextureMaterial : public QSGD3D12Material
-{
-public:
- QSGD3D12SmoothTextureMaterial();
-
- QSGMaterialType *type() const override;
- int compare(const QSGMaterial *other) const override;
-
- virtual int constantBufferSize() const override;
- void preparePipeline(QSGD3D12PipelineState *pipelineState) override;
- UpdateResults updatePipeline(const RenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *extraState,
- quint8 *constantBuffer) override;
-
- void setTexture(QSGTexture *texture) { m_texture = texture; }
- QSGTexture *texture() const { return m_texture; }
-
- void setMipmapFiltering(QSGTexture::Filtering filter) { m_mipmap_filtering = filter; }
- QSGTexture::Filtering mipmapFiltering() const { return m_mipmap_filtering; }
-
- void setFiltering(QSGTexture::Filtering filter) { m_filtering = filter; }
- QSGTexture::Filtering filtering() const { return m_filtering; }
-
- void setHorizontalWrapMode(QSGTexture::WrapMode hwrap) { m_horizontal_wrap = hwrap; }
- QSGTexture::WrapMode horizontalWrapMode() const { return m_horizontal_wrap; }
-
- void setVerticalWrapMode(QSGTexture::WrapMode vwrap) { m_vertical_wrap = vwrap; }
- QSGTexture::WrapMode verticalWrapMode() const { return m_vertical_wrap; }
-
-private:
- static QSGMaterialType mtype;
-
- QSGTexture *m_texture = nullptr;
- QSGTexture::Filtering m_filtering = QSGTexture::Nearest;
- QSGTexture::Filtering m_mipmap_filtering = QSGTexture::None;
- QSGTexture::WrapMode m_horizontal_wrap = QSGTexture::ClampToEdge;
- QSGTexture::WrapMode m_vertical_wrap = QSGTexture::ClampToEdge;
-};
-
-class QSGD3D12TextMaterial : public QSGD3D12Material
-{
-public:
- enum StyleType {
- Normal,
- Styled,
- Outlined,
-
- NStyleTypes
- };
- QSGD3D12TextMaterial(StyleType styleType, QSGD3D12RenderContext *rc, const QRawFont &font,
- QFontEngine::GlyphFormat glyphFormat = QFontEngine::Format_None);
-
- QSGMaterialType *type() const override;
- int compare(const QSGMaterial *other) const override;
-
- virtual int constantBufferSize() const override;
- void preparePipeline(QSGD3D12PipelineState *pipelineState) override;
- UpdateResults updatePipeline(const RenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *extraState,
- quint8 *constantBuffer) override;
-
- void setColor(const QColor &c) { m_color = QVector4D(c.redF(), c.greenF(), c.blueF(), c.alphaF()); }
- void setColor(const QVector4D &color) { m_color = color; }
- const QVector4D &color() const { return m_color; }
-
- void setStyleShift(const QVector2D &shift) { m_styleShift = shift; }
- const QVector2D &styleShift() const { return m_styleShift; }
-
- void setStyleColor(const QColor &c) { m_styleColor = QVector4D(c.redF(), c.greenF(), c.blueF(), c.alphaF()); }
- void setStyleColor(const QVector4D &color) { m_styleColor = color; }
- const QVector4D &styleColor() const { return m_styleColor; }
-
- void populate(const QPointF &position,
- const QVector<quint32> &glyphIndexes, const QVector<QPointF> &glyphPositions,
- QSGGeometry *geometry, QRectF *boundingRect, QPointF *baseLine,
- const QMargins &margins = QMargins(0, 0, 0, 0));
-
- QSGD3D12GlyphCache *glyphCache() const { return static_cast<QSGD3D12GlyphCache *>(m_glyphCache.data()); }
-
-private:
- static const int NTextMaterialTypes = NStyleTypes * 2;
- static QSGMaterialType mtype[NTextMaterialTypes];
- StyleType m_styleType;
- QSGD3D12RenderContext *m_rc;
- QVector4D m_color;
- QVector2D m_styleShift;
- QVector4D m_styleColor;
- QRawFont m_font;
- QExplicitlySharedDataPointer<QFontEngineGlyphCache> m_glyphCache;
- QSize m_lastGlyphCacheSize;
- float m_lastDpr = 0;
- QVector4D m_lastColor;
- QVector2D m_lastStyleShift;
- QVector4D m_lastStyleColor;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12BUILTINMATERIALS_P_H
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context.cpp
deleted file mode 100644
index 0bb342226b..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12context_p.h"
-#include "qsgd3d12rendercontext_p.h"
-#include "qsgd3d12rectanglenode_p.h"
-#include "qsgd3d12imagenode_p.h"
-#include "qsgd3d12glyphnode_p.h"
-#include "qsgd3d12layer_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QSGRenderContext *QSGD3D12Context::createRenderContext()
-{
- return new QSGD3D12RenderContext(this);
-}
-
-QSGRectangleNode *QSGD3D12Context::createRectangleNode()
-{
- return new QSGD3D12RectangleNode;
-}
-
-QSGImageNode *QSGD3D12Context::createImageNode()
-{
- return new QSGD3D12ImageNode;
-}
-
-QSGPainterNode *QSGD3D12Context::createPainterNode(QQuickPaintedItem *item)
-{
- Q_UNUSED(item);
- Q_UNREACHABLE();
- return nullptr;
-}
-
-QSGGlyphNode *QSGD3D12Context::createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode)
-{
- Q_UNUSED(preferNativeGlyphNode);
- // ### distance field text rendering is not supported atm
-
- return new QSGD3D12GlyphNode(static_cast<QSGD3D12RenderContext *>(rc));
-}
-
-QSGNinePatchNode *QSGD3D12Context::createNinePatchNode()
-{
- Q_UNREACHABLE();
- return nullptr;
-}
-
-QSGLayer *QSGD3D12Context::createLayer(QSGRenderContext *rc)
-{
- return new QSGD3D12Layer(static_cast<QSGD3D12RenderContext *>(rc));
-}
-
-QSize QSGD3D12Context::minimumFBOSize() const
-{
- return QSize(16, 16);
-}
-
-QSurfaceFormat QSGD3D12Context::defaultSurfaceFormat() const
-{
- return QSurfaceFormat::defaultFormat();
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context_p.h
deleted file mode 100644
index 2afe22e3af..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context_p.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12CONTEXT_P_H
-#define QSGD3D12CONTEXT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qsgcontext_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12Context : public QSGContext
-{
-public:
- QSGD3D12Context(QObject *parent = 0) : QSGContext(parent) { }
-
- QSGRenderContext *createRenderContext() override;
- QSGRectangleNode *createRectangleNode() override;
- QSGImageNode *createImageNode() override;
- QSGPainterNode *createPainterNode(QQuickPaintedItem *item) override;
- QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) override;
- QSGNinePatchNode *createNinePatchNode() override;
- QSGLayer *createLayer(QSGRenderContext *rc) override;
- QSize minimumFBOSize() const override;
- QSurfaceFormat defaultSurfaceFormat() const override;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12CONTEXT_P_H
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine.cpp
deleted file mode 100644
index afeeea760c..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine.cpp
+++ /dev/null
@@ -1,2740 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12engine_p.h"
-#include "qsgd3d12engine_p_p.h"
-#include "cs_mipmapgen.hlslh"
-#include <QString>
-#include <QColor>
-#include <qmath.h>
-#include <QtCore/private/qsimd_p.h>
-
-QT_BEGIN_NAMESPACE
-
-// NOTE: Avoid categorized logging. It is slow.
-
-#define DECLARE_DEBUG_VAR(variable) \
- static bool debug_ ## variable() \
- { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
-
-DECLARE_DEBUG_VAR(render)
-
-static const int DEFAULT_SWAP_CHAIN_BUFFER_COUNT = 3;
-static const int DEFAULT_FRAME_IN_FLIGHT_COUNT = 2;
-static const int DEFAULT_WAITABLE_SWAP_CHAIN_MAX_LATENCY = 0;
-
-static const int MAX_DRAW_CALLS_PER_LIST = 128;
-
-static const int MAX_CACHED_ROOTSIG = 16;
-static const int MAX_CACHED_PSO = 64;
-
-static const int GPU_CBVSRVUAV_DESCRIPTORS = 512;
-
-static const int BUCKETS_PER_HEAP = 8; // must match freeMap
-static const int DESCRIPTORS_PER_BUCKET = 32; // the bit map (freeMap) is quint32
-static const int MAX_DESCRIPTORS_PER_HEAP = BUCKETS_PER_HEAP * DESCRIPTORS_PER_BUCKET;
-
-D3D12_CPU_DESCRIPTOR_HANDLE QSGD3D12CPUDescriptorHeapManager::allocate(D3D12_DESCRIPTOR_HEAP_TYPE type)
-{
- D3D12_CPU_DESCRIPTOR_HANDLE h = {};
- for (Heap &heap : m_heaps) {
- if (heap.type == type) {
- for (int bucket = 0; bucket < _countof(heap.freeMap); ++bucket)
- if (heap.freeMap[bucket]) {
- unsigned long freePos = _bit_scan_forward(heap.freeMap[bucket]);
- heap.freeMap[bucket] &= ~(1UL << freePos);
- if (Q_UNLIKELY(debug_render()))
- qDebug("descriptor handle type %x reserve in bucket %d index %d", type, bucket, freePos);
- freePos += bucket * DESCRIPTORS_PER_BUCKET;
- h = heap.start;
- h.ptr += freePos * heap.handleSize;
- return h;
- }
- }
- }
-
- Heap heap;
- heap.type = type;
- heap.handleSize = m_handleSizes[type];
-
- D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};
- heapDesc.NumDescriptors = MAX_DESCRIPTORS_PER_HEAP;
- heapDesc.Type = type;
- // The heaps created here are _never_ shader-visible.
-
- HRESULT hr = m_device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&heap.heap));
- if (FAILED(hr)) {
- qWarning("Failed to create heap with type 0x%x: %x", type, hr);
- return h;
- }
-
- heap.start = heap.heap->GetCPUDescriptorHandleForHeapStart();
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("new descriptor heap, type %x, start %llu", type, heap.start.ptr);
-
- heap.freeMap[0] = 0xFFFFFFFE;
- for (int i = 1; i < _countof(heap.freeMap); ++i)
- heap.freeMap[i] = 0xFFFFFFFF;
-
- h = heap.start;
-
- m_heaps.append(heap);
-
- return h;
-}
-
-void QSGD3D12CPUDescriptorHeapManager::release(D3D12_CPU_DESCRIPTOR_HANDLE handle, D3D12_DESCRIPTOR_HEAP_TYPE type)
-{
- for (Heap &heap : m_heaps) {
- if (heap.type == type
- && handle.ptr >= heap.start.ptr
- && handle.ptr < heap.start.ptr + heap.handleSize * MAX_DESCRIPTORS_PER_HEAP) {
- unsigned long pos = (handle.ptr - heap.start.ptr) / heap.handleSize;
- const int bucket = pos / DESCRIPTORS_PER_BUCKET;
- const int indexInBucket = pos - bucket * DESCRIPTORS_PER_BUCKET;
- heap.freeMap[bucket] |= 1UL << indexInBucket;
- if (Q_UNLIKELY(debug_render()))
- qDebug("free descriptor handle type %x bucket %d index %d", type, bucket, indexInBucket);
- return;
- }
- }
- qWarning("QSGD3D12CPUDescriptorHeapManager: Attempted to release untracked descriptor handle %llu of type %d", handle.ptr, type);
-}
-
-void QSGD3D12CPUDescriptorHeapManager::initialize(ID3D12Device *device)
-{
- m_device = device;
-
- for (int i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; ++i)
- m_handleSizes[i] = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE(i));
-}
-
-void QSGD3D12CPUDescriptorHeapManager::releaseResources()
-{
- for (Heap &heap : m_heaps)
- heap.heap = nullptr;
-
- m_heaps.clear();
-
- m_device = nullptr;
-}
-
-// One device per process, one everything else (engine) per window.
-Q_GLOBAL_STATIC(QSGD3D12DeviceManager, deviceManager)
-
-static void getHardwareAdapter(IDXGIFactory1 *factory, IDXGIAdapter1 **outAdapter)
-{
- const D3D_FEATURE_LEVEL fl = D3D_FEATURE_LEVEL_11_0;
- ComPtr<IDXGIAdapter1> adapter;
- DXGI_ADAPTER_DESC1 desc;
-
- for (int adapterIndex = 0; factory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) {
- DXGI_ADAPTER_DESC1 desc;
- adapter->GetDesc1(&desc);
- const QString name = QString::fromUtf16((char16_t *) desc.Description);
- qDebug("Adapter %d: '%s' (flags 0x%x)", adapterIndex, qPrintable(name), desc.Flags);
- }
-
- if (qEnvironmentVariableIsSet("QT_D3D_ADAPTER_INDEX")) {
- const int adapterIndex = qEnvironmentVariableIntValue("QT_D3D_ADAPTER_INDEX");
- if (SUCCEEDED(factory->EnumAdapters1(adapterIndex, &adapter))
- && SUCCEEDED(D3D12CreateDevice(adapter.Get(), fl, _uuidof(ID3D12Device), nullptr))) {
- adapter->GetDesc1(&desc);
- const QString name = QString::fromUtf16((char16_t *) desc.Description);
- qDebug("Using requested adapter '%s'", qPrintable(name));
- *outAdapter = adapter.Detach();
- return;
- }
- }
-
- for (int adapterIndex = 0; factory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) {
- adapter->GetDesc1(&desc);
- if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
- continue;
-
- if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), fl, _uuidof(ID3D12Device), nullptr))) {
- const QString name = QString::fromUtf16((char16_t *) desc.Description);
- qDebug("Using adapter '%s'", qPrintable(name));
- break;
- }
- }
-
- *outAdapter = adapter.Detach();
-}
-
-ID3D12Device *QSGD3D12DeviceManager::ref()
-{
- ensureCreated();
- m_ref.ref();
- return m_device.Get();
-}
-
-void QSGD3D12DeviceManager::unref()
-{
- if (!m_ref.deref()) {
- if (Q_UNLIKELY(debug_render()))
- qDebug("destroying d3d device");
- m_device = nullptr;
- m_factory = nullptr;
- }
-}
-
-void QSGD3D12DeviceManager::deviceLossDetected()
-{
- for (DeviceLossObserver *observer : qAsConst(m_observers))
- observer->deviceLost();
-
- // Nothing else to do here. All windows are expected to release their
- // resources and call unref() in response immediately.
-}
-
-IDXGIFactory4 *QSGD3D12DeviceManager::dxgi()
-{
- ensureCreated();
- return m_factory.Get();
-}
-
-void QSGD3D12DeviceManager::ensureCreated()
-{
- if (m_device)
- return;
-
- HRESULT hr = CreateDXGIFactory2(0, IID_PPV_ARGS(&m_factory));
- if (FAILED(hr)) {
- qWarning("Failed to create DXGI: 0x%x", hr);
- return;
- }
-
- ComPtr<IDXGIAdapter1> adapter;
- getHardwareAdapter(m_factory.Get(), &adapter);
-
- bool warp = true;
- if (adapter) {
- HRESULT hr = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device));
- if (SUCCEEDED(hr))
- warp = false;
- else
- qWarning("Failed to create device: 0x%x", hr);
- }
-
- if (warp) {
- qDebug("Using WARP");
- m_factory->EnumWarpAdapter(IID_PPV_ARGS(&adapter));
- HRESULT hr = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device));
- if (FAILED(hr)) {
- qWarning("Failed to create WARP device: 0x%x", hr);
- return;
- }
- }
-
- ComPtr<IDXGIAdapter3> adapter3;
- if (SUCCEEDED(adapter.As(&adapter3))) {
- DXGI_QUERY_VIDEO_MEMORY_INFO vidMemInfo;
- if (SUCCEEDED(adapter3->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &vidMemInfo))) {
- qDebug("Video memory info: LOCAL: Budget %llu KB CurrentUsage %llu KB AvailableForReservation %llu KB CurrentReservation %llu KB",
- vidMemInfo.Budget / 1024, vidMemInfo.CurrentUsage / 1024,
- vidMemInfo.AvailableForReservation / 1024, vidMemInfo.CurrentReservation / 1024);
- }
- if (SUCCEEDED(adapter3->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &vidMemInfo))) {
- qDebug("Video memory info: NON-LOCAL: Budget %llu KB CurrentUsage %llu KB AvailableForReservation %llu KB CurrentReservation %llu KB",
- vidMemInfo.Budget / 1024, vidMemInfo.CurrentUsage / 1024,
- vidMemInfo.AvailableForReservation / 1024, vidMemInfo.CurrentReservation / 1024);
- }
- }
-}
-
-void QSGD3D12DeviceManager::registerDeviceLossObserver(DeviceLossObserver *observer)
-{
- if (!m_observers.contains(observer))
- m_observers.append(observer);
-}
-
-QSGD3D12Engine::QSGD3D12Engine()
-{
- d = new QSGD3D12EnginePrivate;
-}
-
-QSGD3D12Engine::~QSGD3D12Engine()
-{
- d->waitGPU();
- d->releaseResources();
- delete d;
-}
-
-bool QSGD3D12Engine::attachToWindow(WId window, const QSize &size, float dpr, int samples)
-{
- if (d->isInitialized()) {
- qWarning("QSGD3D12Engine: Cannot attach active engine to window");
- return false;
- }
-
- d->initialize(window, size, dpr, samples);
- return d->isInitialized();
-}
-
-void QSGD3D12Engine::releaseResources()
-{
- d->releaseResources();
-}
-
-bool QSGD3D12Engine::hasResources() const
-{
- // An explicit releaseResources() or a device loss results in initialized == false.
- return d->isInitialized();
-}
-
-void QSGD3D12Engine::setWindowSize(const QSize &size, float dpr)
-{
- d->setWindowSize(size, dpr);
-}
-
-WId QSGD3D12Engine::window() const
-{
- return d->currentWindow();
-}
-
-QSize QSGD3D12Engine::windowSize() const
-{
- return d->currentWindowSize();
-}
-
-float QSGD3D12Engine::windowDevicePixelRatio() const
-{
- return d->currentWindowDpr();
-}
-
-void QSGD3D12Engine::beginFrame()
-{
- d->beginFrame();
-}
-
-void QSGD3D12Engine::endFrame()
-{
- d->endFrame();
-}
-
-void QSGD3D12Engine::beginLayer()
-{
- d->beginLayer();
-}
-
-void QSGD3D12Engine::endLayer()
-{
- d->endLayer();
-}
-
-void QSGD3D12Engine::finalizePipeline(const QSGD3D12PipelineState &pipelineState)
-{
- d->finalizePipeline(pipelineState);
-}
-
-uint QSGD3D12Engine::genBuffer()
-{
- return d->genBuffer();
-}
-
-void QSGD3D12Engine::releaseBuffer(uint id)
-{
- d->releaseBuffer(id);
-}
-
-void QSGD3D12Engine::resetBuffer(uint id, const quint8 *data, int size)
-{
- d->resetBuffer(id, data, size);
-}
-
-void QSGD3D12Engine::markBufferDirty(uint id, int offset, int size)
-{
- d->markBufferDirty(id, offset, size);
-}
-
-void QSGD3D12Engine::queueViewport(const QRect &rect)
-{
- d->queueViewport(rect);
-}
-
-void QSGD3D12Engine::queueScissor(const QRect &rect)
-{
- d->queueScissor(rect);
-}
-
-void QSGD3D12Engine::queueSetRenderTarget(uint id)
-{
- d->queueSetRenderTarget(id);
-}
-
-void QSGD3D12Engine::queueClearRenderTarget(const QColor &color)
-{
- d->queueClearRenderTarget(color);
-}
-
-void QSGD3D12Engine::queueClearDepthStencil(float depthValue, quint8 stencilValue, ClearFlags which)
-{
- d->queueClearDepthStencil(depthValue, stencilValue, which);
-}
-
-void QSGD3D12Engine::queueSetBlendFactor(const QVector4D &factor)
-{
- d->queueSetBlendFactor(factor);
-}
-
-void QSGD3D12Engine::queueSetStencilRef(quint32 ref)
-{
- d->queueSetStencilRef(ref);
-}
-
-void QSGD3D12Engine::queueDraw(const DrawParams &params)
-{
- d->queueDraw(params);
-}
-
-void QSGD3D12Engine::present()
-{
- d->present();
-}
-
-void QSGD3D12Engine::waitGPU()
-{
- d->waitGPU();
-}
-
-uint QSGD3D12Engine::genTexture()
-{
- return d->genTexture();
-}
-
-void QSGD3D12Engine::createTexture(uint id, const QSize &size, QImage::Format format, TextureCreateFlags flags)
-{
- d->createTexture(id, size, format, flags);
-}
-
-void QSGD3D12Engine::queueTextureResize(uint id, const QSize &size)
-{
- d->queueTextureResize(id, size);
-}
-
-void QSGD3D12Engine::queueTextureUpload(uint id, const QImage &image, const QPoint &dstPos)
-{
- d->queueTextureUpload(id, QVector<QImage>() << image, QVector<QPoint>() << dstPos);
-}
-
-void QSGD3D12Engine::queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos)
-{
- d->queueTextureUpload(id, images, dstPos);
-}
-
-void QSGD3D12Engine::releaseTexture(uint id)
-{
- d->releaseTexture(id);
-}
-
-SIZE_T QSGD3D12Engine::textureSRV(uint id) const
-{
- return d->textureSRV(id);
-}
-
-void QSGD3D12Engine::activateTexture(uint id)
-{
- d->activateTexture(id);
-}
-
-uint QSGD3D12Engine::genRenderTarget()
-{
- return d->genRenderTarget();
-}
-
-void QSGD3D12Engine::createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, int samples)
-{
- d->createRenderTarget(id, size, clearColor, samples);
-}
-
-void QSGD3D12Engine::releaseRenderTarget(uint id)
-{
- d->releaseRenderTarget(id);
-}
-
-void QSGD3D12Engine::activateRenderTargetAsTexture(uint id)
-{
- d->activateRenderTargetAsTexture(id);
-}
-
-static inline quint32 alignedSize(quint32 size, quint32 byteAlign)
-{
- return (size + byteAlign - 1) & ~(byteAlign - 1);
-}
-
-quint32 QSGD3D12Engine::alignedConstantBufferSize(quint32 size)
-{
- return alignedSize(size, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT);
-}
-
-QSGD3D12Format QSGD3D12Engine::toDXGIFormat(QSGGeometry::Type sgtype, int tupleSize, int *size)
-{
- QSGD3D12Format format = FmtUnknown;
-
- static const QSGD3D12Format formatMap_ub[] = { FmtUnknown,
- FmtUNormByte,
- FmtUNormByte2,
- FmtUnknown,
- FmtUNormByte4 };
-
- static const QSGD3D12Format formatMap_f[] = { FmtUnknown,
- FmtFloat,
- FmtFloat2,
- FmtFloat3,
- FmtFloat4 };
-
- switch (sgtype) {
- case QSGGeometry::TypeUnsignedByte:
- format = formatMap_ub[tupleSize];
- if (size)
- *size = tupleSize;
- break;
- case QSGGeometry::TypeFloat:
- format = formatMap_f[tupleSize];
- if (size)
- *size = sizeof(float) * tupleSize;
- break;
-
- case QSGGeometry::TypeUnsignedShort:
- format = FmtUnsignedShort;
- if (size)
- *size = sizeof(ushort) * tupleSize;
- break;
- case QSGGeometry::TypeUnsignedInt:
- format = FmtUnsignedInt;
- if (size)
- *size = sizeof(uint) * tupleSize;
- break;
-
- case QSGGeometry::TypeByte:
- case QSGGeometry::TypeInt:
- case QSGGeometry::TypeShort:
- qWarning("no mapping for GL type 0x%x", sgtype);
- break;
-
- default:
- qWarning("unknown GL type 0x%x", sgtype);
- break;
- }
-
- return format;
-}
-
-int QSGD3D12Engine::mipMapLevels(const QSize &size)
-{
- return ceil(log2(qMax(size.width(), size.height()))) + 1;
-}
-
-inline static bool isPowerOfTwo(int x)
-{
- // Assumption: x >= 1
- return x == (x & -x);
-}
-
-QSize QSGD3D12Engine::mipMapAdjustedSourceSize(const QSize &size)
-{
- if (size.isEmpty())
- return size;
-
- QSize adjustedSize = size;
-
- // ### for now only power-of-two sizes are mipmap-capable
- if (!isPowerOfTwo(size.width()))
- adjustedSize.setWidth(qNextPowerOfTwo(size.width()));
- if (!isPowerOfTwo(size.height()))
- adjustedSize.setHeight(qNextPowerOfTwo(size.height()));
-
- return adjustedSize;
-}
-
-void QSGD3D12EnginePrivate::releaseResources()
-{
- if (!initialized)
- return;
-
- mipmapper.releaseResources();
-
- frameCommandList = nullptr;
- copyCommandList = nullptr;
-
- copyCommandAllocator = nullptr;
- for (int i = 0; i < frameInFlightCount; ++i) {
- frameCommandAllocator[i] = nullptr;
- pframeData[i].gpuCbvSrvUavHeap = nullptr;
- delete frameFence[i];
- }
-
- defaultDS = nullptr;
- for (int i = 0; i < swapChainBufferCount; ++i) {
- backBufferRT[i] = nullptr;
- defaultRT[i] = nullptr;
- }
-
- psoCache.clear();
- rootSigCache.clear();
- buffers.clear();
- textures.clear();
- renderTargets.clear();
-
- cpuDescHeapManager.releaseResources();
-
- commandQueue = nullptr;
- copyCommandQueue = nullptr;
- swapChain = nullptr;
-
- delete presentFence;
- textureUploadFence = nullptr;
-
- deviceManager()->unref();
-
- initialized = false;
-
- // 'window' must be kept, may just be a device loss
-}
-
-void QSGD3D12EnginePrivate::initialize(WId w, const QSize &size, float dpr, int samples)
-{
- if (initialized)
- return;
-
- window = w;
- windowSize = size;
- windowDpr = dpr;
- windowSamples = qMax(1, samples);
-
- HWND hwnd = reinterpret_cast<HWND>(w);
-
- swapChainBufferCount = qMin(qEnvironmentVariableIntValue("QT_D3D_BUFFER_COUNT"), MAX_SWAP_CHAIN_BUFFER_COUNT);
- if (swapChainBufferCount < 2)
- swapChainBufferCount = DEFAULT_SWAP_CHAIN_BUFFER_COUNT;
-
- frameInFlightCount = qMin(qEnvironmentVariableIntValue("QT_D3D_FRAME_COUNT"), MAX_FRAME_IN_FLIGHT_COUNT);
- if (frameInFlightCount < 1)
- frameInFlightCount = DEFAULT_FRAME_IN_FLIGHT_COUNT;
-
- static const char *latReqEnvVar = "QT_D3D_WAITABLE_SWAP_CHAIN_MAX_LATENCY";
- if (!qEnvironmentVariableIsSet(latReqEnvVar))
- waitableSwapChainMaxLatency = DEFAULT_WAITABLE_SWAP_CHAIN_MAX_LATENCY;
- else
- waitableSwapChainMaxLatency = qBound(0, qEnvironmentVariableIntValue(latReqEnvVar), 16);
-
- qDebug("d3d12 engine init. swap chain buffer count %d, max frames prepared without blocking %d",
- swapChainBufferCount, frameInFlightCount);
- if (waitableSwapChainMaxLatency)
- qDebug("Swap chain frame latency waitable object enabled. Frame latency is %d", waitableSwapChainMaxLatency);
-
- if (qEnvironmentVariableIntValue("QT_D3D_DEBUG") != 0) {
- qDebug("Enabling debug layer");
- ComPtr<ID3D12Debug> debugController;
- if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
- debugController->EnableDebugLayer();
- }
-
- QSGD3D12DeviceManager *dev = deviceManager();
- device = dev->ref();
- dev->registerDeviceLossObserver(this);
-
- D3D12_COMMAND_QUEUE_DESC queueDesc = {};
- queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
- if (FAILED(device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&commandQueue)))) {
- qWarning("Failed to create command queue");
- return;
- }
-
- queueDesc.Type = D3D12_COMMAND_LIST_TYPE_COPY;
- if (FAILED(device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&copyCommandQueue)))) {
- qWarning("Failed to create copy command queue");
- return;
- }
-
- DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
- swapChainDesc.BufferCount = swapChainBufferCount;
- swapChainDesc.BufferDesc.Width = windowSize.width() * windowDpr;
- swapChainDesc.BufferDesc.Height = windowSize.height() * windowDpr;
- swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
- swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; // D3D12 requires the flip model
- swapChainDesc.OutputWindow = hwnd;
- swapChainDesc.SampleDesc.Count = 1; // Flip does not support MSAA so no choice here
- swapChainDesc.Windowed = TRUE;
- if (waitableSwapChainMaxLatency)
- swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
-
- ComPtr<IDXGISwapChain> baseSwapChain;
- HRESULT hr = dev->dxgi()->CreateSwapChain(commandQueue.Get(), &swapChainDesc, &baseSwapChain);
- if (FAILED(hr)) {
- qWarning("Failed to create swap chain: 0x%x", hr);
- return;
- }
- if (FAILED(baseSwapChain.As(&swapChain))) {
- qWarning("Failed to cast swap chain");
- return;
- }
-
- dev->dxgi()->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER);
-
- if (waitableSwapChainMaxLatency) {
- if (FAILED(swapChain->SetMaximumFrameLatency(waitableSwapChainMaxLatency)))
- qWarning("Failed to set maximum frame latency to %d", waitableSwapChainMaxLatency);
- swapEvent = swapChain->GetFrameLatencyWaitableObject();
- }
-
- for (int i = 0; i < frameInFlightCount; ++i) {
- if (FAILED(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&frameCommandAllocator[i])))) {
- qWarning("Failed to create command allocator");
- return;
- }
- }
-
- if (FAILED(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COPY, IID_PPV_ARGS(&copyCommandAllocator)))) {
- qWarning("Failed to create copy command allocator");
- return;
- }
-
- for (int i = 0; i < frameInFlightCount; ++i) {
- if (!createCbvSrvUavHeap(i, GPU_CBVSRVUAV_DESCRIPTORS))
- return;
- }
-
- cpuDescHeapManager.initialize(device);
-
- setupDefaultRenderTargets();
-
- if (FAILED(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, frameCommandAllocator[0].Get(),
- nullptr, IID_PPV_ARGS(&frameCommandList)))) {
- qWarning("Failed to create command list");
- return;
- }
- // created in recording state, close it for now
- frameCommandList->Close();
-
- if (FAILED(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COPY, copyCommandAllocator.Get(),
- nullptr, IID_PPV_ARGS(&copyCommandList)))) {
- qWarning("Failed to create copy command list");
- return;
- }
- copyCommandList->Close();
-
- frameIndex = 0;
-
- presentFence = createCPUWaitableFence();
- for (int i = 0; i < frameInFlightCount; ++i)
- frameFence[i] = createCPUWaitableFence();
-
- if (FAILED(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&textureUploadFence)))) {
- qWarning("Failed to create fence");
- return;
- }
-
- psoCache.setMaxCost(MAX_CACHED_PSO);
- rootSigCache.setMaxCost(MAX_CACHED_ROOTSIG);
-
- if (!mipmapper.initialize(this))
- return;
-
- currentRenderTarget = 0;
-
- initialized = true;
-}
-
-bool QSGD3D12EnginePrivate::createCbvSrvUavHeap(int pframeIndex, int descriptorCount)
-{
- D3D12_DESCRIPTOR_HEAP_DESC gpuDescHeapDesc = {};
- gpuDescHeapDesc.NumDescriptors = descriptorCount;
- gpuDescHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
- gpuDescHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
-
- if (FAILED(device->CreateDescriptorHeap(&gpuDescHeapDesc, IID_PPV_ARGS(&pframeData[pframeIndex].gpuCbvSrvUavHeap)))) {
- qWarning("Failed to create shader-visible CBV-SRV-UAV heap");
- return false;
- }
-
- pframeData[pframeIndex].gpuCbvSrvUavHeapSize = descriptorCount;
-
- return true;
-}
-
-DXGI_SAMPLE_DESC QSGD3D12EnginePrivate::makeSampleDesc(DXGI_FORMAT format, int samples)
-{
- DXGI_SAMPLE_DESC sampleDesc;
- sampleDesc.Count = 1;
- sampleDesc.Quality = 0;
-
- if (samples > 1) {
- D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msaaInfo = {};
- msaaInfo.Format = format;
- msaaInfo.SampleCount = samples;
- if (SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &msaaInfo, sizeof(msaaInfo)))) {
- if (msaaInfo.NumQualityLevels > 0) {
- sampleDesc.Count = samples;
- sampleDesc.Quality = msaaInfo.NumQualityLevels - 1;
- } else {
- qWarning("No quality levels for multisampling with sample count %d", samples);
- }
- } else {
- qWarning("Failed to query multisample quality levels for sample count %d", samples);
- }
- }
-
- return sampleDesc;
-}
-
-ID3D12Resource *QSGD3D12EnginePrivate::createColorBuffer(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size,
- const QVector4D &clearColor, int samples)
-{
- D3D12_CLEAR_VALUE clearValue = {};
- clearValue.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- clearValue.Color[0] = clearColor.x();
- clearValue.Color[1] = clearColor.y();
- clearValue.Color[2] = clearColor.z();
- clearValue.Color[3] = clearColor.w();
-
- D3D12_HEAP_PROPERTIES heapProp = {};
- heapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
-
- D3D12_RESOURCE_DESC rtDesc = {};
- rtDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
- rtDesc.Width = size.width();
- rtDesc.Height = size.height();
- rtDesc.DepthOrArraySize = 1;
- rtDesc.MipLevels = 1;
- rtDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- rtDesc.SampleDesc = makeSampleDesc(rtDesc.Format, samples);
- rtDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
-
- ID3D12Resource *resource = nullptr;
- if (FAILED(device->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &rtDesc,
- D3D12_RESOURCE_STATE_RENDER_TARGET, &clearValue, IID_PPV_ARGS(&resource)))) {
- qWarning("Failed to create offscreen render target of size %dx%d", size.width(), size.height());
- return nullptr;
- }
-
- device->CreateRenderTargetView(resource, nullptr, viewHandle);
-
- return resource;
-}
-
-ID3D12Resource *QSGD3D12EnginePrivate::createDepthStencil(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size, int samples)
-{
- D3D12_CLEAR_VALUE depthClearValue = {};
- depthClearValue.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
- depthClearValue.DepthStencil.Depth = 1.0f;
- depthClearValue.DepthStencil.Stencil = 0;
-
- D3D12_HEAP_PROPERTIES heapProp = {};
- heapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
-
- D3D12_RESOURCE_DESC bufDesc = {};
- bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
- bufDesc.Width = size.width();
- bufDesc.Height = size.height();
- bufDesc.DepthOrArraySize = 1;
- bufDesc.MipLevels = 1;
- bufDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
- bufDesc.SampleDesc = makeSampleDesc(bufDesc.Format, samples);
- bufDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
- bufDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
-
- ID3D12Resource *resource = nullptr;
- if (FAILED(device->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &bufDesc,
- D3D12_RESOURCE_STATE_DEPTH_WRITE, &depthClearValue, IID_PPV_ARGS(&resource)))) {
- qWarning("Failed to create depth-stencil buffer of size %dx%d", size.width(), size.height());
- return nullptr;
- }
-
- D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilDesc = {};
- depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
- depthStencilDesc.ViewDimension = bufDesc.SampleDesc.Count <= 1 ? D3D12_DSV_DIMENSION_TEXTURE2D : D3D12_DSV_DIMENSION_TEXTURE2DMS;
-
- device->CreateDepthStencilView(resource, &depthStencilDesc, viewHandle);
-
- return resource;
-}
-
-void QSGD3D12EnginePrivate::setupDefaultRenderTargets()
-{
- for (int i = 0; i < swapChainBufferCount; ++i) {
- if (FAILED(swapChain->GetBuffer(i, IID_PPV_ARGS(&backBufferRT[i])))) {
- qWarning("Failed to get buffer %d from swap chain", i);
- return;
- }
- defaultRTV[i] = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
- if (windowSamples == 1) {
- defaultRT[i] = backBufferRT[i];
- device->CreateRenderTargetView(defaultRT[i].Get(), nullptr, defaultRTV[i]);
- } else {
- const QSize size(windowSize.width() * windowDpr, windowSize.height() * windowDpr);
- const QColor cc(Qt::white); // ### what if setClearColor? non-fatal but debug layer warns...
- const QVector4D clearColor(cc.redF(), cc.greenF(), cc.blueF(), cc.alphaF());
- ID3D12Resource *msaaRT = createColorBuffer(defaultRTV[i], size, clearColor, windowSamples);
- if (msaaRT)
- defaultRT[i].Attach(msaaRT);
- }
- }
-
- defaultDSV = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
- const QSize size(windowSize.width() * windowDpr, windowSize.height() * windowDpr);
- ID3D12Resource *ds = createDepthStencil(defaultDSV, size, windowSamples);
- if (ds)
- defaultDS.Attach(ds);
-
- presentFrameIndex = 0;
-}
-
-void QSGD3D12EnginePrivate::setWindowSize(const QSize &size, float dpr)
-{
- if (!initialized || (windowSize == size && windowDpr == dpr))
- return;
-
- waitGPU();
-
- windowSize = size;
- windowDpr = dpr;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug() << "resize" << size << dpr;
-
- // Clear these, otherwise resizing will fail.
- defaultDS = nullptr;
- cpuDescHeapManager.release(defaultDSV, D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
- for (int i = 0; i < swapChainBufferCount; ++i) {
- backBufferRT[i] = nullptr;
- defaultRT[i] = nullptr;
- cpuDescHeapManager.release(defaultRTV[i], D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
- }
-
- const int w = windowSize.width() * windowDpr;
- const int h = windowSize.height() * windowDpr;
- HRESULT hr = swapChain->ResizeBuffers(swapChainBufferCount, w, h, DXGI_FORMAT_R8G8B8A8_UNORM,
- waitableSwapChainMaxLatency ? DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT : 0);
- if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) {
- deviceManager()->deviceLossDetected();
- return;
- } else if (FAILED(hr)) {
- qWarning("Failed to resize buffers: 0x%x", hr);
- return;
- }
-
- setupDefaultRenderTargets();
-}
-
-void QSGD3D12EnginePrivate::deviceLost()
-{
- qWarning("D3D device lost, will attempt to reinitialize");
-
- // Release all resources. This is important because otherwise reinitialization may fail.
- releaseResources();
-
- // Now in uninitialized state (but 'window' is still valid). Will recreate
- // all the resources on the next beginFrame().
-}
-
-QSGD3D12CPUWaitableFence *QSGD3D12EnginePrivate::createCPUWaitableFence() const
-{
- QSGD3D12CPUWaitableFence *f = new QSGD3D12CPUWaitableFence;
- HRESULT hr = device->CreateFence(f->value, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&f->fence));
- if (FAILED(hr)) {
- qWarning("Failed to create fence: 0x%x", hr);
- return f;
- }
- f->event = CreateEvent(nullptr, FALSE, FALSE, nullptr);
- return f;
-}
-
-void QSGD3D12EnginePrivate::waitForGPU(QSGD3D12CPUWaitableFence *f) const
-{
- const UINT64 newValue = f->value.fetchAndAddAcquire(1) + 1;
- commandQueue->Signal(f->fence.Get(), newValue);
- if (f->fence->GetCompletedValue() < newValue) {
- HRESULT hr = f->fence->SetEventOnCompletion(newValue, f->event);
- if (FAILED(hr)) {
- qWarning("SetEventOnCompletion failed: 0x%x", hr);
- return;
- }
- WaitForSingleObject(f->event, INFINITE);
- }
-}
-
-void QSGD3D12EnginePrivate::transitionResource(ID3D12Resource *resource, ID3D12GraphicsCommandList *commandList,
- D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after) const
-{
- D3D12_RESOURCE_BARRIER barrier;
- barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
- barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
- barrier.Transition.pResource = resource;
- barrier.Transition.StateBefore = before;
- barrier.Transition.StateAfter = after;
- barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
-
- commandList->ResourceBarrier(1, &barrier);
-}
-
-void QSGD3D12EnginePrivate::resolveMultisampledTarget(ID3D12Resource *msaa,
- ID3D12Resource *resolve,
- D3D12_RESOURCE_STATES resolveUsage,
- ID3D12GraphicsCommandList *commandList) const
-{
- D3D12_RESOURCE_BARRIER barriers[2];
- for (int i = 0; i < _countof(barriers); ++i) {
- barriers[i].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
- barriers[i].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
- barriers[i].Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
- }
-
- barriers[0].Transition.pResource = msaa;
- barriers[0].Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
- barriers[0].Transition.StateAfter = D3D12_RESOURCE_STATE_RESOLVE_SOURCE;
- barriers[1].Transition.pResource = resolve;
- barriers[1].Transition.StateBefore = resolveUsage;
- barriers[1].Transition.StateAfter = D3D12_RESOURCE_STATE_RESOLVE_DEST;
- commandList->ResourceBarrier(2, barriers);
-
- commandList->ResolveSubresource(resolve, 0, msaa, 0, DXGI_FORMAT_R8G8B8A8_UNORM);
-
- barriers[0].Transition.pResource = msaa;
- barriers[0].Transition.StateBefore = D3D12_RESOURCE_STATE_RESOLVE_SOURCE;
- barriers[0].Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
- barriers[1].Transition.pResource = resolve;
- barriers[1].Transition.StateBefore = D3D12_RESOURCE_STATE_RESOLVE_DEST;
- barriers[1].Transition.StateAfter = resolveUsage;
- commandList->ResourceBarrier(2, barriers);
-}
-
-void QSGD3D12EnginePrivate::uavBarrier(ID3D12Resource *resource, ID3D12GraphicsCommandList *commandList) const
-{
- D3D12_RESOURCE_BARRIER barrier = {};
- barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
- barrier.UAV.pResource = resource;
-
- commandList->ResourceBarrier(1, &barrier);
-}
-
-ID3D12Resource *QSGD3D12EnginePrivate::createBuffer(int size)
-{
- ID3D12Resource *buf;
-
- D3D12_HEAP_PROPERTIES uploadHeapProp = {};
- uploadHeapProp.Type = D3D12_HEAP_TYPE_UPLOAD;
-
- D3D12_RESOURCE_DESC bufDesc = {};
- bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
- bufDesc.Width = size;
- bufDesc.Height = 1;
- bufDesc.DepthOrArraySize = 1;
- bufDesc.MipLevels = 1;
- bufDesc.Format = DXGI_FORMAT_UNKNOWN;
- bufDesc.SampleDesc.Count = 1;
- bufDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
-
- HRESULT hr = device->CreateCommittedResource(&uploadHeapProp, D3D12_HEAP_FLAG_NONE, &bufDesc,
- D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&buf));
- if (FAILED(hr))
- qWarning("Failed to create buffer resource: 0x%x", hr);
-
- return buf;
-}
-
-void QSGD3D12EnginePrivate::ensureBuffer(Buffer *buf)
-{
- Buffer::InFlightData &bfd(buf->d[currentPFrameIndex]);
- // Only enlarge, never shrink
- const bool newBufferNeeded = bfd.buffer ? (buf->cpuDataRef.size > bfd.resourceSize) : true;
- if (newBufferNeeded) {
- // Round it up and overallocate a little bit so that a subsequent
- // buffer contents rebuild with a slightly larger total size does
- // not lead to creating a new buffer.
- const quint32 sz = alignedSize(buf->cpuDataRef.size, 4096);
- if (Q_UNLIKELY(debug_render()))
- qDebug("new buffer[pf=%d] of size %d (actual data size %d)", currentPFrameIndex, sz, buf->cpuDataRef.size);
- bfd.buffer.Attach(createBuffer(sz));
- bfd.resourceSize = sz;
- }
- // Cache the actual data size in the per-in-flight-frame data as well.
- bfd.dataSize = buf->cpuDataRef.size;
-}
-
-void QSGD3D12EnginePrivate::updateBuffer(Buffer *buf)
-{
- if (buf->cpuDataRef.dirty.isEmpty())
- return;
-
- Buffer::InFlightData &bfd(buf->d[currentPFrameIndex]);
- quint8 *p = nullptr;
- const D3D12_RANGE readRange = { 0, 0 };
- if (FAILED(bfd.buffer->Map(0, &readRange, reinterpret_cast<void **>(&p)))) {
- qWarning("Map failed for buffer of size %d", buf->cpuDataRef.size);
- return;
- }
- for (const auto &r : qAsConst(buf->cpuDataRef.dirty)) {
- if (Q_UNLIKELY(debug_render()))
- qDebug("%p o %d s %d", buf, r.first, r.second);
- memcpy(p + r.first, buf->cpuDataRef.p + r.first, r.second);
- }
- bfd.buffer->Unmap(0, nullptr);
- buf->cpuDataRef.dirty.clear();
-}
-
-void QSGD3D12EnginePrivate::beginFrame()
-{
- if (inFrame && !activeLayers)
- qFatal("beginFrame called again without an endFrame, frame index was %d", frameIndex);
-
- if (Q_UNLIKELY(debug_render()))
- qDebug() << "***** begin frame, logical" << frameIndex << "present" << presentFrameIndex << "layer" << activeLayers;
-
- if (inFrame && activeLayers) {
- if (Q_UNLIKELY(debug_render()))
- qDebug("frame %d already in progress", frameIndex);
- if (!currentLayerDepth) {
- // There are layers and the real frame preparation starts now. Prepare for present.
- beginFrameDraw();
- }
- return;
- }
-
- inFrame = true;
-
- // The device may have been lost. This is the point to attempt to start again from scratch.
- if (!initialized && window)
- initialize(window, windowSize, windowDpr, windowSamples);
-
- // Wait for a buffer to be available for Present, if the waitable event is in use.
- if (waitableSwapChainMaxLatency)
- WaitForSingleObject(swapEvent, INFINITE);
-
- // Block if needed. With 2 frames in flight frame N waits for frame N - 2, but not N - 1, to finish.
- currentPFrameIndex = frameIndex % frameInFlightCount;
- if (frameIndex >= frameInFlightCount) {
- ID3D12Fence *fence = frameFence[currentPFrameIndex]->fence.Get();
- HANDLE event = frameFence[currentPFrameIndex]->event;
- // Frame fence values start from 1, hence the +1.
- const quint64 inFlightFenceValue = frameIndex - frameInFlightCount + 1;
- if (fence->GetCompletedValue() < inFlightFenceValue) {
- fence->SetEventOnCompletion(inFlightFenceValue, event);
- WaitForSingleObject(event, INFINITE);
- }
- frameCommandAllocator[currentPFrameIndex]->Reset();
- }
-
- PersistentFrameData &pfd(pframeData[currentPFrameIndex]);
- pfd.cbvSrvUavNextFreeDescriptorIndex = 0;
-
- for (Buffer &b : buffers) {
- if (b.entryInUse())
- b.d[currentPFrameIndex].dirty.clear();
- }
-
- if (frameIndex >= frameInFlightCount) {
- // Now sync the buffer changes from the previous, potentially still in
- // flight, frames. This is done by taking the ranges dirtied in those
- // frames and adding them to the global CPU-side buffer's dirty list,
- // as if this frame changed those ranges. (however, dirty ranges
- // inherited this way are not added to this frame's persistent
- // per-frame dirty list because the next frame after this one should
- // inherit this frame's genuine changes only, the rest will come from
- // the earlier ones)
- for (int delta = frameInFlightCount - 1; delta >= 1; --delta) {
- const int prevPFrameIndex = (frameIndex - delta) % frameInFlightCount;
- PersistentFrameData &prevFrameData(pframeData[prevPFrameIndex]);
- for (uint id : qAsConst(prevFrameData.buffersUsedInFrame)) {
- Buffer &b(buffers[id - 1]);
- if (b.d[currentPFrameIndex].buffer && b.d[currentPFrameIndex].dataSize == b.cpuDataRef.size) {
- if (Q_UNLIKELY(debug_render()))
- qDebug() << "frame" << frameIndex << "takes dirty" << b.d[prevPFrameIndex].dirty
- << "from frame" << frameIndex - delta << "for buffer" << id;
- for (const auto &range : qAsConst(b.d[prevPFrameIndex].dirty))
- addDirtyRange(&b.cpuDataRef.dirty, range.first, range.second, b.cpuDataRef.size);
- } else {
- if (Q_UNLIKELY(debug_render()))
- qDebug() << "frame" << frameIndex << "makes all dirty from frame" << frameIndex - delta
- << "for buffer" << id;
- addDirtyRange(&b.cpuDataRef.dirty, 0, b.cpuDataRef.size, b.cpuDataRef.size);
- }
- }
- }
-
- // Do some texture upload bookkeeping.
- const quint64 finishedFrameIndex = frameIndex - frameInFlightCount; // we know since we just blocked for this
- // pfd conveniently refers to the same slot that was used by that frame
- if (!pfd.pendingTextureUploads.isEmpty()) {
- if (Q_UNLIKELY(debug_render()))
- qDebug("Removing texture upload data for frame %d", finishedFrameIndex);
- for (uint id : qAsConst(pfd.pendingTextureUploads)) {
- const int idx = id - 1;
- Texture &t(textures[idx]);
- // fenceValue is 0 when the previous frame cleared it, skip in
- // this case. Skip also when fenceValue > the value it was when
- // adding the last GPU wait - this is the case when more
- // uploads were queued for the same texture in the meantime.
- if (t.fenceValue && t.fenceValue == t.lastWaitFenceValue) {
- t.fenceValue = 0;
- t.lastWaitFenceValue = 0;
- t.stagingBuffers.clear();
- t.stagingHeaps.clear();
- if (Q_UNLIKELY(debug_render()))
- qDebug("Cleaned staging data for texture %u", id);
- }
- }
- pfd.pendingTextureUploads.clear();
- if (!pfd.pendingTextureMipMap.isEmpty()) {
- if (Q_UNLIKELY(debug_render()))
- qDebug() << "cleaning mipmap generation data for " << pfd.pendingTextureMipMap;
- // no special cleanup is needed as mipmap generation uses the frame's resources
- pfd.pendingTextureMipMap.clear();
- }
- bool hasPending = false;
- for (int delta = 1; delta < frameInFlightCount; ++delta) {
- const PersistentFrameData &prevFrameData(pframeData[(frameIndex - delta) % frameInFlightCount]);
- if (!prevFrameData.pendingTextureUploads.isEmpty()) {
- hasPending = true;
- break;
- }
- }
- if (!hasPending) {
- if (Q_UNLIKELY(debug_render()))
- qDebug("no more pending textures");
- copyCommandAllocator->Reset();
- }
- }
-
- // Do the deferred deletes.
- if (!pfd.deleteQueue.isEmpty()) {
- for (PersistentFrameData::DeleteQueueEntry &e : pfd.deleteQueue) {
- e.res = nullptr;
- e.descHeap = nullptr;
- if (e.cpuDescriptorPtr) {
- D3D12_CPU_DESCRIPTOR_HANDLE h = { e.cpuDescriptorPtr };
- cpuDescHeapManager.release(h, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- }
- }
- pfd.deleteQueue.clear();
- }
- // Deferred deletes issued outside a begin-endFrame go to the next
- // frame's out-of-frame delete queue as these cannot be executed in the
- // next beginFrame, only in next + frameInFlightCount. Move to the
- // normal queue if this is the next beginFrame.
- if (!pfd.outOfFrameDeleteQueue.isEmpty()) {
- pfd.deleteQueue = pfd.outOfFrameDeleteQueue;
- pfd.outOfFrameDeleteQueue.clear();
- }
-
- // Mark released texture, buffer, etc. slots free.
- if (!pfd.pendingReleases.isEmpty()) {
- for (const auto &pr : qAsConst(pfd.pendingReleases)) {
- Q_ASSERT(pr.id);
- if (pr.type == PersistentFrameData::PendingRelease::TypeTexture) {
- Texture &t(textures[pr.id - 1]);
- Q_ASSERT(t.entryInUse());
- t.flags &= ~RenderTarget::EntryInUse; // createTexture() can now reuse this entry
- t.texture = nullptr;
- } else if (pr.type == PersistentFrameData::PendingRelease::TypeBuffer) {
- Buffer &b(buffers[pr.id - 1]);
- Q_ASSERT(b.entryInUse());
- b.flags &= ~Buffer::EntryInUse;
- for (int i = 0; i < frameInFlightCount; ++i)
- b.d[i].buffer = nullptr;
- } else {
- qFatal("Corrupt pending release list, type %d", pr.type);
- }
- }
- pfd.pendingReleases.clear();
- }
- if (!pfd.outOfFramePendingReleases.isEmpty()) {
- pfd.pendingReleases = pfd.outOfFramePendingReleases;
- pfd.outOfFramePendingReleases.clear();
- }
- }
-
- pfd.buffersUsedInFrame.clear();
-
- beginDrawCalls();
-
- // Prepare for present if this is a frame without layers.
- if (!activeLayers)
- beginFrameDraw();
-}
-
-void QSGD3D12EnginePrivate::beginDrawCalls()
-{
- frameCommandList->Reset(frameCommandAllocator[frameIndex % frameInFlightCount].Get(), nullptr);
- commandList = frameCommandList.Get();
-
- tframeData.drawingMode = QSGGeometry::DrawingMode(-1);
- tframeData.currentIndexBuffer = 0;
- tframeData.drawCount = 0;
- tframeData.lastPso = nullptr;
- tframeData.lastRootSig = nullptr;
- tframeData.descHeapSet = false;
-}
-
-void QSGD3D12EnginePrivate::beginFrameDraw()
-{
- if (windowSamples == 1)
- transitionResource(defaultRT[presentFrameIndex % swapChainBufferCount].Get(), commandList,
- D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
-}
-
-void QSGD3D12EnginePrivate::endFrame()
-{
- if (!inFrame)
- qFatal("endFrame called without beginFrame, frame index %d", frameIndex);
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("***** end frame");
-
- endDrawCalls(true);
-
- commandQueue->Signal(frameFence[frameIndex % frameInFlightCount]->fence.Get(), frameIndex + 1);
- ++frameIndex;
-
- inFrame = false;
-}
-
-void QSGD3D12EnginePrivate::endDrawCalls(bool lastInFrame)
-{
- PersistentFrameData &pfd(pframeData[currentPFrameIndex]);
-
- // Now is the time to sync all the changed areas in the buffers.
- if (Q_UNLIKELY(debug_render()))
- qDebug() << "buffers used in drawcall set" << pfd.buffersUsedInDrawCallSet;
- for (uint id : qAsConst(pfd.buffersUsedInDrawCallSet))
- updateBuffer(&buffers[id - 1]);
-
- pfd.buffersUsedInFrame += pfd.buffersUsedInDrawCallSet;
- pfd.buffersUsedInDrawCallSet.clear();
-
- // Add a wait on the 3D queue for the relevant texture uploads on the copy queue.
- if (!pfd.pendingTextureUploads.isEmpty()) {
- quint64 topFenceValue = 0;
- for (uint id : qAsConst(pfd.pendingTextureUploads)) {
- const int idx = id - 1;
- Texture &t(textures[idx]);
- Q_ASSERT(t.fenceValue);
- // skip if already added a Wait in the previous frame
- if (t.lastWaitFenceValue == t.fenceValue)
- continue;
- t.lastWaitFenceValue = t.fenceValue;
- if (t.fenceValue > topFenceValue)
- topFenceValue = t.fenceValue;
- if (t.mipmap())
- pfd.pendingTextureMipMap.insert(id);
- }
- if (topFenceValue) {
- if (Q_UNLIKELY(debug_render()))
- qDebug("added wait for texture fence %llu", topFenceValue);
- commandQueue->Wait(textureUploadFence.Get(), topFenceValue);
- // Generate mipmaps after the wait, when necessary.
- if (!pfd.pendingTextureMipMap.isEmpty()) {
- if (Q_UNLIKELY(debug_render()))
- qDebug() << "starting mipmap generation for" << pfd.pendingTextureMipMap;
- for (uint id : qAsConst(pfd.pendingTextureMipMap))
- mipmapper.queueGenerate(textures[id - 1]);
- }
- }
- }
-
- if (lastInFrame) {
- // Resolve and transition the backbuffer for present, if needed.
- const int idx = presentFrameIndex % swapChainBufferCount;
- if (windowSamples == 1) {
- transitionResource(defaultRT[idx].Get(), commandList,
- D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
- } else {
- if (Q_UNLIKELY(debug_render())) {
- const D3D12_RESOURCE_DESC desc = defaultRT[idx]->GetDesc();
- qDebug("added resolve for multisampled render target (count %d, quality %d)",
- desc.SampleDesc.Count, desc.SampleDesc.Quality);
- }
- resolveMultisampledTarget(defaultRT[idx].Get(), backBufferRT[idx].Get(),
- D3D12_RESOURCE_STATE_PRESENT, commandList);
- }
-
- if (activeLayers) {
- if (Q_UNLIKELY(debug_render()))
- qDebug("this frame had %d layers", activeLayers);
- activeLayers = 0;
- }
- }
-
- // Go!
- HRESULT hr = frameCommandList->Close();
- if (FAILED(hr)) {
- qWarning("Failed to close command list: 0x%x", hr);
- if (hr == E_INVALIDARG)
- qWarning("Invalid arguments. Some of the commands in the list is invalid in some way.");
- }
-
- ID3D12CommandList *commandLists[] = { frameCommandList.Get() };
- commandQueue->ExecuteCommandLists(_countof(commandLists), commandLists);
-
- commandList = nullptr;
-}
-
-void QSGD3D12EnginePrivate::beginLayer()
-{
- if (inFrame && !activeLayers)
- qFatal("Layer rendering cannot be started while a frame is active");
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("===== beginLayer active %d depth %d (inFrame=%d)", activeLayers, currentLayerDepth, inFrame);
-
- ++activeLayers;
- ++currentLayerDepth;
-
- // Do an early beginFrame. With multiple layers this results in
- // beginLayer - beginFrame - endLayer - beginLayer - beginFrame - endLayer - ... - (*) beginFrame - endFrame
- // where (*) denotes the start of the preparation of the actual, non-layer frame.
-
- if (activeLayers == 1)
- beginFrame();
-}
-
-void QSGD3D12EnginePrivate::endLayer()
-{
- if (!inFrame || !activeLayers || !currentLayerDepth)
- qFatal("Mismatched endLayer");
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("===== endLayer active %d depth %d", activeLayers, currentLayerDepth);
-
- --currentLayerDepth;
-
- // Do not touch activeLayers. It remains valid until endFrame.
-}
-
-// Root signature:
-// [0] CBV - always present
-// [1] table with 1 SRV per texture (optional)
-// one static sampler per texture (optional)
-//
-// SRVs can be created freely via QSGD3D12CPUDescriptorHeapManager and stored
-// in QSGD3D12TextureView. The engine will copy them onto a dedicated,
-// shader-visible CBV-SRV-UAV heap in the correct order.
-
-void QSGD3D12EnginePrivate::finalizePipeline(const QSGD3D12PipelineState &pipelineState)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- tframeData.pipelineState = pipelineState;
-
- RootSigCacheEntry *cachedRootSig = rootSigCache[pipelineState.shaders.rootSig];
- if (!cachedRootSig) {
- if (Q_UNLIKELY(debug_render()))
- qDebug("NEW ROOTSIG");
-
- cachedRootSig = new RootSigCacheEntry;
-
- D3D12_ROOT_PARAMETER rootParams[4];
- int rootParamCount = 0;
-
- rootParams[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
- rootParams[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- rootParams[0].Descriptor.ShaderRegister = 0; // b0
- rootParams[0].Descriptor.RegisterSpace = 0;
- ++rootParamCount;
-
- if (!pipelineState.shaders.rootSig.textureViews.isEmpty()) {
- rootParams[rootParamCount].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
- rootParams[rootParamCount].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
- rootParams[rootParamCount].DescriptorTable.NumDescriptorRanges = 1;
- D3D12_DESCRIPTOR_RANGE descRange;
- descRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
- descRange.NumDescriptors = pipelineState.shaders.rootSig.textureViews.count();
- descRange.BaseShaderRegister = 0; // t0, t1, ...
- descRange.RegisterSpace = 0;
- descRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
- rootParams[rootParamCount].DescriptorTable.pDescriptorRanges = &descRange;
- ++rootParamCount;
- }
-
- Q_ASSERT(rootParamCount <= _countof(rootParams));
- D3D12_ROOT_SIGNATURE_DESC desc;
- desc.NumParameters = rootParamCount;
- desc.pParameters = rootParams;
- desc.NumStaticSamplers = pipelineState.shaders.rootSig.textureViews.count();
- D3D12_STATIC_SAMPLER_DESC staticSamplers[8];
- int sdIdx = 0;
- Q_ASSERT(pipelineState.shaders.rootSig.textureViews.count() <= _countof(staticSamplers));
- for (const QSGD3D12TextureView &tv : qAsConst(pipelineState.shaders.rootSig.textureViews)) {
- D3D12_STATIC_SAMPLER_DESC sd = {};
- sd.Filter = D3D12_FILTER(tv.filter);
- sd.AddressU = D3D12_TEXTURE_ADDRESS_MODE(tv.addressModeHoriz);
- sd.AddressV = D3D12_TEXTURE_ADDRESS_MODE(tv.addressModeVert);
- sd.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
- sd.MinLOD = 0.0f;
- sd.MaxLOD = D3D12_FLOAT32_MAX;
- sd.ShaderRegister = sdIdx; // t0, t1, ...
- sd.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
- staticSamplers[sdIdx++] = sd;
- }
- desc.pStaticSamplers = staticSamplers;
- desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
-
- ComPtr<ID3DBlob> signature;
- ComPtr<ID3DBlob> error;
- if (FAILED(D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error))) {
- qWarning("Failed to serialize root signature");
- return;
- }
- if (FAILED(device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(),
- IID_PPV_ARGS(&cachedRootSig->rootSig)))) {
- qWarning("Failed to create root signature");
- return;
- }
-
- rootSigCache.insert(pipelineState.shaders.rootSig, cachedRootSig);
- }
-
- PSOCacheEntry *cachedPso = psoCache[pipelineState];
- if (!cachedPso) {
- if (Q_UNLIKELY(debug_render()))
- qDebug("NEW PSO");
-
- cachedPso = new PSOCacheEntry;
-
- D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
-
- D3D12_INPUT_ELEMENT_DESC inputElements[8];
- Q_ASSERT(pipelineState.inputElements.count() <= _countof(inputElements));
- int ieIdx = 0;
- for (const QSGD3D12InputElement &ie : pipelineState.inputElements) {
- D3D12_INPUT_ELEMENT_DESC ieDesc = {};
- ieDesc.SemanticName = ie.semanticName;
- ieDesc.SemanticIndex = ie.semanticIndex;
- ieDesc.Format = DXGI_FORMAT(ie.format);
- ieDesc.InputSlot = ie.slot;
- ieDesc.AlignedByteOffset = ie.offset;
- ieDesc.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
- if (Q_UNLIKELY(debug_render()))
- qDebug("input [%d]: %s %d 0x%x %d", ieIdx, ie.semanticName, ie.offset, ie.format, ie.slot);
- inputElements[ieIdx++] = ieDesc;
- }
-
- psoDesc.InputLayout = { inputElements, UINT(ieIdx) };
-
- psoDesc.pRootSignature = cachedRootSig->rootSig.Get();
-
- D3D12_SHADER_BYTECODE vshader;
- vshader.pShaderBytecode = pipelineState.shaders.vs;
- vshader.BytecodeLength = pipelineState.shaders.vsSize;
- D3D12_SHADER_BYTECODE pshader;
- pshader.pShaderBytecode = pipelineState.shaders.ps;
- pshader.BytecodeLength = pipelineState.shaders.psSize;
-
- psoDesc.VS = vshader;
- psoDesc.PS = pshader;
-
- D3D12_RASTERIZER_DESC rastDesc = {};
- rastDesc.FillMode = D3D12_FILL_MODE_SOLID;
- rastDesc.CullMode = D3D12_CULL_MODE(pipelineState.cullMode);
- rastDesc.FrontCounterClockwise = pipelineState.frontCCW;
- rastDesc.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
- rastDesc.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
- rastDesc.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
- rastDesc.DepthClipEnable = TRUE;
-
- psoDesc.RasterizerState = rastDesc;
-
- D3D12_BLEND_DESC blendDesc = {};
- if (pipelineState.blend == QSGD3D12PipelineState::BlendNone) {
- D3D12_RENDER_TARGET_BLEND_DESC noBlendDesc = {};
- noBlendDesc.RenderTargetWriteMask = pipelineState.colorWrite ? D3D12_COLOR_WRITE_ENABLE_ALL : 0;
- blendDesc.RenderTarget[0] = noBlendDesc;
- } else if (pipelineState.blend == QSGD3D12PipelineState::BlendPremul) {
- const D3D12_RENDER_TARGET_BLEND_DESC premulBlendDesc = {
- TRUE, FALSE,
- D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
- D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
- D3D12_LOGIC_OP_NOOP,
- UINT8(pipelineState.colorWrite ? D3D12_COLOR_WRITE_ENABLE_ALL : 0)
- };
- blendDesc.RenderTarget[0] = premulBlendDesc;
- } else if (pipelineState.blend == QSGD3D12PipelineState::BlendColor) {
- const D3D12_RENDER_TARGET_BLEND_DESC colorBlendDesc = {
- TRUE, FALSE,
- D3D12_BLEND_BLEND_FACTOR, D3D12_BLEND_INV_SRC_COLOR, D3D12_BLEND_OP_ADD,
- D3D12_BLEND_BLEND_FACTOR, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
- D3D12_LOGIC_OP_NOOP,
- UINT8(pipelineState.colorWrite ? D3D12_COLOR_WRITE_ENABLE_ALL : 0)
- };
- blendDesc.RenderTarget[0] = colorBlendDesc;
- }
- psoDesc.BlendState = blendDesc;
-
- psoDesc.DepthStencilState.DepthEnable = pipelineState.depthEnable;
- psoDesc.DepthStencilState.DepthWriteMask = pipelineState.depthWrite ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO;
- psoDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC(pipelineState.depthFunc);
-
- psoDesc.DepthStencilState.StencilEnable = pipelineState.stencilEnable;
- psoDesc.DepthStencilState.StencilReadMask = psoDesc.DepthStencilState.StencilWriteMask = 0xFF;
- D3D12_DEPTH_STENCILOP_DESC stencilOpDesc = {
- D3D12_STENCIL_OP(pipelineState.stencilFailOp),
- D3D12_STENCIL_OP(pipelineState.stencilDepthFailOp),
- D3D12_STENCIL_OP(pipelineState.stencilPassOp),
- D3D12_COMPARISON_FUNC(pipelineState.stencilFunc)
- };
- psoDesc.DepthStencilState.FrontFace = psoDesc.DepthStencilState.BackFace = stencilOpDesc;
-
- psoDesc.SampleMask = UINT_MAX;
- psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE(pipelineState.topologyType);
- psoDesc.NumRenderTargets = 1;
- psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
- psoDesc.DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
- psoDesc.SampleDesc = defaultRT[0]->GetDesc().SampleDesc;
-
- HRESULT hr = device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&cachedPso->pso));
- if (FAILED(hr)) {
- qWarning("Failed to create graphics pipeline state");
- return;
- }
-
- psoCache.insert(pipelineState, cachedPso);
- }
-
- if (cachedPso->pso.Get() != tframeData.lastPso) {
- tframeData.lastPso = cachedPso->pso.Get();
- commandList->SetPipelineState(tframeData.lastPso);
- }
-
- if (cachedRootSig->rootSig.Get() != tframeData.lastRootSig) {
- tframeData.lastRootSig = cachedRootSig->rootSig.Get();
- commandList->SetGraphicsRootSignature(tframeData.lastRootSig);
- }
-
- if (!pipelineState.shaders.rootSig.textureViews.isEmpty())
- setDescriptorHeaps();
-}
-
-void QSGD3D12EnginePrivate::setDescriptorHeaps(bool force)
-{
- if (force || !tframeData.descHeapSet) {
- tframeData.descHeapSet = true;
- ID3D12DescriptorHeap *heaps[] = { pframeData[currentPFrameIndex].gpuCbvSrvUavHeap.Get() };
- commandList->SetDescriptorHeaps(_countof(heaps), heaps);
- }
-}
-
-void QSGD3D12EnginePrivate::queueViewport(const QRect &rect)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- tframeData.viewport = rect;
- const D3D12_VIEWPORT viewport = { float(rect.x()), float(rect.y()), float(rect.width()), float(rect.height()), 0, 1 };
- commandList->RSSetViewports(1, &viewport);
-}
-
-void QSGD3D12EnginePrivate::queueScissor(const QRect &rect)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- tframeData.scissor = rect;
- const D3D12_RECT scissorRect = { rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height() };
- commandList->RSSetScissorRects(1, &scissorRect);
-}
-
-void QSGD3D12EnginePrivate::queueSetRenderTarget(uint id)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle;
- D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle;
-
- if (!id) {
- rtvHandle = defaultRTV[presentFrameIndex % swapChainBufferCount];
- dsvHandle = defaultDSV;
- } else {
- const int idx = id - 1;
- Q_ASSERT(idx < renderTargets.count() && renderTargets[idx].entryInUse());
- RenderTarget &rt(renderTargets[idx]);
- rtvHandle = rt.rtv;
- dsvHandle = rt.dsv;
- rt.flags |= RenderTarget::NeedsReadBarrier;
- }
-
- commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, &dsvHandle);
-
- currentRenderTarget = id;
-}
-
-void QSGD3D12EnginePrivate::queueClearRenderTarget(const QColor &color)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- const float clearColor[] = { float(color.redF()), float(color.blueF()), float(color.greenF()), float(color.alphaF()) };
- D3D12_CPU_DESCRIPTOR_HANDLE rtv = !currentRenderTarget
- ? defaultRTV[presentFrameIndex % swapChainBufferCount]
- : renderTargets[currentRenderTarget - 1].rtv;
- commandList->ClearRenderTargetView(rtv, clearColor, 0, nullptr);
-}
-
-void QSGD3D12EnginePrivate::queueClearDepthStencil(float depthValue, quint8 stencilValue, QSGD3D12Engine::ClearFlags which)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- D3D12_CPU_DESCRIPTOR_HANDLE dsv = !currentRenderTarget
- ? defaultDSV
- : renderTargets[currentRenderTarget - 1].dsv;
- commandList->ClearDepthStencilView(dsv, D3D12_CLEAR_FLAGS(int(which)), depthValue, stencilValue, 0, nullptr);
-}
-
-void QSGD3D12EnginePrivate::queueSetBlendFactor(const QVector4D &factor)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- tframeData.blendFactor = factor;
- const float f[4] = { factor.x(), factor.y(), factor.z(), factor.w() };
- commandList->OMSetBlendFactor(f);
-}
-
-void QSGD3D12EnginePrivate::queueSetStencilRef(quint32 ref)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- tframeData.stencilRef = ref;
- commandList->OMSetStencilRef(ref);
-}
-
-void QSGD3D12EnginePrivate::queueDraw(const QSGD3D12Engine::DrawParams &params)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- const bool skip = tframeData.scissor.isEmpty();
-
- PersistentFrameData &pfd(pframeData[currentPFrameIndex]);
-
- pfd.buffersUsedInDrawCallSet.insert(params.vertexBuf);
- const int vertexBufIdx = params.vertexBuf - 1;
- Q_ASSERT(params.vertexBuf && vertexBufIdx < buffers.count() && buffers[vertexBufIdx].entryInUse());
- pfd.buffersUsedInDrawCallSet.insert(params.constantBuf);
- const int constantBufIdx = params.constantBuf - 1;
- Q_ASSERT(params.constantBuf && constantBufIdx < buffers.count() && buffers[constantBufIdx].entryInUse());
- int indexBufIdx = -1;
- if (params.indexBuf) {
- pfd.buffersUsedInDrawCallSet.insert(params.indexBuf);
- indexBufIdx = params.indexBuf - 1;
- Q_ASSERT(indexBufIdx < buffers.count() && buffers[indexBufIdx].entryInUse());
- }
-
- // Ensure buffers are created but do not copy the data here, leave that to endDrawCalls().
- ensureBuffer(&buffers[vertexBufIdx]);
- ensureBuffer(&buffers[constantBufIdx]);
- if (indexBufIdx >= 0)
- ensureBuffer(&buffers[indexBufIdx]);
-
- // Set the CBV.
- if (!skip && params.cboOffset >= 0) {
- ID3D12Resource *cbuf = buffers[constantBufIdx].d[currentPFrameIndex].buffer.Get();
- if (cbuf)
- commandList->SetGraphicsRootConstantBufferView(0, cbuf->GetGPUVirtualAddress() + params.cboOffset);
- }
-
- // Set up vertex and index buffers.
- ID3D12Resource *vbuf = buffers[vertexBufIdx].d[currentPFrameIndex].buffer.Get();
- ID3D12Resource *ibuf = indexBufIdx >= 0 && params.startIndexIndex >= 0
- ? buffers[indexBufIdx].d[currentPFrameIndex].buffer.Get() : nullptr;
-
- if (!skip && params.mode != tframeData.drawingMode) {
- D3D_PRIMITIVE_TOPOLOGY topology;
- switch (params.mode) {
- case QSGGeometry::DrawPoints:
- topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
- break;
- case QSGGeometry::DrawLines:
- topology = D3D_PRIMITIVE_TOPOLOGY_LINELIST;
- break;
- case QSGGeometry::DrawLineStrip:
- topology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
- break;
- case QSGGeometry::DrawTriangles:
- topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
- break;
- case QSGGeometry::DrawTriangleStrip:
- topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
- break;
- default:
- qFatal("Unsupported drawing mode 0x%x", params.mode);
- break;
- }
- commandList->IASetPrimitiveTopology(topology);
- tframeData.drawingMode = params.mode;
- }
-
- if (!skip) {
- D3D12_VERTEX_BUFFER_VIEW vbv;
- vbv.BufferLocation = vbuf->GetGPUVirtualAddress() + params.vboOffset;
- vbv.SizeInBytes = params.vboSize;
- vbv.StrideInBytes = params.vboStride;
-
- // must be set after the topology
- commandList->IASetVertexBuffers(0, 1, &vbv);
- }
-
- if (!skip && params.startIndexIndex >= 0 && ibuf && tframeData.currentIndexBuffer != params.indexBuf) {
- tframeData.currentIndexBuffer = params.indexBuf;
- D3D12_INDEX_BUFFER_VIEW ibv;
- ibv.BufferLocation = ibuf->GetGPUVirtualAddress();
- ibv.SizeInBytes = buffers[indexBufIdx].cpuDataRef.size;
- ibv.Format = DXGI_FORMAT(params.indexFormat);
- commandList->IASetIndexBuffer(&ibv);
- }
-
- // Copy the SRVs to a drawcall-dedicated area of the shader-visible descriptor heap.
- Q_ASSERT(tframeData.activeTextures.count() == tframeData.pipelineState.shaders.rootSig.textureViews.count());
- if (!tframeData.activeTextures.isEmpty()) {
- if (!skip) {
- ensureGPUDescriptorHeap(tframeData.activeTextures.count());
- const uint stride = cpuDescHeapManager.handleSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- D3D12_CPU_DESCRIPTOR_HANDLE dst = pfd.gpuCbvSrvUavHeap->GetCPUDescriptorHandleForHeapStart();
- dst.ptr += pfd.cbvSrvUavNextFreeDescriptorIndex * stride;
- for (const TransientFrameData::ActiveTexture &t : qAsConst(tframeData.activeTextures)) {
- Q_ASSERT(t.id);
- const int idx = t.id - 1;
- const bool isTex = t.type == TransientFrameData::ActiveTexture::TypeTexture;
- device->CopyDescriptorsSimple(1, dst, isTex ? textures[idx].srv : renderTargets[idx].srv,
- D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- dst.ptr += stride;
- }
-
- D3D12_GPU_DESCRIPTOR_HANDLE gpuAddr = pfd.gpuCbvSrvUavHeap->GetGPUDescriptorHandleForHeapStart();
- gpuAddr.ptr += pfd.cbvSrvUavNextFreeDescriptorIndex * stride;
- commandList->SetGraphicsRootDescriptorTable(1, gpuAddr);
-
- pfd.cbvSrvUavNextFreeDescriptorIndex += tframeData.activeTextures.count();
- }
- tframeData.activeTextures.clear();
- }
-
- // Add the draw call.
- if (!skip) {
- ++tframeData.drawCount;
- if (params.startIndexIndex >= 0)
- commandList->DrawIndexedInstanced(params.count, 1, params.startIndexIndex, 0, 0);
- else
- commandList->DrawInstanced(params.count, 1, 0, 0);
- }
-
- if (tframeData.drawCount == MAX_DRAW_CALLS_PER_LIST) {
- if (Q_UNLIKELY(debug_render()))
- qDebug("Limit of %d draw calls reached, executing command list", MAX_DRAW_CALLS_PER_LIST);
- // submit the command list
- endDrawCalls();
- // start a new one
- beginDrawCalls();
- // prepare for the upcoming drawcalls
- queueSetRenderTarget(currentRenderTarget);
- queueViewport(tframeData.viewport);
- queueScissor(tframeData.scissor);
- queueSetBlendFactor(tframeData.blendFactor);
- queueSetStencilRef(tframeData.stencilRef);
- finalizePipeline(tframeData.pipelineState);
- }
-}
-
-void QSGD3D12EnginePrivate::ensureGPUDescriptorHeap(int cbvSrvUavDescriptorCount)
-{
- PersistentFrameData &pfd(pframeData[currentPFrameIndex]);
- int newSize = pfd.gpuCbvSrvUavHeapSize;
- while (pfd.cbvSrvUavNextFreeDescriptorIndex + cbvSrvUavDescriptorCount > newSize)
- newSize *= 2;
- if (newSize != pfd.gpuCbvSrvUavHeapSize) {
- if (Q_UNLIKELY(debug_render()))
- qDebug("Out of space for SRVs, creating new CBV-SRV-UAV descriptor heap with descriptor count %d", newSize);
- deferredDelete(pfd.gpuCbvSrvUavHeap);
- createCbvSrvUavHeap(currentPFrameIndex, newSize);
- setDescriptorHeaps(true);
- pfd.cbvSrvUavNextFreeDescriptorIndex = 0;
- }
-}
-
-void QSGD3D12EnginePrivate::present()
-{
- if (!initialized)
- return;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("--- present with vsync ---");
-
- // This call will not block the CPU unless at least 3 buffers are queued,
- // unless the waitable frame latency event is enabled. Then the latency of
- // 3 is changed to whatever value desired, and blocking happens in
- // beginFrame. If none of these hold, the fence-based wait in beginFrame
- // throttles. Vsync (interval 1) is always enabled.
- HRESULT hr = swapChain->Present(1, 0);
- if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) {
- deviceManager()->deviceLossDetected();
- return;
- } else if (FAILED(hr)) {
- qWarning("Present failed: 0x%x", hr);
- return;
- }
-
- ++presentFrameIndex;
-}
-
-void QSGD3D12EnginePrivate::waitGPU()
-{
- if (!initialized)
- return;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("--- blocking wait for GPU ---");
-
- waitForGPU(presentFence);
-}
-
-template<class T> uint newId(T *tbl)
-{
- uint id = 0;
- for (int i = 0; i < tbl->count(); ++i) {
- if (!(*tbl)[i].entryInUse()) {
- id = i + 1;
- break;
- }
- }
-
- if (!id) {
- tbl->resize(tbl->size() + 1);
- id = tbl->count();
- }
-
- (*tbl)[id - 1].flags = 0x01; // reset flags and set EntryInUse
-
- return id;
-}
-
-template<class T> void syncEntryFlags(T *e, int flag, bool b)
-{
- if (b)
- e->flags |= flag;
- else
- e->flags &= ~flag;
-}
-
-uint QSGD3D12EnginePrivate::genBuffer()
-{
- return newId(&buffers);
-}
-
-void QSGD3D12EnginePrivate::releaseBuffer(uint id)
-{
- if (!id)
- return;
-
- const int idx = id - 1;
- Q_ASSERT(idx < buffers.count());
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("releasing buffer %u", id);
-
- Buffer &b(buffers[idx]);
- if (!b.entryInUse())
- return;
-
- // Do not null out and do not mark the entry reusable yet.
- // Do that only when the frames potentially in flight have finished for sure.
-
- for (int i = 0; i < frameInFlightCount; ++i) {
- if (b.d[i].buffer)
- deferredDelete(b.d[i].buffer);
- }
-
- QSet<PersistentFrameData::PendingRelease> *pendingReleasesSet = inFrame
- ? &pframeData[currentPFrameIndex].pendingReleases
- : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFramePendingReleases;
-
- pendingReleasesSet->insert(PersistentFrameData::PendingRelease(PersistentFrameData::PendingRelease::TypeBuffer, id));
-}
-
-void QSGD3D12EnginePrivate::resetBuffer(uint id, const quint8 *data, int size)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- Q_ASSERT(id);
- const int idx = id - 1;
- Q_ASSERT(idx < buffers.count() && buffers[idx].entryInUse());
- Buffer &b(buffers[idx]);
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("reset buffer %u, size %d", id, size);
-
- b.cpuDataRef.p = data;
- b.cpuDataRef.size = size;
-
- b.cpuDataRef.dirty.clear();
- b.d[currentPFrameIndex].dirty.clear();
-
- if (size > 0) {
- const QPair<int, int> range = qMakePair(0, size);
- b.cpuDataRef.dirty.append(range);
- b.d[currentPFrameIndex].dirty.append(range);
- }
-}
-
-void QSGD3D12EnginePrivate::addDirtyRange(DirtyList *dirty, int offset, int size, int bufferSize)
-{
- // Bail out when the dirty list already spans the entire buffer.
- if (!dirty->isEmpty()) {
- if (dirty->at(0).first == 0 && dirty->at(0).second == bufferSize)
- return;
- }
-
- const QPair<int, int> range = qMakePair(offset, size);
- if (!dirty->contains(range))
- dirty->append(range);
-}
-
-void QSGD3D12EnginePrivate::markBufferDirty(uint id, int offset, int size)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- Q_ASSERT(id);
- const int idx = id - 1;
- Q_ASSERT(idx < buffers.count() && buffers[idx].entryInUse());
- Buffer &b(buffers[idx]);
-
- addDirtyRange(&b.cpuDataRef.dirty, offset, size, b.cpuDataRef.size);
- addDirtyRange(&b.d[currentPFrameIndex].dirty, offset, size, b.cpuDataRef.size);
-}
-
-uint QSGD3D12EnginePrivate::genTexture()
-{
- const uint id = newId(&textures);
- textures[id - 1].fenceValue = 0;
- return id;
-}
-
-static inline DXGI_FORMAT textureFormat(QImage::Format format, bool wantsAlpha, bool mipmap,
- QImage::Format *imageFormat, int *bytesPerPixel)
-{
- DXGI_FORMAT f = DXGI_FORMAT_R8G8B8A8_UNORM;
- QImage::Format convFormat = format;
- int bpp = 4;
-
- if (!mipmap) {
- switch (format) {
- case QImage::Format_Grayscale8:
- case QImage::Format_Indexed8:
- case QImage::Format_Alpha8:
- f = DXGI_FORMAT_R8_UNORM;
- bpp = 1;
- break;
- case QImage::Format_RGB32:
- f = DXGI_FORMAT_B8G8R8A8_UNORM;
- break;
- case QImage::Format_ARGB32:
- f = DXGI_FORMAT_B8G8R8A8_UNORM;
- convFormat = wantsAlpha ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
- break;
- case QImage::Format_ARGB32_Premultiplied:
- f = DXGI_FORMAT_B8G8R8A8_UNORM;
- convFormat = wantsAlpha ? format : QImage::Format_RGB32;
- break;
- default:
- convFormat = wantsAlpha ? QImage::Format_RGBA8888_Premultiplied : QImage::Format_RGBX8888;
- break;
- }
- } else {
- // Mipmap generation needs unordered access and BGRA is not an option for that. Stick to RGBA.
- convFormat = wantsAlpha ? QImage::Format_RGBA8888_Premultiplied : QImage::Format_RGBX8888;
- }
-
- if (imageFormat)
- *imageFormat = convFormat;
-
- if (bytesPerPixel)
- *bytesPerPixel = bpp;
-
- return f;
-}
-
-void QSGD3D12EnginePrivate::createTexture(uint id, const QSize &size, QImage::Format format,
- QSGD3D12Engine::TextureCreateFlags createFlags)
-{
- Q_ASSERT(id);
- const int idx = id - 1;
- Q_ASSERT(idx < textures.count() && textures[idx].entryInUse());
- Texture &t(textures[idx]);
-
- syncEntryFlags(&t, Texture::Alpha, createFlags & QSGD3D12Engine::CreateWithAlpha);
- syncEntryFlags(&t, Texture::MipMap, createFlags & QSGD3D12Engine::CreateWithMipMaps);
-
- const QSize adjustedSize = !t.mipmap() ? size : QSGD3D12Engine::mipMapAdjustedSourceSize(size);
-
- D3D12_HEAP_PROPERTIES defaultHeapProp = {};
- defaultHeapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
-
- D3D12_RESOURCE_DESC textureDesc = {};
- textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
- textureDesc.Width = adjustedSize.width();
- textureDesc.Height = adjustedSize.height();
- textureDesc.DepthOrArraySize = 1;
- textureDesc.MipLevels = !t.mipmap() ? 1 : QSGD3D12Engine::mipMapLevels(adjustedSize);
- textureDesc.Format = textureFormat(format, t.alpha(), t.mipmap(), nullptr, nullptr);
- textureDesc.SampleDesc.Count = 1;
- textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
- if (t.mipmap())
- textureDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
-
- HRESULT hr = device->CreateCommittedResource(&defaultHeapProp, D3D12_HEAP_FLAG_NONE, &textureDesc,
- D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(&t.texture));
- if (FAILED(hr)) {
- qWarning("Failed to create texture resource: 0x%x", hr);
- return;
- }
-
- t.srv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
-
- D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
- srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
- srvDesc.Format = textureDesc.Format;
- srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
- srvDesc.Texture2D.MipLevels = textureDesc.MipLevels;
-
- device->CreateShaderResourceView(t.texture.Get(), &srvDesc, t.srv);
-
- if (t.mipmap()) {
- // Mipmap generation will need an UAV for each level that needs to be generated.
- t.mipUAVs.clear();
- for (int level = 1; level < textureDesc.MipLevels; ++level) {
- D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
- uavDesc.Format = textureDesc.Format;
- uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
- uavDesc.Texture2D.MipSlice = level;
- D3D12_CPU_DESCRIPTOR_HANDLE h = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- device->CreateUnorderedAccessView(t.texture.Get(), nullptr, &uavDesc, h);
- t.mipUAVs.append(h);
- }
- }
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("created texture %u, size %dx%d, miplevels %d", id, adjustedSize.width(), adjustedSize.height(), textureDesc.MipLevels);
-}
-
-void QSGD3D12EnginePrivate::queueTextureResize(uint id, const QSize &size)
-{
- Q_ASSERT(id);
- const int idx = id - 1;
- Q_ASSERT(idx < textures.count() && textures[idx].entryInUse());
- Texture &t(textures[idx]);
-
- if (!t.texture) {
- qWarning("Cannot resize non-created texture %u", id);
- return;
- }
-
- if (t.mipmap()) {
- qWarning("Cannot resize mipmapped texture %u", id);
- return;
- }
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("resizing texture %u, size %dx%d", id, size.width(), size.height());
-
- D3D12_RESOURCE_DESC textureDesc = t.texture->GetDesc();
- textureDesc.Width = size.width();
- textureDesc.Height = size.height();
-
- D3D12_HEAP_PROPERTIES defaultHeapProp = {};
- defaultHeapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
-
- ComPtr<ID3D12Resource> oldTexture = t.texture;
- deferredDelete(t.texture);
-
- HRESULT hr = device->CreateCommittedResource(&defaultHeapProp, D3D12_HEAP_FLAG_NONE, &textureDesc,
- D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(&t.texture));
- if (FAILED(hr)) {
- qWarning("Failed to create resized texture resource: 0x%x", hr);
- return;
- }
-
- deferredDelete(t.srv);
- t.srv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
-
- D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
- srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
- srvDesc.Format = textureDesc.Format;
- srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
- srvDesc.Texture2D.MipLevels = textureDesc.MipLevels;
-
- device->CreateShaderResourceView(t.texture.Get(), &srvDesc, t.srv);
-
- D3D12_TEXTURE_COPY_LOCATION dstLoc;
- dstLoc.pResource = t.texture.Get();
- dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
- dstLoc.SubresourceIndex = 0;
-
- D3D12_TEXTURE_COPY_LOCATION srcLoc;
- srcLoc.pResource = oldTexture.Get();
- srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
- srcLoc.SubresourceIndex = 0;
-
- copyCommandList->Reset(copyCommandAllocator.Get(), nullptr);
-
- copyCommandList->CopyTextureRegion(&dstLoc, 0, 0, 0, &srcLoc, nullptr);
-
- copyCommandList->Close();
- ID3D12CommandList *commandLists[] = { copyCommandList.Get() };
- copyCommandQueue->ExecuteCommandLists(_countof(commandLists), commandLists);
-
- t.fenceValue = nextTextureUploadFenceValue.fetchAndAddAcquire(1) + 1;
- copyCommandQueue->Signal(textureUploadFence.Get(), t.fenceValue);
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("submitted old content copy for texture %u on the copy queue, fence %llu", id, t.fenceValue);
-}
-
-void QSGD3D12EnginePrivate::queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos)
-{
- Q_ASSERT(id);
- Q_ASSERT(images.count() == dstPos.count());
- if (images.isEmpty())
- return;
-
- const int idx = id - 1;
- Q_ASSERT(idx < textures.count() && textures[idx].entryInUse());
- Texture &t(textures[idx]);
- Q_ASSERT(t.texture);
-
- // When mipmapping is not in use, image can be smaller than the size passed
- // to createTexture() and dstPos can specify a non-zero destination position.
-
- if (t.mipmap() && (images.count() != 1 || dstPos.count() != 1 || !dstPos[0].isNull())) {
- qWarning("Mipmapped textures (%u) do not support partial uploads", id);
- return;
- }
-
- // Make life simpler by disallowing queuing a new mipmapped upload before the previous one finishes.
- if (t.mipmap() && t.fenceValue) {
- qWarning("Attempted to queue mipmapped texture upload (%u) while a previous upload is still in progress", id);
- return;
- }
-
- t.fenceValue = nextTextureUploadFenceValue.fetchAndAddAcquire(1) + 1;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("adding upload for texture %u on the copy queue, fence %llu", id, t.fenceValue);
-
- D3D12_RESOURCE_DESC textureDesc = t.texture->GetDesc();
- const QSize adjustedTextureSize(textureDesc.Width, textureDesc.Height);
-
- int totalSize = 0;
- for (const QImage &image : images) {
- int bytesPerPixel;
- textureFormat(image.format(), t.alpha(), t.mipmap(), nullptr, &bytesPerPixel);
- const int w = !t.mipmap() ? image.width() : adjustedTextureSize.width();
- const int h = !t.mipmap() ? image.height() : adjustedTextureSize.height();
- const int stride = alignedSize(w * bytesPerPixel, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
- totalSize += alignedSize(h * stride, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT);
- }
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("%d sub-uploads, heap size %d bytes", images.count(), totalSize);
-
- // Instead of individual committed resources for each upload buffer,
- // allocate only once and use placed resources.
- D3D12_HEAP_PROPERTIES uploadHeapProp = {};
- uploadHeapProp.Type = D3D12_HEAP_TYPE_UPLOAD;
- D3D12_HEAP_DESC uploadHeapDesc = {};
- uploadHeapDesc.SizeInBytes = totalSize;
- uploadHeapDesc.Properties = uploadHeapProp;
- uploadHeapDesc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
-
- Texture::StagingHeap sheap;
- if (FAILED(device->CreateHeap(&uploadHeapDesc, IID_PPV_ARGS(&sheap.heap)))) {
- qWarning("Failed to create texture upload heap of size %d", totalSize);
- return;
- }
- t.stagingHeaps.append(sheap);
-
- copyCommandList->Reset(copyCommandAllocator.Get(), nullptr);
-
- int placedOffset = 0;
- for (int i = 0; i < images.count(); ++i) {
- QImage::Format convFormat;
- int bytesPerPixel;
- textureFormat(images[i].format(), t.alpha(), t.mipmap(), &convFormat, &bytesPerPixel);
- if (Q_UNLIKELY(debug_render() && i == 0))
- qDebug("source image format %d, target format %d, bpp %d", images[i].format(), convFormat, bytesPerPixel);
-
- QImage convImage = images[i].format() == convFormat ? images[i] : images[i].convertToFormat(convFormat);
-
- if (t.mipmap() && adjustedTextureSize != convImage.size())
- convImage = convImage.scaled(adjustedTextureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
-
- const int stride = alignedSize(convImage.width() * bytesPerPixel, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
-
- D3D12_RESOURCE_DESC bufDesc = {};
- bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
- bufDesc.Width = stride * convImage.height();
- bufDesc.Height = 1;
- bufDesc.DepthOrArraySize = 1;
- bufDesc.MipLevels = 1;
- bufDesc.Format = DXGI_FORMAT_UNKNOWN;
- bufDesc.SampleDesc.Count = 1;
- bufDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
-
- Texture::StagingBuffer sbuf;
- if (FAILED(device->CreatePlacedResource(sheap.heap.Get(), placedOffset,
- &bufDesc, D3D12_RESOURCE_STATE_GENERIC_READ,
- nullptr, IID_PPV_ARGS(&sbuf.buffer)))) {
- qWarning("Failed to create texture upload buffer");
- return;
- }
-
- quint8 *p = nullptr;
- const D3D12_RANGE readRange = { 0, 0 };
- if (FAILED(sbuf.buffer->Map(0, &readRange, reinterpret_cast<void **>(&p)))) {
- qWarning("Map failed (texture upload buffer)");
- return;
- }
- for (int y = 0, ye = convImage.height(); y < ye; ++y) {
- memcpy(p, convImage.constScanLine(y), convImage.width() * bytesPerPixel);
- p += stride;
- }
- sbuf.buffer->Unmap(0, nullptr);
-
- D3D12_TEXTURE_COPY_LOCATION dstLoc;
- dstLoc.pResource = t.texture.Get();
- dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
- dstLoc.SubresourceIndex = 0;
-
- D3D12_TEXTURE_COPY_LOCATION srcLoc;
- srcLoc.pResource = sbuf.buffer.Get();
- srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
- srcLoc.PlacedFootprint.Offset = 0;
- srcLoc.PlacedFootprint.Footprint.Format = textureDesc.Format;
- srcLoc.PlacedFootprint.Footprint.Width = convImage.width();
- srcLoc.PlacedFootprint.Footprint.Height = convImage.height();
- srcLoc.PlacedFootprint.Footprint.Depth = 1;
- srcLoc.PlacedFootprint.Footprint.RowPitch = stride;
-
- copyCommandList->CopyTextureRegion(&dstLoc, dstPos[i].x(), dstPos[i].y(), 0, &srcLoc, nullptr);
-
- t.stagingBuffers.append(sbuf);
- placedOffset += alignedSize(bufDesc.Width, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT);
- }
-
- copyCommandList->Close();
- ID3D12CommandList *commandLists[] = { copyCommandList.Get() };
- copyCommandQueue->ExecuteCommandLists(_countof(commandLists), commandLists);
- copyCommandQueue->Signal(textureUploadFence.Get(), t.fenceValue);
-}
-
-void QSGD3D12EnginePrivate::releaseTexture(uint id)
-{
- if (!id)
- return;
-
- const int idx = id - 1;
- Q_ASSERT(idx < textures.count());
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("releasing texture %d", id);
-
- Texture &t(textures[idx]);
- if (!t.entryInUse())
- return;
-
- if (t.texture) {
- deferredDelete(t.texture);
- deferredDelete(t.srv);
- for (D3D12_CPU_DESCRIPTOR_HANDLE h : t.mipUAVs)
- deferredDelete(h);
- }
-
- QSet<PersistentFrameData::PendingRelease> *pendingReleasesSet = inFrame
- ? &pframeData[currentPFrameIndex].pendingReleases
- : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFramePendingReleases;
-
- pendingReleasesSet->insert(PersistentFrameData::PendingRelease(PersistentFrameData::PendingRelease::TypeTexture, id));
-}
-
-SIZE_T QSGD3D12EnginePrivate::textureSRV(uint id) const
-{
- Q_ASSERT(id);
- const int idx = id - 1;
- Q_ASSERT(idx < textures.count() && textures[idx].entryInUse());
- return textures[idx].srv.ptr;
-}
-
-void QSGD3D12EnginePrivate::activateTexture(uint id)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- Q_ASSERT(id);
- const int idx = id - 1;
- Q_ASSERT(idx < textures.count() && textures[idx].entryInUse());
-
- // activeTextures is a vector because the order matters
- tframeData.activeTextures.append(TransientFrameData::ActiveTexture(TransientFrameData::ActiveTexture::TypeTexture, id));
-
- if (textures[idx].fenceValue)
- pframeData[currentPFrameIndex].pendingTextureUploads.insert(id);
-}
-
-bool QSGD3D12EnginePrivate::MipMapGen::initialize(QSGD3D12EnginePrivate *enginePriv)
-{
- engine = enginePriv;
-
- D3D12_STATIC_SAMPLER_DESC sampler = {};
- sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
- sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
- sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
- sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
- sampler.MinLOD = 0.0f;
- sampler.MaxLOD = D3D12_FLOAT32_MAX;
-
- D3D12_DESCRIPTOR_RANGE descRange[2];
- descRange[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
- descRange[0].NumDescriptors = 1;
- descRange[0].BaseShaderRegister = 0; // t0
- descRange[0].RegisterSpace = 0;
- descRange[0].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
- descRange[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
- descRange[1].NumDescriptors = 4;
- descRange[1].BaseShaderRegister = 0; // u0..u3
- descRange[1].RegisterSpace = 0;
- descRange[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
-
- // Split into two to allow switching between the first and second set of UAVs later.
- D3D12_ROOT_PARAMETER rootParameters[3];
- rootParameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
- rootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- rootParameters[0].DescriptorTable.NumDescriptorRanges = 1;
- rootParameters[0].DescriptorTable.pDescriptorRanges = &descRange[0];
-
- rootParameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
- rootParameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- rootParameters[1].DescriptorTable.NumDescriptorRanges = 1;
- rootParameters[1].DescriptorTable.pDescriptorRanges = &descRange[1];
-
- rootParameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
- rootParameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- rootParameters[2].Constants.Num32BitValues = 4; // uint2 mip1Size, uint sampleLevel, uint totalMips
- rootParameters[2].Constants.ShaderRegister = 0; // b0
- rootParameters[2].Constants.RegisterSpace = 0;
-
- D3D12_ROOT_SIGNATURE_DESC desc = {};
- desc.NumParameters = 3;
- desc.pParameters = rootParameters;
- desc.NumStaticSamplers = 1;
- desc.pStaticSamplers = &sampler;
-
- ComPtr<ID3DBlob> signature;
- ComPtr<ID3DBlob> error;
- if (FAILED(D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error))) {
- QByteArray msg(static_cast<const char *>(error->GetBufferPointer()), error->GetBufferSize());
- qWarning("Failed to serialize compute root signature: %s", qPrintable(msg));
- return false;
- }
- if (FAILED(engine->device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(),
- IID_PPV_ARGS(&rootSig)))) {
- qWarning("Failed to create compute root signature");
- return false;
- }
-
- D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {};
- psoDesc.pRootSignature = rootSig.Get();
- psoDesc.CS.pShaderBytecode = g_CS_Generate4MipMaps;
- psoDesc.CS.BytecodeLength = sizeof(g_CS_Generate4MipMaps);
-
- if (FAILED(engine->device->CreateComputePipelineState(&psoDesc, IID_PPV_ARGS(&pipelineState)))) {
- qWarning("Failed to create compute pipeline state");
- return false;
- }
-
- return true;
-}
-
-void QSGD3D12EnginePrivate::MipMapGen::releaseResources()
-{
- pipelineState = nullptr;
- rootSig = nullptr;
-}
-
-// The mipmap generator is used to insert commands on the main 3D queue. It is
-// guaranteed that the queue has a wait for the base texture level upload
-// before invoking queueGenerate(). There can be any number of invocations
-// without waiting for earlier ones to finish. finished() is invoked when it is
-// known for sure that frame containing the upload and mipmap generation has
-// finished on the GPU.
-
-void QSGD3D12EnginePrivate::MipMapGen::queueGenerate(const Texture &t)
-{
- D3D12_RESOURCE_DESC textureDesc = t.texture->GetDesc();
-
- engine->commandList->SetPipelineState(pipelineState.Get());
- engine->commandList->SetComputeRootSignature(rootSig.Get());
-
- // 1 SRV + (miplevels - 1) UAVs
- const int descriptorCount = 1 + (textureDesc.MipLevels - 1);
-
- engine->ensureGPUDescriptorHeap(descriptorCount);
-
- // The descriptor heap is set on the command list either because the
- // ensure() call above resized, or, typically, due to a texture-dependent
- // draw call earlier.
-
- engine->transitionResource(t.texture.Get(), engine->commandList,
- D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
-
- QSGD3D12EnginePrivate::PersistentFrameData &pfd(engine->pframeData[engine->currentPFrameIndex]);
-
- const uint stride = engine->cpuDescHeapManager.handleSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- D3D12_CPU_DESCRIPTOR_HANDLE h = pfd.gpuCbvSrvUavHeap->GetCPUDescriptorHandleForHeapStart();
- h.ptr += pfd.cbvSrvUavNextFreeDescriptorIndex * stride;
-
- engine->device->CopyDescriptorsSimple(1, h, t.srv, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- h.ptr += stride;
-
- for (int level = 1; level < textureDesc.MipLevels; ++level, h.ptr += stride)
- engine->device->CopyDescriptorsSimple(1, h, t.mipUAVs[level - 1], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
-
- D3D12_GPU_DESCRIPTOR_HANDLE gpuAddr = pfd.gpuCbvSrvUavHeap->GetGPUDescriptorHandleForHeapStart();
- gpuAddr.ptr += pfd.cbvSrvUavNextFreeDescriptorIndex * stride;
-
- engine->commandList->SetComputeRootDescriptorTable(0, gpuAddr);
- gpuAddr.ptr += stride; // now points to the first UAV
-
- for (int level = 1; level < textureDesc.MipLevels; level += 4, gpuAddr.ptr += stride * 4) {
- engine->commandList->SetComputeRootDescriptorTable(1, gpuAddr);
-
- QSize sz(textureDesc.Width, textureDesc.Height);
- sz.setWidth(qMax(1, sz.width() >> level));
- sz.setHeight(qMax(1, sz.height() >> level));
-
- const quint32 constants[4] = { quint32(sz.width()), quint32(sz.height()),
- quint32(level - 1),
- quint32(textureDesc.MipLevels - 1) };
-
- engine->commandList->SetComputeRoot32BitConstants(2, 4, constants, 0);
- engine->commandList->Dispatch(sz.width(), sz.height(), 1);
- engine->uavBarrier(t.texture.Get(), engine->commandList);
- }
-
- engine->transitionResource(t.texture.Get(), engine->commandList,
- D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
-
- pfd.cbvSrvUavNextFreeDescriptorIndex += descriptorCount;
-}
-
-void QSGD3D12EnginePrivate::deferredDelete(ComPtr<ID3D12Resource> res)
-{
- PersistentFrameData::DeleteQueueEntry e;
- e.res = res;
- QVector<PersistentFrameData::DeleteQueueEntry> *dq = inFrame
- ? &pframeData[currentPFrameIndex].deleteQueue
- : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFrameDeleteQueue;
- (*dq) << e;
-}
-
-void QSGD3D12EnginePrivate::deferredDelete(ComPtr<ID3D12DescriptorHeap> dh)
-{
- PersistentFrameData::DeleteQueueEntry e;
- e.descHeap = dh;
- QVector<PersistentFrameData::DeleteQueueEntry> *dq = inFrame
- ? &pframeData[currentPFrameIndex].deleteQueue
- : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFrameDeleteQueue;
- (*dq) << e;
-}
-
-void QSGD3D12EnginePrivate::deferredDelete(D3D12_CPU_DESCRIPTOR_HANDLE h)
-{
- PersistentFrameData::DeleteQueueEntry e;
- e.cpuDescriptorPtr = h.ptr;
- QVector<PersistentFrameData::DeleteQueueEntry> *dq = inFrame
- ? &pframeData[currentPFrameIndex].deleteQueue
- : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFrameDeleteQueue;
- (*dq) << e;
-}
-
-uint QSGD3D12EnginePrivate::genRenderTarget()
-{
- return newId(&renderTargets);
-}
-
-void QSGD3D12EnginePrivate::createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, int samples)
-{
- Q_ASSERT(id);
- const int idx = id - 1;
- Q_ASSERT(idx < renderTargets.count() && renderTargets[idx].entryInUse());
- RenderTarget &rt(renderTargets[idx]);
-
- rt.rtv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
- rt.dsv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
- rt.srv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
-
- samples = qMax(1, samples);
- ID3D12Resource *res = createColorBuffer(rt.rtv, size, clearColor, samples);
- if (res)
- rt.color.Attach(res);
-
- ID3D12Resource *dsres = createDepthStencil(rt.dsv, size, samples);
- if (dsres)
- rt.ds.Attach(dsres);
-
- const bool multisample = rt.color->GetDesc().SampleDesc.Count > 1;
- syncEntryFlags(&rt, RenderTarget::Multisample, multisample);
-
- if (!multisample) {
- device->CreateShaderResourceView(rt.color.Get(), nullptr, rt.srv);
- } else {
- D3D12_HEAP_PROPERTIES defaultHeapProp = {};
- defaultHeapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
-
- D3D12_RESOURCE_DESC textureDesc = {};
- textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
- textureDesc.Width = size.width();
- textureDesc.Height = size.height();
- textureDesc.DepthOrArraySize = 1;
- textureDesc.MipLevels = 1;
- textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- textureDesc.SampleDesc.Count = 1;
- textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
-
- HRESULT hr = device->CreateCommittedResource(&defaultHeapProp, D3D12_HEAP_FLAG_NONE, &textureDesc,
- D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(&rt.colorResolve));
- if (FAILED(hr)) {
- qWarning("Failed to create resolve buffer: 0x%x", hr);
- return;
- }
-
- device->CreateShaderResourceView(rt.colorResolve.Get(), nullptr, rt.srv);
- }
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("created new render target %u, size %dx%d, samples %d", id, size.width(), size.height(), samples);
-}
-
-void QSGD3D12EnginePrivate::releaseRenderTarget(uint id)
-{
- if (!id)
- return;
-
- const int idx = id - 1;
- Q_ASSERT(idx < renderTargets.count());
- RenderTarget &rt(renderTargets[idx]);
- if (!rt.entryInUse())
- return;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("releasing render target %u", id);
-
- if (rt.colorResolve) {
- deferredDelete(rt.colorResolve);
- rt.colorResolve = nullptr;
- }
- if (rt.color) {
- deferredDelete(rt.color);
- rt.color = nullptr;
- deferredDelete(rt.rtv);
- deferredDelete(rt.srv);
- }
- if (rt.ds) {
- deferredDelete(rt.ds);
- rt.ds = nullptr;
- deferredDelete(rt.dsv);
- }
-
- rt.flags &= ~RenderTarget::EntryInUse;
-}
-
-void QSGD3D12EnginePrivate::activateRenderTargetAsTexture(uint id)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- Q_ASSERT(id);
- const int idx = id - 1;
- Q_ASSERT(idx < renderTargets.count());
- RenderTarget &rt(renderTargets[idx]);
- Q_ASSERT(rt.entryInUse() && rt.color);
-
- if (rt.flags & RenderTarget::NeedsReadBarrier) {
- rt.flags &= ~RenderTarget::NeedsReadBarrier;
- if (rt.flags & RenderTarget::Multisample)
- resolveMultisampledTarget(rt.color.Get(), rt.colorResolve.Get(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, commandList);
- else
- transitionResource(rt.color.Get(), commandList, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
- }
-
- tframeData.activeTextures.append(TransientFrameData::ActiveTexture::ActiveTexture(TransientFrameData::ActiveTexture::TypeRenderTarget, id));
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p.h
deleted file mode 100644
index 84bb5a554e..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p.h
+++ /dev/null
@@ -1,357 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12ENGINE_P_H
-#define QSGD3D12ENGINE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QWindow>
-#include <QImage>
-#include <QVector4D>
-#include <qsggeometry.h>
-#include <qt_windows.h>
-
-QT_BEGIN_NAMESPACE
-
-// No D3D or COM headers must be pulled in here. All that has to be isolated
-// to engine_p_p.h and engine.cpp.
-
-class QSGD3D12EnginePrivate;
-
-// Shader bytecode and other strings are expected to be static so that a
-// different pointer means a different shader.
-
-enum QSGD3D12Format {
- FmtUnknown = 0,
-
- FmtFloat4 = 2, // DXGI_FORMAT_R32G32B32A32_FLOAT
- FmtFloat3 = 6, // DXGI_FORMAT_R32G32B32_FLOAT
- FmtFloat2 = 16, // DXGI_FORMAT_R32G32_FLOAT
- FmtFloat = 41, // DXGI_FORMAT_R32_FLOAT
-
- // glVertexAttribPointer with GL_UNSIGNED_BYTE and normalized == true maps to the UNORM formats below
- FmtUNormByte4 = 28, // DXGI_FORMAT_R8G8B8A8_UNORM
- FmtUNormByte2 = 49, // DXGI_FORMAT_R8G8_UNORM
- FmtUNormByte = 61, // DXGI_FORMAT_R8_UNORM
-
- // Index data types
- FmtUnsignedShort = 57, // DXGI_FORMAT_R16_UINT
- FmtUnsignedInt = 42 // DXGI_FORMAT_R32_UINT
-};
-
-struct QSGD3D12InputElement
-{
- const char *semanticName = nullptr;
- int semanticIndex = 0;
- QSGD3D12Format format = FmtFloat4;
- quint32 slot = 0;
- quint32 offset = 0;
-
- bool operator==(const QSGD3D12InputElement &other) const {
- return semanticName == other.semanticName && semanticIndex == other.semanticIndex
- && format == other.format && slot == other.slot && offset == other.offset;
- }
-};
-
-inline uint qHash(const QSGD3D12InputElement &key, uint seed = 0)
-{
- return qHash(key.semanticName, seed) + key.semanticIndex + key.format + key.offset;
-}
-
-struct QSGD3D12TextureView
-{
- enum Filter {
- FilterNearest = 0,
- FilterLinear = 0x15,
- FilterMinMagNearestMipLinear = 0x1,
- FilterMinMagLinearMipNearest = 0x14
- };
-
- enum AddressMode {
- AddressWrap = 1,
- AddressClamp = 3
- };
-
- Filter filter = FilterLinear;
- AddressMode addressModeHoriz = AddressClamp;
- AddressMode addressModeVert = AddressClamp;
-
- bool operator==(const QSGD3D12TextureView &other) const {
- return filter == other.filter
- && addressModeHoriz == other.addressModeHoriz
- && addressModeVert == other.addressModeVert;
- }
-};
-
-inline uint qHash(const QSGD3D12TextureView &key, uint seed = 0)
-{
- Q_UNUSED(seed);
- return key.filter + key.addressModeHoriz + key.addressModeVert;
-}
-
-struct QSGD3D12RootSignature
-{
- QVector<QSGD3D12TextureView> textureViews;
-
- bool operator==(const QSGD3D12RootSignature &other) const {
- return textureViews == other.textureViews;
- }
-};
-
-inline uint qHash(const QSGD3D12RootSignature &key, uint seed = 0)
-{
- return qHash(key.textureViews, seed);
-}
-
-// Shader bytecode blobs and root signature-related data.
-struct QSGD3D12ShaderState
-{
- const quint8 *vs = nullptr;
- quint32 vsSize = 0;
- const quint8 *ps = nullptr;
- quint32 psSize = 0;
-
- QSGD3D12RootSignature rootSig;
-
- bool operator==(const QSGD3D12ShaderState &other) const {
- return vs == other.vs && vsSize == other.vsSize
- && ps == other.ps && psSize == other.psSize
- && rootSig == other.rootSig;
- }
-};
-
-inline uint qHash(const QSGD3D12ShaderState &key, uint seed = 0)
-{
- return qHash(key.vs, seed) + key.vsSize + qHash(key.ps, seed) + key.psSize + qHash(key.rootSig, seed);
-}
-
-struct QSGD3D12PipelineState
-{
- enum CullMode {
- CullNone = 1,
- CullFront,
- CullBack
- };
-
- enum CompareFunc {
- CompareNever = 1,
- CompareLess,
- CompareEqual,
- CompareLessEqual,
- CompareGreater,
- CompareNotEqual,
- CompareGreaterEqual,
- CompareAlways
- };
-
- enum StencilOp {
- StencilKeep = 1,
- StencilZero,
- StencilReplace,
- StencilIncrSat,
- StencilDecrSat,
- StencilInvert,
- StencilIncr,
- StencilDescr
- };
-
- enum TopologyType {
- TopologyTypePoint = 1,
- TopologyTypeLine,
- TopologyTypeTriangle
- };
-
- enum BlendType {
- BlendNone,
- BlendPremul, // == GL_ONE, GL_ONE_MINUS_SRC_ALPHA
- BlendColor // == GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR
- };
-
- QSGD3D12ShaderState shaders;
-
- QVector<QSGD3D12InputElement> inputElements;
-
- CullMode cullMode = CullNone;
- bool frontCCW = true;
- bool colorWrite = true;
- BlendType blend = BlendNone;
- bool depthEnable = true;
- CompareFunc depthFunc = CompareLess;
- bool depthWrite = true;
- bool stencilEnable = false;
- CompareFunc stencilFunc = CompareEqual;
- StencilOp stencilFailOp = StencilKeep;
- StencilOp stencilDepthFailOp = StencilKeep;
- StencilOp stencilPassOp = StencilKeep;
- TopologyType topologyType = TopologyTypeTriangle;
-
- bool operator==(const QSGD3D12PipelineState &other) const {
- return shaders == other.shaders
- && inputElements == other.inputElements
- && cullMode == other.cullMode
- && frontCCW == other.frontCCW
- && colorWrite == other.colorWrite
- && blend == other.blend
- && depthEnable == other.depthEnable
- && (!depthEnable || depthFunc == other.depthFunc)
- && depthWrite == other.depthWrite
- && stencilEnable == other.stencilEnable
- && (!stencilEnable || stencilFunc == other.stencilFunc)
- && (!stencilEnable || stencilFailOp == other.stencilFailOp)
- && (!stencilEnable || stencilDepthFailOp == other.stencilDepthFailOp)
- && (!stencilEnable || stencilPassOp == other.stencilPassOp)
- && topologyType == other.topologyType;
- }
-};
-
-inline uint qHash(const QSGD3D12PipelineState &key, uint seed = 0)
-{
- return qHash(key.shaders, seed) + qHash(key.inputElements, seed)
- + key.cullMode + key.frontCCW
- + key.colorWrite + key.blend
- + key.depthEnable + key.depthWrite
- + key.stencilEnable
- + key.topologyType;
-}
-
-class QSGD3D12Engine
-{
-public:
- QSGD3D12Engine();
- ~QSGD3D12Engine();
-
- bool attachToWindow(WId window, const QSize &size, float dpr, int samples);
- void releaseResources();
- bool hasResources() const;
- void setWindowSize(const QSize &size, float dpr);
- WId window() const;
- QSize windowSize() const;
- float windowDevicePixelRatio() const;
-
- void beginFrame();
- void endFrame();
- void beginLayer();
- void endLayer();
-
- uint genBuffer();
- void releaseBuffer(uint id);
- void resetBuffer(uint id, const quint8 *data, int size);
- void markBufferDirty(uint id, int offset, int size);
-
- enum ClearFlag {
- ClearDepth = 0x1,
- ClearStencil = 0x2
- };
- Q_DECLARE_FLAGS(ClearFlags, ClearFlag)
-
- void queueViewport(const QRect &rect);
- void queueScissor(const QRect &rect);
- void queueSetRenderTarget(uint id = 0);
- void queueClearRenderTarget(const QColor &color);
- void queueClearDepthStencil(float depthValue, quint8 stencilValue, ClearFlags which);
- void queueSetBlendFactor(const QVector4D &factor);
- void queueSetStencilRef(quint32 ref);
-
- void finalizePipeline(const QSGD3D12PipelineState &pipelineState);
-
- struct DrawParams {
- QSGGeometry::DrawingMode mode = QSGGeometry::DrawTriangles;
- int count = 0;
- uint vertexBuf = 0;
- uint indexBuf = 0;
- uint constantBuf = 0;
- int vboOffset = 0;
- int vboSize = 0;
- int vboStride = 0;
- int cboOffset = 0;
- int startIndexIndex = -1;
- QSGD3D12Format indexFormat = FmtUnsignedShort;
- };
-
- void queueDraw(const DrawParams &params);
-
- void present();
- void waitGPU();
-
- static quint32 alignedConstantBufferSize(quint32 size);
- static QSGD3D12Format toDXGIFormat(QSGGeometry::Type sgtype, int tupleSize = 1, int *size = nullptr);
- static int mipMapLevels(const QSize &size);
- static QSize mipMapAdjustedSourceSize(const QSize &size);
-
- enum TextureCreateFlag {
- CreateWithAlpha = 0x1,
- CreateWithMipMaps = 0x2
- };
- Q_DECLARE_FLAGS(TextureCreateFlags, TextureCreateFlag)
-
- uint genTexture();
- void createTexture(uint id, const QSize &size, QImage::Format format, TextureCreateFlags flags);
- void queueTextureResize(uint id, const QSize &size);
- void queueTextureUpload(uint id, const QImage &image, const QPoint &dstPos = QPoint());
- void queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos);
- void releaseTexture(uint id);
- SIZE_T textureSRV(uint id) const;
- void activateTexture(uint id);
-
- uint genRenderTarget();
- void createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, int samples);
- void releaseRenderTarget(uint id);
- void activateRenderTargetAsTexture(uint id);
-
-private:
- QSGD3D12EnginePrivate *d;
- Q_DISABLE_COPY(QSGD3D12Engine)
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Engine::ClearFlags)
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Engine::TextureCreateFlags)
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12ENGINE_P_H
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p_p.h
deleted file mode 100644
index 40d1fdb510..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p_p.h
+++ /dev/null
@@ -1,421 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12ENGINE_P_P_H
-#define QSGD3D12ENGINE_P_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qsgd3d12engine_p.h"
-#include <QCache>
-
-#include <d3d12.h>
-#include <dxgi1_4.h>
-#include <wrl/client.h>
-
-using namespace Microsoft::WRL;
-
-// No moc-related features (Q_OBJECT, signals, etc.) can be used here to due
-// moc-generated code failing to compile when combined with COM stuff.
-
-// Recommended reading before moving further: https://github.com/Microsoft/DirectXTK/wiki/ComPtr
-// Note esp. operator= vs. Attach and operator& vs. GetAddressOf
-
-// ID3D12* is never passed to Qt containers directly. Always use ComPtr and put it into a struct.
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12CPUDescriptorHeapManager
-{
-public:
- void initialize(ID3D12Device *device);
-
- void releaseResources();
-
- D3D12_CPU_DESCRIPTOR_HANDLE allocate(D3D12_DESCRIPTOR_HEAP_TYPE type);
- void release(D3D12_CPU_DESCRIPTOR_HANDLE handle, D3D12_DESCRIPTOR_HEAP_TYPE type);
- quint32 handleSize(D3D12_DESCRIPTOR_HEAP_TYPE type) const { return m_handleSizes[type]; }
-
-private:
- ID3D12Device *m_device = nullptr;
- struct Heap {
- D3D12_DESCRIPTOR_HEAP_TYPE type;
- ComPtr<ID3D12DescriptorHeap> heap;
- D3D12_CPU_DESCRIPTOR_HANDLE start;
- quint32 handleSize;
- quint32 freeMap[8];
- };
- QVector<Heap> m_heaps;
- quint32 m_handleSizes[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES];
-};
-
-class QSGD3D12DeviceManager
-{
-public:
- ID3D12Device *ref();
- void unref();
- void deviceLossDetected();
- IDXGIFactory4 *dxgi();
-
- struct DeviceLossObserver {
- virtual void deviceLost() = 0;
- };
- void registerDeviceLossObserver(DeviceLossObserver *observer);
-
-private:
- void ensureCreated();
-
- ComPtr<ID3D12Device> m_device;
- ComPtr<IDXGIFactory4> m_factory;
- QAtomicInt m_ref;
- QVector<DeviceLossObserver *> m_observers;
-};
-
-struct QSGD3D12CPUWaitableFence
-{
- ~QSGD3D12CPUWaitableFence() {
- if (event)
- CloseHandle(event);
- }
- ComPtr<ID3D12Fence> fence;
- HANDLE event = nullptr;
- QAtomicInt value;
-};
-
-class QSGD3D12EnginePrivate : public QSGD3D12DeviceManager::DeviceLossObserver
-{
-public:
- void initialize(WId w, const QSize &size, float dpr, int samples);
- bool isInitialized() const { return initialized; }
- void releaseResources();
- void setWindowSize(const QSize &size, float dpr);
- WId currentWindow() const { return window; }
- QSize currentWindowSize() const { return windowSize; }
- float currentWindowDpr() const { return windowDpr; }
-
- void beginFrame();
- void endFrame();
- void beginLayer();
- void endLayer();
-
- uint genBuffer();
- void releaseBuffer(uint id);
- void resetBuffer(uint id, const quint8 *data, int size);
- void markBufferDirty(uint id, int offset, int size);
-
- void queueViewport(const QRect &rect);
- void queueScissor(const QRect &rect);
- void queueSetRenderTarget(uint id);
- void queueClearRenderTarget(const QColor &color);
- void queueClearDepthStencil(float depthValue, quint8 stencilValue, QSGD3D12Engine::ClearFlags which);
- void queueSetBlendFactor(const QVector4D &factor);
- void queueSetStencilRef(quint32 ref);
-
- void finalizePipeline(const QSGD3D12PipelineState &pipelineState);
-
- void queueDraw(const QSGD3D12Engine::DrawParams &params);
-
- void present();
- void waitGPU();
-
- uint genTexture();
- void createTexture(uint id, const QSize &size, QImage::Format format, QSGD3D12Engine::TextureCreateFlags flags);
- void queueTextureResize(uint id, const QSize &size);
- void queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos);
- void releaseTexture(uint id);
- SIZE_T textureSRV(uint id) const;
- void activateTexture(uint id);
-
- uint genRenderTarget();
- void createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, int samples);
- void releaseRenderTarget(uint id);
- void activateRenderTargetAsTexture(uint id);
-
- // the device is intentionally hidden here. all resources have to go
- // through the engine and, unlike with GL, cannot just be created in random
- // places due to the need for proper tracking, managing and releasing.
-private:
- void setupDefaultRenderTargets();
- void deviceLost() override;
-
- bool createCbvSrvUavHeap(int pframeIndex, int descriptorCount);
- void setDescriptorHeaps(bool force = false);
- void ensureGPUDescriptorHeap(int cbvSrvUavDescriptorCount);
-
- DXGI_SAMPLE_DESC makeSampleDesc(DXGI_FORMAT format, int samples);
- ID3D12Resource *createColorBuffer(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size,
- const QVector4D &clearColor, int samples);
- ID3D12Resource *createDepthStencil(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size, int samples);
-
- QSGD3D12CPUWaitableFence *createCPUWaitableFence() const;
- void waitForGPU(QSGD3D12CPUWaitableFence *f) const;
-
- void transitionResource(ID3D12Resource *resource, ID3D12GraphicsCommandList *commandList,
- D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after) const;
- void resolveMultisampledTarget(ID3D12Resource *msaa, ID3D12Resource *resolve, D3D12_RESOURCE_STATES resolveUsage,
- ID3D12GraphicsCommandList *commandList) const;
- void uavBarrier(ID3D12Resource *resource, ID3D12GraphicsCommandList *commandList) const;
-
- ID3D12Resource *createBuffer(int size);
-
- typedef QVector<QPair<int, int> > DirtyList;
- void addDirtyRange(DirtyList *dirty, int offset, int size, int bufferSize);
-
- struct PersistentFrameData {
- ComPtr<ID3D12DescriptorHeap> gpuCbvSrvUavHeap;
- int gpuCbvSrvUavHeapSize;
- int cbvSrvUavNextFreeDescriptorIndex;
- QSet<uint> pendingTextureUploads;
- QSet<uint> pendingTextureMipMap;
- struct DeleteQueueEntry {
- ComPtr<ID3D12Resource> res;
- ComPtr<ID3D12DescriptorHeap> descHeap;
- SIZE_T cpuDescriptorPtr = 0;
- };
- QVector<DeleteQueueEntry> deleteQueue;
- QVector<DeleteQueueEntry> outOfFrameDeleteQueue;
- QSet<uint> buffersUsedInDrawCallSet;
- QSet<uint> buffersUsedInFrame;
- struct PendingRelease {
- enum Type {
- TypeTexture,
- TypeBuffer
- };
- Type type = TypeTexture;
- uint id = 0;
- PendingRelease(Type type, uint id) : type(type), id(id) { }
- PendingRelease() { }
- bool operator==(const PendingRelease &other) const { return type == other.type && id == other.id; }
- };
- QSet<PendingRelease> pendingReleases;
- QSet<PendingRelease> outOfFramePendingReleases;
- };
- friend uint qHash(const PersistentFrameData::PendingRelease &pr, uint seed);
-
- void deferredDelete(ComPtr<ID3D12Resource> res);
- void deferredDelete(ComPtr<ID3D12DescriptorHeap> dh);
- void deferredDelete(D3D12_CPU_DESCRIPTOR_HANDLE h);
-
- struct Buffer;
- void ensureBuffer(Buffer *buf);
- void updateBuffer(Buffer *buf);
-
- void beginDrawCalls();
- void beginFrameDraw();
- void endDrawCalls(bool lastInFrame = false);
-
- static const int MAX_SWAP_CHAIN_BUFFER_COUNT = 4;
- static const int MAX_FRAME_IN_FLIGHT_COUNT = 4;
-
- bool initialized = false;
- bool inFrame = false;
- WId window = 0;
- QSize windowSize;
- float windowDpr;
- int windowSamples;
- int swapChainBufferCount;
- int frameInFlightCount;
- int waitableSwapChainMaxLatency;
- ID3D12Device *device;
- ComPtr<ID3D12CommandQueue> commandQueue;
- ComPtr<ID3D12CommandQueue> copyCommandQueue;
- ComPtr<IDXGISwapChain3> swapChain;
- HANDLE swapEvent;
- ComPtr<ID3D12Resource> backBufferRT[MAX_SWAP_CHAIN_BUFFER_COUNT];
- ComPtr<ID3D12Resource> defaultRT[MAX_SWAP_CHAIN_BUFFER_COUNT];
- D3D12_CPU_DESCRIPTOR_HANDLE defaultRTV[MAX_SWAP_CHAIN_BUFFER_COUNT];
- ComPtr<ID3D12Resource> defaultDS;
- D3D12_CPU_DESCRIPTOR_HANDLE defaultDSV;
- ComPtr<ID3D12CommandAllocator> frameCommandAllocator[MAX_FRAME_IN_FLIGHT_COUNT];
- ComPtr<ID3D12CommandAllocator> copyCommandAllocator;
- ComPtr<ID3D12GraphicsCommandList> frameCommandList;
- ComPtr<ID3D12GraphicsCommandList> copyCommandList;
- QSGD3D12CPUDescriptorHeapManager cpuDescHeapManager;
- quint64 presentFrameIndex;
- quint64 frameIndex;
- QSGD3D12CPUWaitableFence *presentFence = nullptr;
- QSGD3D12CPUWaitableFence *frameFence[MAX_FRAME_IN_FLIGHT_COUNT];
-
- PersistentFrameData pframeData[MAX_FRAME_IN_FLIGHT_COUNT];
- int currentPFrameIndex;
- ID3D12GraphicsCommandList *commandList = nullptr;
- int activeLayers = 0;
- int currentLayerDepth = 0;
-
- struct PSOCacheEntry {
- ComPtr<ID3D12PipelineState> pso;
- };
- QCache<QSGD3D12PipelineState, PSOCacheEntry> psoCache;
- struct RootSigCacheEntry {
- ComPtr<ID3D12RootSignature> rootSig;
- };
- QCache<QSGD3D12RootSignature, RootSigCacheEntry> rootSigCache;
-
- struct Texture {
- enum Flag {
- EntryInUse = 0x01,
- Alpha = 0x02,
- MipMap = 0x04
- };
- int flags = 0;
- bool entryInUse() const { return flags & EntryInUse; }
- bool alpha() const { return flags & Alpha; }
- bool mipmap() const { return flags & MipMap; }
- ComPtr<ID3D12Resource> texture;
- D3D12_CPU_DESCRIPTOR_HANDLE srv;
- quint64 fenceValue = 0;
- quint64 lastWaitFenceValue = 0;
- struct StagingHeap {
- ComPtr<ID3D12Heap> heap;
- };
- QVector<StagingHeap> stagingHeaps;
- struct StagingBuffer {
- ComPtr<ID3D12Resource> buffer;
- };
- QVector<StagingBuffer> stagingBuffers;
- QVector<D3D12_CPU_DESCRIPTOR_HANDLE> mipUAVs;
- };
-
- QVector<Texture> textures;
- ComPtr<ID3D12Fence> textureUploadFence;
- QAtomicInt nextTextureUploadFenceValue;
-
- struct TransientFrameData {
- QSGGeometry::DrawingMode drawingMode;
- uint currentIndexBuffer;
- struct ActiveTexture {
- enum Type {
- TypeTexture,
- TypeRenderTarget
- };
- Type type = TypeTexture;
- uint id = 0;
- ActiveTexture(Type type, uint id) : type(type), id(id) { }
- ActiveTexture() { }
- };
- QVector<ActiveTexture> activeTextures;
- int drawCount;
- ID3D12PipelineState *lastPso;
- ID3D12RootSignature *lastRootSig;
- bool descHeapSet;
-
- QRect viewport;
- QRect scissor;
- QVector4D blendFactor = QVector4D(1, 1, 1, 1);
- quint32 stencilRef = 1;
- QSGD3D12PipelineState pipelineState;
- };
- TransientFrameData tframeData;
-
- struct MipMapGen {
- bool initialize(QSGD3D12EnginePrivate *enginePriv);
- void releaseResources();
- void queueGenerate(const Texture &t);
-
- QSGD3D12EnginePrivate *engine;
- ComPtr<ID3D12RootSignature> rootSig;
- ComPtr<ID3D12PipelineState> pipelineState;
- };
-
- MipMapGen mipmapper;
-
- struct RenderTarget {
- enum Flag {
- EntryInUse = 0x01,
- NeedsReadBarrier = 0x02,
- Multisample = 0x04
- };
- int flags = 0;
- bool entryInUse() const { return flags & EntryInUse; }
- ComPtr<ID3D12Resource> color;
- ComPtr<ID3D12Resource> colorResolve;
- D3D12_CPU_DESCRIPTOR_HANDLE rtv;
- ComPtr<ID3D12Resource> ds;
- D3D12_CPU_DESCRIPTOR_HANDLE dsv;
- D3D12_CPU_DESCRIPTOR_HANDLE srv;
- };
-
- QVector<RenderTarget> renderTargets;
- uint currentRenderTarget;
-
- struct CPUBufferRef {
- const quint8 *p = nullptr;
- quint32 size = 0;
- DirtyList dirty;
- CPUBufferRef() { dirty.reserve(16); }
- };
-
- struct Buffer {
- enum Flag {
- EntryInUse = 0x01
- };
- int flags = 0;
- bool entryInUse() const { return flags & EntryInUse; }
- struct InFlightData {
- ComPtr<ID3D12Resource> buffer;
- DirtyList dirty;
- quint32 dataSize = 0;
- quint32 resourceSize = 0;
- InFlightData() { dirty.reserve(16); }
- };
- InFlightData d[MAX_FRAME_IN_FLIGHT_COUNT];
- CPUBufferRef cpuDataRef;
- };
-
- QVector<Buffer> buffers;
-};
-
-inline uint qHash(const QSGD3D12EnginePrivate::PersistentFrameData::PendingRelease &pr, uint seed = 0)
-{
- Q_UNUSED(seed);
- return pr.id + pr.type;
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphcache.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphcache.cpp
deleted file mode 100644
index 373e16d7c4..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphcache.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12glyphcache_p.h"
-#include "qsgd3d12engine_p.h"
-
-QT_BEGIN_NAMESPACE
-
-// NOTE: Avoid categorized logging. It is slow.
-
-#define DECLARE_DEBUG_VAR(variable) \
- static bool debug_ ## variable() \
- { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
-
-DECLARE_DEBUG_VAR(render)
-
-QSGD3D12GlyphCache::QSGD3D12GlyphCache(QSGD3D12Engine *engine, QFontEngine::GlyphFormat format, const QTransform &matrix)
- : QTextureGlyphCache(format, matrix),
- m_engine(engine)
-{
-}
-
-QSGD3D12GlyphCache::~QSGD3D12GlyphCache()
-{
- if (m_id)
- m_engine->releaseTexture(m_id);
-}
-
-void QSGD3D12GlyphCache::createTextureData(int width, int height)
-{
- width = qMax(128, width);
- height = qMax(32, height);
-
- m_id = m_engine->genTexture();
- Q_ASSERT(m_id);
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("new glyph cache texture %u of size %dx%d, fontengine format %d", m_id, width, height, m_format);
-
- m_size = QSize(width, height);
-
- const QImage::Format imageFormat =
- m_format == QFontEngine::Format_A8 ? QImage::Format_Alpha8 : QImage::Format_ARGB32_Premultiplied;
- m_engine->createTexture(m_id, m_size, imageFormat, QSGD3D12Engine::CreateWithAlpha);
-}
-
-void QSGD3D12GlyphCache::resizeTextureData(int width, int height)
-{
- width = qMax(128, width);
- height = qMax(32, height);
-
- if (m_size.width() >= width && m_size.height() >= height)
- return;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("glyph cache texture %u resize to %dx%d", m_id, width, height);
-
- m_size = QSize(width, height);
-
- m_engine->queueTextureResize(m_id, m_size);
-}
-
-void QSGD3D12GlyphCache::beginFillTexture()
-{
- Q_ASSERT(m_glyphImages.isEmpty() && m_glyphPos.isEmpty());
-}
-
-void QSGD3D12GlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition)
-{
- QImage mask = textureMapForGlyph(glyph, subPixelPosition);
- const int maskWidth = mask.width();
- const int maskHeight = mask.height();
-
- if (mask.format() == QImage::Format_Mono) {
- mask = mask.convertToFormat(QImage::Format_Indexed8);
- for (int y = 0; y < maskHeight; ++y) {
- uchar *src = mask.scanLine(y);
- for (int x = 0; x < maskWidth; ++x)
- src[x] = -src[x]; // convert 0 and 1 into 0 and 255
- }
- } else if (mask.depth() == 32) {
- if (mask.format() == QImage::Format_RGB32) {
- // We need to make the alpha component equal to the average of the RGB values.
- // This is needed when drawing sub-pixel antialiased text on translucent targets.
- for (int y = 0; y < maskHeight; ++y) {
- QRgb *src = reinterpret_cast<QRgb *>(mask.scanLine(y));
- for (int x = 0; x < maskWidth; ++x) {
- const int r = qRed(src[x]);
- const int g = qGreen(src[x]);
- const int b = qBlue(src[x]);
- int avg;
- if (mask.format() == QImage::Format_RGB32)
- avg = (r + g + b + 1) / 3; // "+1" for rounding.
- else // Format_ARGB32_Premultiplied
- avg = qAlpha(src[x]);
- src[x] = qRgba(r, g, b, avg);
- }
- }
- }
- }
-
- m_glyphImages.append(mask);
- m_glyphPos.append(QPoint(c.x, c.y));
-}
-
-void QSGD3D12GlyphCache::endFillTexture()
-{
- if (m_glyphImages.isEmpty())
- return;
-
- Q_ASSERT(m_id);
-
- m_engine->queueTextureUpload(m_id, m_glyphImages, m_glyphPos);
-
- // Nothing else left to do, it is up to the text material to call
- // activateTexture() which will then add the texture dependency to the frame.
-
- m_glyphImages.clear();
- m_glyphPos.clear();
-}
-
-int QSGD3D12GlyphCache::glyphPadding() const
-{
- return 1;
-}
-
-int QSGD3D12GlyphCache::maxTextureWidth() const
-{
- return 16384;
-}
-
-int QSGD3D12GlyphCache::maxTextureHeight() const
-{
- return 16384;
-}
-
-void QSGD3D12GlyphCache::activateTexture()
-{
- if (m_id)
- m_engine->activateTexture(m_id);
-}
-
-QSize QSGD3D12GlyphCache::currentSize() const
-{
- return m_size;
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphcache_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphcache_p.h
deleted file mode 100644
index a7430580a8..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphcache_p.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12GLYPHCACHE_P_H
-#define QSGD3D12GLYPHCACHE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/private/qtextureglyphcache_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12Engine;
-
-class QSGD3D12GlyphCache : public QTextureGlyphCache
-{
-public:
- QSGD3D12GlyphCache(QSGD3D12Engine *engine, QFontEngine::GlyphFormat format, const QTransform &matrix);
- ~QSGD3D12GlyphCache();
-
- void createTextureData(int width, int height) override;
- void resizeTextureData(int width, int height) override;
- void beginFillTexture() override;
- void fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition) override;
- void endFillTexture() override;
- int glyphPadding() const override;
- int maxTextureWidth() const override;
- int maxTextureHeight() const override;
-
- void activateTexture();
- QSize currentSize() const;
-
-private:
- QSGD3D12Engine *m_engine;
- uint m_id = 0;
- QVector<QImage> m_glyphImages;
- QVector<QPoint> m_glyphPos;
- QSize m_size;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12GLYPHCACHE_P_H
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphnode.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphnode.cpp
deleted file mode 100644
index e559739018..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphnode.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12glyphnode_p.h"
-#include "qsgd3d12builtinmaterials_p.h"
-
-QT_BEGIN_NAMESPACE
-
-void QSGD3D12GlyphNode::setMaterialColor(const QColor &color)
-{
- static_cast<QSGD3D12TextMaterial *>(m_material)->setColor(color);
-}
-
-void QSGD3D12GlyphNode::update()
-{
- QRawFont font = m_glyphs.rawFont();
- QMargins margins(0, 0, 0, 0);
-
- if (m_style == QQuickText::Normal) {
- // QSGBasicGlyphNode dtor will delete
- m_material = new QSGD3D12TextMaterial(QSGD3D12TextMaterial::Normal, m_rc, font);
- } else if (m_style == QQuickText::Outline) {
- QSGD3D12TextMaterial *material = new QSGD3D12TextMaterial(QSGD3D12TextMaterial::Outlined,
- m_rc, font, QFontEngine::Format_A8);
- material->setStyleColor(m_styleColor);
- m_material = material;
- margins = QMargins(1, 1, 1, 1);
- } else {
- QSGD3D12TextMaterial *material = new QSGD3D12TextMaterial(QSGD3D12TextMaterial::Styled,
- m_rc, font, QFontEngine::Format_A8);
- if (m_style == QQuickText::Sunken) {
- material->setStyleShift(QVector2D(0, -1));
- margins.setTop(1);
- } else if (m_style == QQuickText::Raised) {
- material->setStyleShift(QVector2D(0, 1));
- margins.setBottom(1);
- }
- material->setStyleColor(m_styleColor);
- m_material = material;
- }
-
- QSGD3D12TextMaterial *textMaterial = static_cast<QSGD3D12TextMaterial *>(m_material);
- textMaterial->setColor(m_color);
-
- QRectF boundingRect;
- textMaterial->populate(m_position, m_glyphs.glyphIndexes(), m_glyphs.positions(), geometry(),
- &boundingRect, &m_baseLine, margins);
- setBoundingRect(boundingRect);
-
- setMaterial(m_material);
- markDirty(DirtyGeometry);
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphnode_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphnode_p.h
deleted file mode 100644
index d04a8e8777..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphnode_p.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12GLYPHNODE_P_H
-#define QSGD3D12GLYPHNODE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qsgbasicglyphnode_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12RenderContext;
-
-class QSGD3D12GlyphNode : public QSGBasicGlyphNode
-{
-public:
- QSGD3D12GlyphNode(QSGD3D12RenderContext *rc) : m_rc(rc) { }
-
- void setMaterialColor(const QColor &color) override;
- void update() override;
-
-private:
- QSGD3D12RenderContext *m_rc;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12GLYPHNODE_P_H
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12imagenode.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12imagenode.cpp
deleted file mode 100644
index 9bb360bc5e..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12imagenode.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12imagenode_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QSGD3D12ImageNode::QSGD3D12ImageNode()
-{
- setMaterial(&m_material);
-}
-
-void QSGD3D12ImageNode::setFiltering(QSGTexture::Filtering filtering)
-{
- if (m_material.filtering() == filtering)
- return;
-
- m_material.setFiltering(filtering);
- m_smoothMaterial.setFiltering(filtering);
- markDirty(DirtyMaterial);
-}
-
-void QSGD3D12ImageNode::setMipmapFiltering(QSGTexture::Filtering filtering)
-{
- if (m_material.mipmapFiltering() == filtering)
- return;
-
- m_material.setMipmapFiltering(filtering);
- m_smoothMaterial.setMipmapFiltering(filtering);
- markDirty(DirtyMaterial);
-}
-
-void QSGD3D12ImageNode::setVerticalWrapMode(QSGTexture::WrapMode wrapMode)
-{
- if (m_material.verticalWrapMode() == wrapMode)
- return;
-
- m_material.setVerticalWrapMode(wrapMode);
- m_smoothMaterial.setVerticalWrapMode(wrapMode);
- markDirty(DirtyMaterial);
-}
-
-void QSGD3D12ImageNode::setHorizontalWrapMode(QSGTexture::WrapMode wrapMode)
-{
- if (m_material.horizontalWrapMode() == wrapMode)
- return;
-
- m_material.setHorizontalWrapMode(wrapMode);
- m_smoothMaterial.setHorizontalWrapMode(wrapMode);
- markDirty(DirtyMaterial);
-}
-
-void QSGD3D12ImageNode::updateMaterialAntialiasing()
-{
- if (m_antialiasing)
- setMaterial(&m_smoothMaterial);
- else
- setMaterial(&m_material);
-}
-
-void QSGD3D12ImageNode::setMaterialTexture(QSGTexture *texture)
-{
- m_material.setTexture(texture);
- m_smoothMaterial.setTexture(texture);
-}
-
-QSGTexture *QSGD3D12ImageNode::materialTexture() const
-{
- return m_material.texture();
-}
-
-bool QSGD3D12ImageNode::updateMaterialBlending()
-{
- const bool alpha = m_material.flags() & QSGMaterial::Blending;
- if (materialTexture() && alpha != materialTexture()->hasAlphaChannel()) {
- m_material.setFlag(QSGMaterial::Blending, !alpha);
- return true;
- }
- return false;
-}
-
-bool QSGD3D12ImageNode::supportsWrap(const QSize &) const
-{
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12imagenode_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12imagenode_p.h
deleted file mode 100644
index ef4b38884a..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12imagenode_p.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12IMAGENODE_P_H
-#define QSGD3D12IMAGENODE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qsgbasicimagenode_p.h>
-#include "qsgd3d12builtinmaterials_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12ImageNode : public QSGBasicImageNode
-{
-public:
- QSGD3D12ImageNode();
-
- void setMipmapFiltering(QSGTexture::Filtering filtering) override;
- void setFiltering(QSGTexture::Filtering filtering) override;
- void setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) override;
- void setVerticalWrapMode(QSGTexture::WrapMode wrapMode) override;
-
- void updateMaterialAntialiasing() override;
- void setMaterialTexture(QSGTexture *texture) override;
- QSGTexture *materialTexture() const override;
- bool updateMaterialBlending() override;
- bool supportsWrap(const QSize &size) const override;
-
-private:
- QSGD3D12TextureMaterial m_material;
- QSGD3D12SmoothTextureMaterial m_smoothMaterial;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12IMAGENODE_P_H
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer.cpp
deleted file mode 100644
index 6623c51f5c..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12layer_p.h"
-#include "qsgd3d12rendercontext_p.h"
-#include "qsgd3d12engine_p.h"
-#include "qsgd3d12renderer_p.h"
-
-QT_BEGIN_NAMESPACE
-
-// NOTE: Avoid categorized logging. It is slow.
-
-#define DECLARE_DEBUG_VAR(variable) \
- static bool debug_ ## variable() \
- { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
-
-DECLARE_DEBUG_VAR(render)
-
-QSGD3D12Layer::QSGD3D12Layer(QSGD3D12RenderContext *rc)
- : m_rc(rc)
-{
- if (Q_UNLIKELY(debug_render()))
- qDebug("new layer %p", this);
-}
-
-QSGD3D12Layer::~QSGD3D12Layer()
-{
- if (Q_UNLIKELY(debug_render()))
- qDebug("destroying layer %p", this);
-
- cleanup();
-}
-
-// QSGTexture
-
-int QSGD3D12Layer::textureId() const
-{
- return m_rt; // not a texture id per se but will do
-}
-
-QSize QSGD3D12Layer::textureSize() const
-{
- return m_size;
-}
-
-bool QSGD3D12Layer::hasAlphaChannel() const
-{
- return true;
-}
-
-bool QSGD3D12Layer::hasMipmaps() const
-{
- // mipmapped layers are not supported for now
- return false;
-}
-
-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_mirrorHorizontal ? -1 : 1,
- m_mirrorVertical ? -1 : 1);
-}
-
-void QSGD3D12Layer::bind()
-{
- if (Q_UNLIKELY(debug_render()))
- qDebug("layer %p bind rt=%u", this, m_rt);
-
- // ###
-
- m_rc->engine()->activateRenderTargetAsTexture(m_rt);
-}
-
-// QSGDynamicTexture
-
-bool QSGD3D12Layer::updateTexture()
-{
- if (Q_UNLIKELY(debug_render()))
- qDebug("layer %p updateTexture", this);
-
- const bool doUpdate = (m_live || m_updateContentPending) && m_dirtyTexture;
-
- if (doUpdate)
- updateContent();
-
- if (m_updateContentPending) {
- m_updateContentPending = false;
- emit scheduledUpdateCompleted();
- }
-
- return doUpdate;
-}
-
-// QSGLayer
-
-void QSGD3D12Layer::setItem(QSGNode *item)
-{
- if (m_item == item)
- return;
-
- if (m_live && !item)
- resetRenderTarget();
-
- m_item = item;
- markDirtyTexture();
-}
-
-void QSGD3D12Layer::setRect(const QRectF &rect)
-{
- if (m_rect == rect)
- return;
-
- m_rect = rect;
- markDirtyTexture();
-}
-
-void QSGD3D12Layer::setSize(const QSize &size)
-{
- if (m_size == size)
- return;
-
- if (m_live && size.isNull())
- resetRenderTarget();
-
- m_size = size;
- markDirtyTexture();
-}
-
-void QSGD3D12Layer::scheduleUpdate()
-{
- if (m_updateContentPending)
- return;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("layer %p scheduleUpdate", this);
-
- m_updateContentPending = true;
-
- if (m_dirtyTexture)
- emit updateRequested();
-}
-
-QImage QSGD3D12Layer::toImage() const
-{
- // ### figure out something for item grab support
- return QImage();
-}
-
-void QSGD3D12Layer::setLive(bool live)
-{
- if (m_live == live)
- return;
-
- if (live && (!m_item || m_size.isNull()))
- resetRenderTarget();
-
- m_live = live;
- markDirtyTexture();
-}
-
-void QSGD3D12Layer::setRecursive(bool recursive)
-{
- m_recursive = recursive;
-}
-
-void QSGD3D12Layer::setFormat(uint format)
-{
- Q_UNUSED(format);
-}
-
-void QSGD3D12Layer::setHasMipmaps(bool mipmap)
-{
- // mipmapped layers are not supported for now
- Q_UNUSED(mipmap);
-}
-
-void QSGD3D12Layer::setDevicePixelRatio(qreal ratio)
-{
- m_dpr = ratio;
-}
-
-void QSGD3D12Layer::setMirrorHorizontal(bool mirror)
-{
- m_mirrorHorizontal = mirror;
-}
-
-void QSGD3D12Layer::setMirrorVertical(bool mirror)
-{
- m_mirrorVertical = mirror;
-}
-
-void QSGD3D12Layer::markDirtyTexture()
-{
- if (Q_UNLIKELY(debug_render()))
- qDebug("layer %p markDirtyTexture", this);
-
- m_dirtyTexture = true;
-
- if (m_live || m_updateContentPending)
- emit updateRequested();
-}
-
-void QSGD3D12Layer::invalidated()
-{
- cleanup();
-}
-
-void QSGD3D12Layer::cleanup()
-{
- if (!m_renderer && !m_rt)
- return;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("layer %p cleanup renderer=%p rt=%u", this, m_renderer, m_rt);
-
- delete m_renderer;
- m_renderer = nullptr;
-
- resetRenderTarget();
-}
-
-void QSGD3D12Layer::resetRenderTarget()
-{
- if (!m_rt)
- return;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("layer %p resetRenderTarget rt=%u", this, m_rt);
-
- m_rc->engine()->releaseRenderTarget(m_rt);
- m_rt = 0;
-}
-
-void QSGD3D12Layer::updateContent()
-{
- if (Q_UNLIKELY(debug_render()))
- qDebug("layer %p updateContent", this);
-
- if (!m_item || m_size.isNull()) {
- resetRenderTarget();
- m_dirtyTexture = false;
- return;
- }
-
- QSGNode *root = m_item;
- while (root->firstChild() && root->type() != QSGNode::RootNodeType)
- root = root->firstChild();
-
- if (root->type() != QSGNode::RootNodeType)
- return;
-
- if (!m_renderer) {
- m_renderer = m_rc->createRenderer();
- static_cast<QSGD3D12Renderer *>(m_renderer)->turnToLayerRenderer();
- connect(m_renderer, &QSGRenderer::sceneGraphChanged, this, &QSGD3D12Layer::markDirtyTexture);
- }
-
- m_renderer->setDevicePixelRatio(m_dpr);
- m_renderer->setRootNode(static_cast<QSGRootNode *>(root));
-
- if (!m_rt || m_rtSize != m_size) {
- // ### recursive, multisample
-
- if (m_rt)
- resetRenderTarget();
-
- m_rt = m_rc->engine()->genRenderTarget();
- m_rtSize = m_size;
- m_rc->engine()->createRenderTarget(m_rt, m_rtSize, QVector4D(0, 0, 0, 0), 0);
- }
-
- m_dirtyTexture = false;
-
- m_renderer->setDeviceRect(m_size);
- m_renderer->setViewportRect(m_size);
- QRectF mirrored(m_mirrorHorizontal ? m_rect.right() : m_rect.left(),
- m_mirrorVertical ? m_rect.bottom() : m_rect.top(),
- m_mirrorHorizontal ? -m_rect.width() : m_rect.width(),
- m_mirrorVertical ? -m_rect.height() : m_rect.height());
- m_renderer->setProjectionMatrixToRect(mirrored);
- m_renderer->setClearColor(Qt::transparent);
-
- // ### recursive, multisample
- m_renderer->renderScene(m_rt);
-
- if (m_recursive)
- markDirtyTexture(); // Continuously update if 'live' and 'recursive'.
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer_p.h
deleted file mode 100644
index d167cf4f66..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer_p.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12LAYER_P_H
-#define QSGD3D12LAYER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qsgadaptationlayer_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12RenderContext;
-
-class QSGD3D12Layer : public QSGLayer
-{
- Q_OBJECT
-
-public:
- QSGD3D12Layer(QSGD3D12RenderContext *rc);
- ~QSGD3D12Layer();
-
- int textureId() const override;
- QSize textureSize() const override;
- bool hasAlphaChannel() const override;
- bool hasMipmaps() const override;
- QRectF normalizedTextureSubRect() const override;
- void bind() override;
-
- bool updateTexture() override;
-
- void setItem(QSGNode *item) override;
- void setRect(const QRectF &rect) override;
- void setSize(const QSize &size) override;
- void scheduleUpdate() override;
- QImage toImage() const override;
- void setLive(bool live) override;
- void setRecursive(bool recursive) override;
- void setFormat(uint format) override;
- void setHasMipmaps(bool mipmap) override;
- void setDevicePixelRatio(qreal ratio) override;
- void setMirrorHorizontal(bool mirror) override;
- void setMirrorVertical(bool mirror) override;
-
-public Q_SLOTS:
- void markDirtyTexture() override;
- void invalidated() override;
-
-private:
- void cleanup();
- void resetRenderTarget();
- void updateContent();
-
- QSGD3D12RenderContext *m_rc;
- uint m_rt = 0;
- QSize m_rtSize;
- QSize m_size;
- QRectF m_rect;
- QSGNode *m_item = nullptr;
- QSGRenderer *m_renderer = nullptr;
- float m_dpr = 1;
- bool m_mirrorHorizontal = false;
- bool m_mirrorVertical = true;
- bool m_live = true;
- bool m_recursive = false;
- bool m_dirtyTexture = true;
- bool m_updateContentPending = false;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12LAYER_P_H
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material.cpp
deleted file mode 100644
index 3412a4b63b..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12material_p.h"
-#include <private/qsgrenderer_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QSGD3D12Material::RenderState QSGD3D12Material::makeRenderState(QSGRenderer *renderer, RenderState::DirtyStates dirty)
-{
- RenderState rs;
- rs.m_dirty = dirty;
- rs.m_data = renderer;
- return rs;
-}
-
-float QSGD3D12Material::RenderState::opacity() const
-{
- Q_ASSERT(m_data);
- return static_cast<const QSGRenderer *>(m_data)->currentOpacity();
-}
-
-float QSGD3D12Material::RenderState::determinant() const
-{
- Q_ASSERT(m_data);
- return static_cast<const QSGRenderer *>(m_data)->determinant();
-}
-
-QMatrix4x4 QSGD3D12Material::RenderState::combinedMatrix() const
-{
- Q_ASSERT(m_data);
- return static_cast<const QSGRenderer *>(m_data)->currentCombinedMatrix();
-}
-
-float QSGD3D12Material::RenderState::devicePixelRatio() const
-{
- Q_ASSERT(m_data);
- return static_cast<const QSGRenderer *>(m_data)->devicePixelRatio();
-}
-
-QMatrix4x4 QSGD3D12Material::RenderState::modelViewMatrix() const
-{
- Q_ASSERT(m_data);
- return static_cast<const QSGRenderer *>(m_data)->currentModelViewMatrix();
-}
-
-QMatrix4x4 QSGD3D12Material::RenderState::projectionMatrix() const
-{
- Q_ASSERT(m_data);
- return static_cast<const QSGRenderer *>(m_data)->currentProjectionMatrix();
-}
-
-QRect QSGD3D12Material::RenderState::viewportRect() const
-{
- Q_ASSERT(m_data);
- return static_cast<const QSGRenderer *>(m_data)->viewportRect();
-}
-
-QRect QSGD3D12Material::RenderState::deviceRect() const
-{
- Q_ASSERT(m_data);
- return static_cast<const QSGRenderer *>(m_data)->deviceRect();
-}
-
-QSGMaterialShader *QSGD3D12Material::createShader() const
-{
- return nullptr;
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material_p.h
deleted file mode 100644
index e9af8e68a0..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material_p.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12MATERIAL_P_H
-#define QSGD3D12MATERIAL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtQuick/qsgmaterial.h>
-#include "qsgd3d12engine_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QSGRenderer;
-
-// The D3D renderer works with QSGD3D12Material as the "base" class since
-// QSGMaterial and its GL program related bits are not suitable. Also, there is
-// no split like with QSGMaterialShader.
-
-class QSGD3D12Material : public QSGMaterial
-{
-public:
- struct RenderState {
- enum DirtyState {
- DirtyMatrix = 0x0001,
- DirtyOpacity = 0x0002,
- DirtyCachedMaterialData = 0x0004,
- DirtyAll = 0xFFFF
- };
- Q_DECLARE_FLAGS(DirtyStates, DirtyState)
-
- DirtyStates dirtyStates() const { return m_dirty; }
-
- bool isMatrixDirty() const { return m_dirty & DirtyMatrix; }
- bool isOpacityDirty() const { return m_dirty & DirtyOpacity; }
- bool isCachedMaterialDataDirty() const { return m_dirty & DirtyCachedMaterialData; }
-
- float opacity() const;
- QMatrix4x4 combinedMatrix() const;
- QMatrix4x4 modelViewMatrix() const;
- QMatrix4x4 projectionMatrix() const;
- QRect viewportRect() const;
- QRect deviceRect() const;
- float determinant() const;
- float devicePixelRatio() const;
-
- DirtyStates m_dirty = 0;
- void *m_data = nullptr;
- };
-
- struct ExtraState {
- QVector4D blendFactor;
- };
-
- enum UpdateResult {
- UpdatedShaders = 0x0001,
- UpdatedConstantBuffer = 0x0002,
- UpdatedBlendFactor = 0x0004
- };
- Q_DECLARE_FLAGS(UpdateResults, UpdateResult)
-
- static RenderState makeRenderState(QSGRenderer *renderer, RenderState::DirtyStates dirty);
-
- virtual int constantBufferSize() const = 0;
- virtual void preparePipeline(QSGD3D12PipelineState *pipelineState) = 0;
- virtual UpdateResults updatePipeline(const RenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *extraState,
- quint8 *constantBuffer) = 0;
-
-private:
- QSGMaterialShader *createShader() const override; // dummy, QSGMaterialShader is too GL dependent
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Material::RenderState::DirtyStates)
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Material::UpdateResults)
-
-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
deleted file mode 100644
index 7548f5cbc0..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12rectanglenode_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QSGD3D12RectangleNode::QSGD3D12RectangleNode()
-{
- setMaterial(&m_material);
-}
-
-void QSGD3D12RectangleNode::updateMaterialAntialiasing()
-{
- if (m_antialiasing)
- setMaterial(&m_smoothMaterial);
- else
- setMaterial(&m_material);
-}
-
-void QSGD3D12RectangleNode::updateMaterialBlending(QSGNode::DirtyState *state)
-{
- // smoothed material is always blended, so no change in material state
- if (material() == &m_material) {
- bool wasBlending = (m_material.flags() & QSGMaterial::Blending);
- bool isBlending = (m_gradient_stops.size() > 0 && !m_gradient_is_opaque)
- || (m_color.alpha() < 255 && m_color.alpha() != 0)
- || (m_pen_width > 0 && m_border_color.alpha() < 255);
- if (wasBlending != isBlending) {
- m_material.setFlag(QSGMaterial::Blending, isBlending);
- *state |= QSGNode::DirtyMaterial;
- }
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode_p.h
deleted file mode 100644
index 95f734bc4c..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode_p.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12RECTANGLENODE_P_H
-#define QSGD3D12RECTANGLENODE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qsgbasicrectanglenode_p.h>
-#include "qsgd3d12builtinmaterials_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12RectangleNode : public QSGBasicRectangleNode
-{
-public:
- QSGD3D12RectangleNode();
-
-private:
- void updateMaterialAntialiasing() override;
- void updateMaterialBlending(QSGNode::DirtyState *state) override;
-
- QSGD3D12VertexColorMaterial m_material;
- QSGD3D12SmoothColorMaterial m_smoothMaterial;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12RECTANGLENODE_P_H
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext.cpp
deleted file mode 100644
index af3e8e36ee..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12rendercontext_p.h"
-#include "qsgd3d12renderer_p.h"
-#include "qsgd3d12texture_p.h"
-
-QT_BEGIN_NAMESPACE
-
-// NOTE: Avoid categorized logging. It is slow.
-
-#define DECLARE_DEBUG_VAR(variable) \
- static bool debug_ ## variable() \
- { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
-
-DECLARE_DEBUG_VAR(render)
-
-QSGD3D12RenderContext::QSGD3D12RenderContext(QSGContext *ctx)
- : QSGRenderContext(ctx)
-{
-}
-
-void QSGD3D12RenderContext::invalidate()
-{
- if (Q_UNLIKELY(debug_render()))
- qDebug("rendercontext invalidate engine %p, %d/%d/%d", m_engine,
- m_texturesToDelete.count(), m_textures.count(), m_fontEnginesToClean.count());
-
- qDeleteAll(m_texturesToDelete);
- m_texturesToDelete.clear();
-
- qDeleteAll(m_textures);
- m_textures.clear();
-
- for (QSet<QFontEngine *>::const_iterator it = m_fontEnginesToClean.constBegin(),
- end = m_fontEnginesToClean.constEnd(); it != end; ++it) {
- (*it)->clearGlyphCache(m_engine);
- if (!(*it)->ref.deref())
- delete *it;
- }
- m_fontEnginesToClean.clear();
-
- m_sg->renderContextInvalidated(this);
- emit invalidated();
-}
-
-QSGTexture *QSGD3D12RenderContext::createTexture(const QImage &image, uint flags) const
-{
- Q_ASSERT(m_engine);
- QSGD3D12Texture *t = new QSGD3D12Texture(m_engine);
- t->setImage(image, flags);
- return t;
-}
-
- QSGRenderer *QSGD3D12RenderContext::createRenderer()
-{
- return new QSGD3D12Renderer(this);
-}
-
-void QSGD3D12RenderContext::renderNextFrame(QSGRenderer *renderer, uint fbo)
-{
- static_cast<QSGD3D12Renderer *>(renderer)->renderScene(fbo);
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext_p.h
deleted file mode 100644
index 1acb7e4205..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext_p.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12RENDERCONTEXT_P_H
-#define QSGD3D12RENDERCONTEXT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qsgcontext_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12Engine;
-
-class QSGD3D12RenderContext : public QSGRenderContext
-{
-public:
- QSGD3D12RenderContext(QSGContext *ctx);
- void invalidate() override;
- void renderNextFrame(QSGRenderer *renderer, uint fbo) override;
- QSGTexture *createTexture(const QImage &image, uint flags) const override;
- QSGRenderer *createRenderer() override;
-
- void setEngine(QSGD3D12Engine *engine) { m_engine = engine; }
- QSGD3D12Engine *engine() { return m_engine; }
-
-private:
- QSGD3D12Engine *m_engine = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12RENDERCONTEXT_P_H
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp
deleted file mode 100644
index 7f8b10f003..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp
+++ /dev/null
@@ -1,710 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12renderer_p.h"
-#include "qsgd3d12rendercontext_p.h"
-#include <private/qsgnodeupdater_p.h>
-
-#include "vs_stencilclip.hlslh"
-#include "ps_stencilclip.hlslh"
-
-//#define I_LIKE_STENCIL
-
-QT_BEGIN_NAMESPACE
-
-#define QSGNODE_TRAVERSE(NODE) for (QSGNode *child = NODE->firstChild(); child; child = child->nextSibling())
-
-// NOTE: Avoid categorized logging. It is slow.
-
-#define DECLARE_DEBUG_VAR(variable) \
- static bool debug_ ## variable() \
- { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
-
-DECLARE_DEBUG_VAR(build)
-DECLARE_DEBUG_VAR(change)
-DECLARE_DEBUG_VAR(render)
-
-class DummyUpdater : public QSGNodeUpdater
-{
-public:
- void updateState(QSGNode *) { };
-};
-
-QSGD3D12Renderer::QSGD3D12Renderer(QSGRenderContext *context)
- : QSGRenderer(context),
- m_renderList(16),
- m_vboData(1024),
- m_iboData(256),
- m_cboData(4096)
-{
- setNodeUpdater(new DummyUpdater);
- m_freshPipelineState.shaders.rootSig.textureViews.reserve(4);
-}
-
-QSGD3D12Renderer::~QSGD3D12Renderer()
-{
- if (m_engine) {
- m_engine->releaseBuffer(m_vertexBuf);
- m_engine->releaseBuffer(m_indexBuf);
- m_engine->releaseBuffer(m_constantBuf);
- }
-}
-
-void QSGD3D12Renderer::renderScene(GLuint fboId)
-{
- m_renderTarget = fboId;
-
- struct DummyBindable : public QSGBindable {
- void bind() const { }
- } bindable;
-
- QSGRenderer::renderScene(bindable); // calls back render()
-}
-
-// Search through the node set and remove nodes that are descendants of other
-// nodes in the same set.
-static QSet<QSGNode *> qsg_removeDescendants(const QSet<QSGNode *> &nodes, QSGRootNode *root)
-{
- QSet<QSGNode *> result = nodes;
- for (QSGNode *node : nodes) {
- QSGNode *n = node;
- while (n != root) {
- if (n != node && result.contains(n)) {
- result.remove(node);
- break;
- }
- n = n->parent();
- }
- }
- return result;
-}
-
-void QSGD3D12Renderer::updateMatrices(QSGNode *node, QSGTransformNode *xform)
-{
- if (node->isSubtreeBlocked())
- return;
-
- if (node->type() == QSGNode::TransformNodeType) {
- QSGTransformNode *tn = static_cast<QSGTransformNode *>(node);
- if (xform)
- tn->setCombinedMatrix(xform->combinedMatrix() * tn->matrix());
- else
- tn->setCombinedMatrix(tn->matrix());
- QSGNODE_TRAVERSE(node)
- updateMatrices(child, tn);
- } else {
- if (node->type() == QSGNode::GeometryNodeType || node->type() == QSGNode::ClipNodeType) {
- m_nodeDirtyMap[node] |= QSGD3D12Material::RenderState::DirtyMatrix;
- QSGBasicGeometryNode *gnode = static_cast<QSGBasicGeometryNode *>(node);
- const QMatrix4x4 *newMatrix = xform ? &xform->combinedMatrix() : nullptr;
- // NB the newMatrix ptr is usually the same as before as it just
- // references the transform node's own matrix.
- gnode->setMatrix(newMatrix);
- }
- QSGNODE_TRAVERSE(node)
- updateMatrices(child, xform);
- }
-}
-
-void QSGD3D12Renderer::updateOpacities(QSGNode *node, float inheritedOpacity)
-{
- if (node->isSubtreeBlocked())
- return;
-
- if (node->type() == QSGNode::OpacityNodeType) {
- QSGOpacityNode *on = static_cast<QSGOpacityNode *>(node);
- float combined = inheritedOpacity * on->opacity();
- on->setCombinedOpacity(combined);
- QSGNODE_TRAVERSE(node)
- updateOpacities(child, combined);
- } else {
- if (node->type() == QSGNode::GeometryNodeType) {
- m_nodeDirtyMap[node] |= QSGD3D12Material::RenderState::DirtyOpacity;
- QSGGeometryNode *gn = static_cast<QSGGeometryNode *>(node);
- gn->setInheritedOpacity(inheritedOpacity);
- }
- QSGNODE_TRAVERSE(node)
- updateOpacities(child, inheritedOpacity);
- }
-}
-
-void QSGD3D12Renderer::buildRenderList(QSGNode *node, QSGClipNode *clip)
-{
- if (node->isSubtreeBlocked())
- return;
-
- if (node->type() == QSGNode::GeometryNodeType || node->type() == QSGNode::ClipNodeType) {
- QSGBasicGeometryNode *gn = static_cast<QSGBasicGeometryNode *>(node);
- QSGGeometry *g = gn->geometry();
-
- Element e;
- e.node = gn;
-
- if (g->vertexCount() > 0) {
- e.vboOffset = m_vboData.size();
- const int vertexSize = g->sizeOfVertex() * g->vertexCount();
- m_vboData.resize(m_vboData.size() + vertexSize);
- memcpy(m_vboData.data() + e.vboOffset, g->vertexData(), vertexSize);
- }
-
- if (g->indexCount() > 0) {
- e.iboOffset = m_iboData.size();
- e.iboStride = g->sizeOfIndex();
- const int indexSize = e.iboStride * g->indexCount();
- m_iboData.resize(m_iboData.size() + indexSize);
- memcpy(m_iboData.data() + e.iboOffset, g->indexData(), indexSize);
- }
-
- e.cboOffset = m_cboData.size();
- if (node->type() == QSGNode::GeometryNodeType) {
- QSGD3D12Material *m = static_cast<QSGD3D12Material *>(static_cast<QSGGeometryNode *>(node)->activeMaterial());
- e.cboSize = m->constantBufferSize();
- } else {
- // Stencil-based clipping needs a 4x4 matrix.
- e.cboSize = QSGD3D12Engine::alignedConstantBufferSize(16 * sizeof(float));
- }
- m_cboData.resize(m_cboData.size() + e.cboSize);
-
- m_renderList.add(e);
-
- gn->setClipList(clip);
- if (node->type() == QSGNode::ClipNodeType)
- clip = static_cast<QSGClipNode *>(node);
- }
-
- QSGNODE_TRAVERSE(node)
- buildRenderList(child, clip);
-}
-
-void QSGD3D12Renderer::render()
-{
- QSGD3D12RenderContext *rc = static_cast<QSGD3D12RenderContext *>(context());
- m_engine = rc->engine();
- if (!m_layerRenderer)
- m_engine->beginFrame();
- else
- m_engine->beginLayer();
-
- m_activeScissorRect = QRect();
-
- if (m_rebuild) {
- m_rebuild = false;
-
- m_dirtyTransformNodes.clear();
- m_dirtyTransformNodes.insert(rootNode());
- m_dirtyOpacityNodes.clear();
- m_dirtyOpacityNodes.insert(rootNode());
-
- m_renderList.reset();
- m_vboData.reset();
- m_iboData.reset();
- m_cboData.reset();
-
- buildRenderList(rootNode(), nullptr);
-
- if (!m_vertexBuf)
- m_vertexBuf = m_engine->genBuffer();
- m_engine->resetBuffer(m_vertexBuf, m_vboData.data(), m_vboData.size());
-
- if (!m_constantBuf)
- m_constantBuf = m_engine->genBuffer();
- m_engine->resetBuffer(m_constantBuf, m_cboData.data(), m_cboData.size());
-
- if (m_iboData.size()) {
- if (!m_indexBuf)
- m_indexBuf = m_engine->genBuffer();
- m_engine->resetBuffer(m_indexBuf, m_iboData.data(), m_iboData.size());
- } else if (m_indexBuf) {
- m_engine->releaseBuffer(m_indexBuf);
- m_indexBuf = 0;
- }
-
- if (Q_UNLIKELY(debug_build())) {
- qDebug("renderList: %d elements in total", m_renderList.size());
- for (int i = 0; i < m_renderList.size(); ++i) {
- const Element &e = m_renderList.at(i);
- qDebug() << " - " << e.vboOffset << e.iboOffset << e.cboOffset << e.cboSize << e.node;
- }
- }
- }
-
- const QRect devRect = deviceRect();
- m_projectionChangedDueToDeviceSize = devRect != m_lastDeviceRect;
- if (m_projectionChangedDueToDeviceSize)
- m_lastDeviceRect = devRect;
-
- if (m_dirtyTransformNodes.size()) {
- const QSet<QSGNode *> subTreeRoots = qsg_removeDescendants(m_dirtyTransformNodes, rootNode());
- for (QSGNode *node : subTreeRoots) {
- // First find the parent transform so we have the accumulated
- // matrix up until this point.
- QSGTransformNode *xform = 0;
- QSGNode *n = node;
- if (n->type() == QSGNode::TransformNodeType)
- n = node->parent();
- while (n != rootNode() && n->type() != QSGNode::TransformNodeType)
- n = n->parent();
- if (n != rootNode())
- xform = static_cast<QSGTransformNode *>(n);
-
- // Then update in the subtree
- updateMatrices(node, xform);
- }
- }
-
- if (m_dirtyOpacityNodes.size()) {
- const QSet<QSGNode *> subTreeRoots = qsg_removeDescendants(m_dirtyOpacityNodes, rootNode());
- for (QSGNode *node : subTreeRoots) {
- float opacity = 1.0f;
- QSGNode *n = node;
- if (n->type() == QSGNode::OpacityNodeType)
- n = node->parent();
- while (n != rootNode() && n->type() != QSGNode::OpacityNodeType)
- n = n->parent();
- if (n != rootNode())
- opacity = static_cast<QSGOpacityNode *>(n)->combinedOpacity();
-
- updateOpacities(node, opacity);
- }
- m_dirtyOpaqueElements = true;
- }
-
- if (m_dirtyOpaqueElements) {
- m_dirtyOpaqueElements = false;
- m_opaqueElements.clear();
- m_opaqueElements.resize(m_renderList.size());
- for (int i = 0; i < m_renderList.size(); ++i) {
- const Element &e = m_renderList.at(i);
- if (e.node->type() == QSGNode::GeometryNodeType) {
- const QSGGeometryNode *gn = static_cast<QSGGeometryNode *>(e.node);
- if (gn->inheritedOpacity() > 0.999f && ((gn->activeMaterial()->flags() & QSGMaterial::Blending) == 0))
- m_opaqueElements.setBit(i);
- }
- }
- }
-
- // Build pipeline state and draw calls.
- renderElements();
-
- m_dirtyTransformNodes.clear();
- m_dirtyOpacityNodes.clear();
- m_dirtyOpaqueElements = false;
- m_nodeDirtyMap.clear();
-
- // Finalize buffers and execute commands.
- if (!m_layerRenderer)
- m_engine->endFrame();
- else
- m_engine->endLayer();
-}
-
-void QSGD3D12Renderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
-{
- // note that with DirtyNodeRemoved the window and all the graphics engine may already be gone
-
- if (Q_UNLIKELY(debug_change())) {
- QDebug debug = qDebug();
- debug << "dirty:";
- if (state & QSGNode::DirtyGeometry)
- debug << "Geometry";
- if (state & QSGNode::DirtyMaterial)
- debug << "Material";
- if (state & QSGNode::DirtyMatrix)
- debug << "Matrix";
- if (state & QSGNode::DirtyNodeAdded)
- debug << "Added";
- if (state & QSGNode::DirtyNodeRemoved)
- debug << "Removed";
- if (state & QSGNode::DirtyOpacity)
- debug << "Opacity";
- if (state & QSGNode::DirtySubtreeBlocked)
- debug << "SubtreeBlocked";
- if (state & QSGNode::DirtyForceUpdate)
- debug << "ForceUpdate";
-
- // when removed, some parts of the node could already have been destroyed
- // so don't debug it out.
- if (state & QSGNode::DirtyNodeRemoved)
- debug << (void *) node << node->type();
- else
- debug << node;
- }
-
- if (state & (QSGNode::DirtyNodeAdded
- | QSGNode::DirtyNodeRemoved
- | QSGNode::DirtySubtreeBlocked
- | QSGNode::DirtyGeometry
- | QSGNode::DirtyForceUpdate))
- m_rebuild = true;
-
- if (state & QSGNode::DirtyMatrix)
- m_dirtyTransformNodes << node;
-
- if (state & QSGNode::DirtyOpacity)
- m_dirtyOpacityNodes << node;
-
- if (state & QSGNode::DirtyMaterial)
- m_dirtyOpaqueElements = true;
-
- QSGRenderer::nodeChanged(node, state);
-}
-
-void QSGD3D12Renderer::renderElements()
-{
- m_engine->queueSetRenderTarget(m_renderTarget);
- m_engine->queueViewport(viewportRect());
- m_engine->queueClearRenderTarget(clearColor());
- m_engine->queueClearDepthStencil(1, 0, QSGD3D12Engine::ClearDepth | QSGD3D12Engine::ClearStencil);
-
- m_pipelineState.blend = m_freshPipelineState.blend = QSGD3D12PipelineState::BlendNone;
- m_pipelineState.depthEnable = m_freshPipelineState.depthEnable = true;
- m_pipelineState.depthWrite = m_freshPipelineState.depthWrite = true;
-
- // First do opaque...
- // The algorithm is quite simple. We traverse the list back-to-front, and
- // for every item we start a second traversal and draw all elements which
- // have identical material. Then we clear the bit for this in the rendered
- // list so we don't draw it again when we come to that index.
- QBitArray rendered = m_opaqueElements;
- for (int i = m_renderList.size() - 1; i >= 0; --i) {
- if (rendered.testBit(i)) {
- renderElement(i);
- for (int j = i - 1; j >= 0; --j) {
- if (rendered.testBit(j)) {
- const QSGGeometryNode *gni = static_cast<QSGGeometryNode *>(m_renderList.at(i).node);
- const QSGGeometryNode *gnj = static_cast<QSGGeometryNode *>(m_renderList.at(j).node);
- if (gni->clipList() == gnj->clipList()
- && gni->inheritedOpacity() == gnj->inheritedOpacity()
- && gni->geometry()->drawingMode() == gnj->geometry()->drawingMode()
- && gni->geometry()->attributes() == gnj->geometry()->attributes()) {
- const QSGMaterial *ami = gni->activeMaterial();
- const QSGMaterial *amj = gnj->activeMaterial();
- if (ami->type() == amj->type()
- && ami->flags() == amj->flags()
- && ami->compare(amj) == 0) {
- renderElement(j);
- rendered.clearBit(j);
- }
- }
- }
- }
- }
- }
-
- m_pipelineState.blend = m_freshPipelineState.blend = QSGD3D12PipelineState::BlendPremul;
- m_pipelineState.depthWrite = m_freshPipelineState.depthWrite = false;
-
- // ...then the alpha ones
- for (int i = 0; i < m_renderList.size(); ++i) {
- if (m_renderList.at(i).node->type() == QSGNode::GeometryNodeType && !m_opaqueElements.testBit(i))
- renderElement(i);
- }
-}
-
-void QSGD3D12Renderer::renderElement(int elementIndex)
-{
- Element &e = m_renderList.at(elementIndex);
- Q_ASSERT(e.node->type() == QSGNode::GeometryNodeType);
-
- if (e.vboOffset < 0)
- return;
-
- Q_ASSERT(e.cboOffset >= 0);
-
- const QSGGeometryNode *gn = static_cast<QSGGeometryNode *>(e.node);
- if (Q_UNLIKELY(debug_render()))
- qDebug() << "renderElement:" << elementIndex << gn << e.vboOffset << e.iboOffset << gn->inheritedOpacity() << gn->clipList();
-
- if (gn->inheritedOpacity() < 0.001f) // pretty much invisible, don't draw it
- return;
-
- // Update the QSGRenderer members which the materials will access.
- m_current_projection_matrix = projectionMatrix();
- const float scale = 1.0 / m_renderList.size();
- m_current_projection_matrix(2, 2) = scale;
- m_current_projection_matrix(2, 3) = 1.0f - (elementIndex + 1) * scale;
- m_current_model_view_matrix = gn->matrix() ? *gn->matrix() : QMatrix4x4();
- m_current_determinant = m_current_model_view_matrix.determinant();
- m_current_opacity = gn->inheritedOpacity();
-
- const QSGGeometry *g = gn->geometry();
- QSGD3D12Material *m = static_cast<QSGD3D12Material *>(gn->activeMaterial());
-
- if (m->type() != m_lastMaterialType) {
- m_pipelineState = m_freshPipelineState;
- m->preparePipeline(&m_pipelineState);
- }
-
- QSGD3D12Material::RenderState::DirtyStates dirtyState = m_nodeDirtyMap.value(e.node);
-
- // After a rebuild everything in the cbuffer has to be updated.
- if (!e.cboPrepared) {
- e.cboPrepared = true;
- dirtyState = QSGD3D12Material::RenderState::DirtyAll;
- }
-
- // DirtyMatrix does not include projection matrix changes that can arise
- // due to changing the render target's size (and there is no rebuild).
- // Accommodate for this.
- if (m_projectionChangedDueToDeviceSize)
- dirtyState |= QSGD3D12Material::RenderState::DirtyMatrix;
-
- quint8 *cboPtr = nullptr;
- if (e.cboSize > 0)
- cboPtr = m_cboData.data() + e.cboOffset;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug() << "dirty state for" << e.node << "is" << dirtyState;
-
- QSGD3D12Material::ExtraState extraState;
- QSGD3D12Material::UpdateResults updRes = m->updatePipeline(QSGD3D12Material::makeRenderState(this, dirtyState),
- &m_pipelineState,
- &extraState,
- cboPtr);
-
- if (updRes.testFlag(QSGD3D12Material::UpdatedConstantBuffer))
- m_engine->markBufferDirty(m_constantBuf, e.cboOffset, e.cboSize);
-
- if (updRes.testFlag(QSGD3D12Material::UpdatedBlendFactor))
- m_engine->queueSetBlendFactor(extraState.blendFactor);
-
- setInputLayout(g, &m_pipelineState);
-
- m_lastMaterialType = m->type();
-
- setupClipping(gn, elementIndex);
-
- // ### 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->finalizePipeline(m_pipelineState);
-
- queueDrawCall(g, e);
-}
-
-void QSGD3D12Renderer::setInputLayout(const QSGGeometry *g, QSGD3D12PipelineState *pipelineState)
-{
- pipelineState->inputElements.resize(g->attributeCount());
- const QSGGeometry::Attribute *attrs = g->attributes();
- quint32 offset = 0;
- for (int i = 0; i < g->attributeCount(); ++i) {
- QSGD3D12InputElement &ie(pipelineState->inputElements[i]);
- static const char *semanticNames[] = { "UNKNOWN", "POSITION", "COLOR", "TEXCOORD", "TEXCOORD", "TEXCOORD" };
- static const int semanticIndices[] = { 0, 0, 0, 0, 1, 2 };
- Q_ASSERT(attrs[i].semantic >= 1 && attrs[i].semantic < _countof(semanticNames));
- const int tupleSize = attrs[i].tupleSize;
- ie.semanticName = semanticNames[attrs[i].semantic];
- ie.semanticIndex = semanticIndices[attrs[i].semantic];
- ie.offset = offset;
- int bytesPerTuple = 0;
- ie.format = QSGD3D12Engine::toDXGIFormat(QSGGeometry::Type(attrs[i].type), tupleSize, &bytesPerTuple);
- if (ie.format == FmtUnknown)
- qFatal("QSGD3D12Renderer: unsupported tuple size for attribute type 0x%x", attrs[i].type);
- offset += bytesPerTuple;
- // There is one buffer with interleaved data so the slot is always 0.
- ie.slot = 0;
- }
-}
-
-void QSGD3D12Renderer::queueDrawCall(const QSGGeometry *g, const QSGD3D12Renderer::Element &e)
-{
- QSGD3D12Engine::DrawParams dp;
- dp.mode = QSGGeometry::DrawingMode(g->drawingMode());
- dp.vertexBuf = m_vertexBuf;
- dp.constantBuf = m_constantBuf;
- dp.vboOffset = e.vboOffset;
- dp.vboSize = g->vertexCount() * g->sizeOfVertex();
- dp.vboStride = g->sizeOfVertex();
- dp.cboOffset = e.cboOffset;
-
- if (e.iboOffset >= 0) {
- const QSGGeometry::Type indexType = QSGGeometry::Type(g->indexType());
- const QSGD3D12Format indexFormat = QSGD3D12Engine::toDXGIFormat(indexType);
- if (indexFormat == FmtUnknown)
- qFatal("QSGD3D12Renderer: unsupported index type 0x%x", indexType);
- dp.count = g->indexCount();
- dp.indexBuf = m_indexBuf;
- dp.startIndexIndex = e.iboOffset / e.iboStride;
- dp.indexFormat = indexFormat;
- } else {
- dp.count = g->vertexCount();
- }
-
- m_engine->queueDraw(dp);
-}
-
-void QSGD3D12Renderer::setupClipping(const QSGGeometryNode *gn, int elementIndex)
-{
- const QSGClipNode *clip = gn->clipList();
-
- const QRect devRect = deviceRect();
- QRect scissorRect;
- enum ClipType {
- ClipScissor = 0x1,
- ClipStencil = 0x2
- };
- int clipTypes = 0;
- quint32 stencilValue = 0;
-
- while (clip) {
- QMatrix4x4 m = projectionMatrix();
- if (clip->matrix())
- m *= *clip->matrix();
-
-#ifndef I_LIKE_STENCIL
- const bool isRectangleWithNoPerspective = clip->isRectangular()
- && qFuzzyIsNull(m(3, 0)) && qFuzzyIsNull(m(3, 1));
- const bool noRotate = qFuzzyIsNull(m(0, 1)) && qFuzzyIsNull(m(1, 0));
- const bool isRotate90 = qFuzzyIsNull(m(0, 0)) && qFuzzyIsNull(m(1, 1));
-
- if (isRectangleWithNoPerspective && (noRotate || isRotate90)) {
- QRectF bbox = clip->clipRect();
- float invW = 1.0f / m(3, 3);
- float fx1, fy1, fx2, fy2;
- if (noRotate) {
- fx1 = (bbox.left() * m(0, 0) + m(0, 3)) * invW;
- fy1 = (bbox.bottom() * m(1, 1) + m(1, 3)) * invW;
- fx2 = (bbox.right() * m(0, 0) + m(0, 3)) * invW;
- fy2 = (bbox.top() * m(1, 1) + m(1, 3)) * invW;
- } else {
- Q_ASSERT(isRotate90);
- fx1 = (bbox.bottom() * m(0, 1) + m(0, 3)) * invW;
- fy1 = (bbox.left() * m(1, 0) + m(1, 3)) * invW;
- fx2 = (bbox.top() * m(0, 1) + m(0, 3)) * invW;
- fy2 = (bbox.right() * m(1, 0) + m(1, 3)) * invW;
- }
-
- if (fx1 > fx2)
- qSwap(fx1, fx2);
- if (fy1 > fy2)
- qSwap(fy1, fy2);
-
- int ix1 = qRound((fx1 + 1) * devRect.width() * 0.5f);
- int iy1 = qRound((fy1 + 1) * devRect.height() * 0.5f);
- int ix2 = qRound((fx2 + 1) * devRect.width() * 0.5f);
- int iy2 = qRound((fy2 + 1) * devRect.height() * 0.5f);
-
- if (!(clipTypes & ClipScissor)) {
- scissorRect = QRect(ix1, devRect.height() - iy2, ix2 - ix1, iy2 - iy1);
- clipTypes |= ClipScissor;
- } else {
- scissorRect &= QRect(ix1, devRect.height() - iy2, ix2 - ix1, iy2 - iy1);
- }
- } else
-#endif
- {
- clipTypes |= ClipStencil;
- renderStencilClip(clip, elementIndex, m, stencilValue);
- }
-
- clip = clip->clipList();
- }
-
- setScissor((clipTypes & ClipScissor) ? scissorRect : viewportRect());
-
- if (clipTypes & ClipStencil) {
- m_pipelineState.stencilEnable = true;
- m_engine->queueSetStencilRef(stencilValue);
- } else {
- m_pipelineState.stencilEnable = false;
- }
-}
-
-void QSGD3D12Renderer::setScissor(const QRect &r)
-{
- if (m_activeScissorRect == r)
- return;
-
- m_activeScissorRect = r;
- m_engine->queueScissor(r);
-}
-
-void QSGD3D12Renderer::renderStencilClip(const QSGClipNode *clip, int elementIndex,
- const QMatrix4x4 &m, quint32 &stencilValue)
-{
- QSGD3D12PipelineState sps;
- sps.shaders.vs = g_VS_StencilClip;
- sps.shaders.vsSize = sizeof(g_VS_StencilClip);
- sps.shaders.ps = g_PS_StencilClip;
- sps.shaders.psSize = sizeof(g_PS_StencilClip);
-
- m_engine->queueClearDepthStencil(1, 0, QSGD3D12Engine::ClearStencil);
- sps.stencilEnable = true;
- sps.colorWrite = false;
- sps.depthWrite = false;
-
- sps.stencilFunc = QSGD3D12PipelineState::CompareEqual;
- sps.stencilFailOp = QSGD3D12PipelineState::StencilKeep;
- sps.stencilDepthFailOp = QSGD3D12PipelineState::StencilKeep;
- sps.stencilPassOp = QSGD3D12PipelineState::StencilIncr;
-
- m_engine->queueSetStencilRef(stencilValue);
-
- int clipIndex = elementIndex;
- while (m_renderList.at(--clipIndex).node != clip) {
- Q_ASSERT(clipIndex >= 0);
- }
- const Element &ce = m_renderList.at(clipIndex);
- Q_ASSERT(ce.node == clip);
-
- const QSGGeometry *g = clip->geometry();
- Q_ASSERT(g->attributeCount() == 1);
- Q_ASSERT(g->attributes()[0].tupleSize == 2);
- Q_ASSERT(g->attributes()[0].type == QSGGeometry::TypeFloat);
-
- setInputLayout(g, &sps);
- m_engine->finalizePipeline(sps);
-
- Q_ASSERT(ce.cboSize > 0);
- quint8 *p = m_cboData.data() + ce.cboOffset;
- memcpy(p, m.constData(), 16 * sizeof(float));
- m_engine->markBufferDirty(m_constantBuf, ce.cboOffset, ce.cboSize);
-
- queueDrawCall(g, ce);
-
- ++stencilValue;
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer_p.h
deleted file mode 100644
index adb2252f80..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer_p.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12RENDERER_P_H
-#define QSGD3D12RENDERER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qsgrenderer_p.h>
-#include <QtGui/private/qdatabuffer_p.h>
-#include "qsgd3d12engine_p.h"
-#include "qsgd3d12material_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12Renderer : public QSGRenderer
-{
-public:
- QSGD3D12Renderer(QSGRenderContext *context);
- ~QSGD3D12Renderer();
-
- void renderScene(GLuint fboId) override;
- void render() override;
- void nodeChanged(QSGNode *node, QSGNode::DirtyState state) override;
-
- void turnToLayerRenderer() { m_layerRenderer = true; }
-
-private:
- void updateMatrices(QSGNode *node, QSGTransformNode *xform);
- void updateOpacities(QSGNode *node, float inheritedOpacity);
- void buildRenderList(QSGNode *node, QSGClipNode *clip);
- void renderElements();
- void renderElement(int elementIndex);
- void setInputLayout(const QSGGeometry *g, QSGD3D12PipelineState *pipelineState);
- void setupClipping(const QSGGeometryNode *gn, int elementIndex);
- void setScissor(const QRect &r);
- void renderStencilClip(const QSGClipNode *clip, int elementIndex, const QMatrix4x4 &m, quint32 &stencilValue);
-
- struct Element {
- QSGBasicGeometryNode *node = nullptr;
- qint32 vboOffset = -1;
- qint32 iboOffset = -1;
- quint32 iboStride = 0;
- qint32 cboOffset = -1;
- quint32 cboSize = 0;
- bool cboPrepared = false;
- };
-
- void queueDrawCall(const QSGGeometry *g, const Element &e);
-
- bool m_layerRenderer = false;
- QSet<QSGNode *> m_dirtyTransformNodes;
- QSet<QSGNode *> m_dirtyOpacityNodes;
- QBitArray m_opaqueElements;
- bool m_rebuild = true;
- bool m_dirtyOpaqueElements = true;
- QDataBuffer<quint8> m_vboData;
- QDataBuffer<quint8> m_iboData;
- QDataBuffer<quint8> m_cboData;
- QDataBuffer<Element> m_renderList;
- uint m_vertexBuf = 0;
- uint m_indexBuf = 0;
- uint m_constantBuf = 0;
- QSGD3D12Engine *m_engine = nullptr;
-
- QSGMaterialType *m_lastMaterialType = nullptr;
- QSGD3D12PipelineState m_pipelineState;
- QSGD3D12PipelineState m_freshPipelineState;
-
- typedef QHash<QSGNode *, QSGD3D12Material::RenderState::DirtyStates> NodeDirtyMap;
- NodeDirtyMap m_nodeDirtyMap;
-
- QRect m_activeScissorRect;
- QRect m_lastDeviceRect;
- bool m_projectionChangedDueToDeviceSize;
-
- uint m_renderTarget = 0;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12RENDERER_P_H
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop.cpp
deleted file mode 100644
index 121d010bbb..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop.cpp
+++ /dev/null
@@ -1,1101 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12renderloop_p.h"
-#include "qsgd3d12engine_p.h"
-#include "qsgd3d12context_p.h"
-#include "qsgd3d12rendercontext_p.h"
-#include <private/qsgrenderer_p.h>
-#include <private/qquickwindow_p.h>
-#include <private/qquickprofiler_p.h>
-#include <private/qquickanimatorcontroller_p.h>
-#include <private/qquickprofiler_p.h>
-#include <private/qqmldebugserviceinterfaces_p.h>
-#include <private/qqmldebugconnector_p.h>
-#include <QElapsedTimer>
-
-QT_BEGIN_NAMESPACE
-
-// NOTE: Avoid categorized logging. It is slow.
-
-#define DECLARE_DEBUG_VAR(variable) \
- static bool debug_ ## variable() \
- { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
-
-DECLARE_DEBUG_VAR(loop)
-DECLARE_DEBUG_VAR(time)
-
-/*
- The D3D render loop mostly mirrors the threaded OpenGL render loop.
-
- There are two classes here. QSGD3D12RenderLoop and QSGD3D12RenderThread. All
- communication between the two is based on event passing and we have a number
- of custom events.
-
- Render loop is per process, render thread is per window. The
- QSGD3D12RenderContext and QSGD3D12Engine are per window as well. The former
- is created (but not owned) by QQuickWindow. The D3D device is per process.
-
- In this implementation, the render thread is never blocked and the GUI
- thread will initiate a polishAndSync which will block and wait for the
- render thread to pick it up and release the block only after the render
- thread is done syncing. The reason for this is:
-
- 1. Clear blocking paradigm. We only have one real "block" point
- (polishAndSync()) and all blocking is initiated by GUI and picked up by
- Render at specific times based on events. This makes the execution
- deterministic.
-
- 2. Render does not have to interact with GUI. This is done so that the
- render thread can run its own animation system which stays alive even when
- the GUI thread is blocked doing I/O, object instantiation, QPainter-painting
- or any other non-trivial task.
-
- The render thread has affinity to the GUI thread until a window is shown.
- From that moment and until the window is destroyed, it will have affinity to
- the render thread. (moved back at the end of run for cleanup).
- */
-
-// Passed from the RL to the RT when a window is removed obscured and should be
-// removed from the render loop.
-const QEvent::Type WM_Obscure = QEvent::Type(QEvent::User + 1);
-
-// Passed from the RL to RT when GUI has been locked, waiting for sync.
-const QEvent::Type WM_RequestSync = QEvent::Type(QEvent::User + 2);
-
-// Passed by the RT to itself to trigger another render pass. This is typically
-// a result of QQuickWindow::update().
-const QEvent::Type WM_RequestRepaint = QEvent::Type(QEvent::User + 3);
-
-// Passed by the RL to the RT to maybe release resource if no windows are
-// rendering.
-const QEvent::Type WM_TryRelease = QEvent::Type(QEvent::User + 4);
-
-// Passed by the RL to the RT when a QQuickWindow::grabWindow() is called.
-const QEvent::Type WM_Grab = QEvent::Type(QEvent::User + 5);
-
-// Passed by the window when there is a render job to run.
-const QEvent::Type WM_PostJob = QEvent::Type(QEvent::User + 6);
-
-class QSGD3D12WindowEvent : public QEvent
-{
-public:
- QSGD3D12WindowEvent(QQuickWindow *c, QEvent::Type type) : QEvent(type), window(c) { }
- QQuickWindow *window;
-};
-
-class QSGD3D12TryReleaseEvent : public QSGD3D12WindowEvent
-{
-public:
- QSGD3D12TryReleaseEvent(QQuickWindow *win, bool destroy)
- : QSGD3D12WindowEvent(win, WM_TryRelease), destroying(destroy) { }
- bool destroying;
-};
-
-class QSGD3D12SyncEvent : public QSGD3D12WindowEvent
-{
-public:
- QSGD3D12SyncEvent(QQuickWindow *c, bool inExpose, bool force)
- : QSGD3D12WindowEvent(c, WM_RequestSync)
- , size(c->size())
- , dpr(c->effectiveDevicePixelRatio())
- , syncInExpose(inExpose)
- , forceRenderPass(force) { }
- QSize size;
- float dpr;
- bool syncInExpose;
- bool forceRenderPass;
-};
-
-class QSGD3D12GrabEvent : public QSGD3D12WindowEvent
-{
-public:
- QSGD3D12GrabEvent(QQuickWindow *c, QImage *result)
- : QSGD3D12WindowEvent(c, WM_Grab), image(result) { }
- QImage *image;
-};
-
-class QSGD3D12JobEvent : public QSGD3D12WindowEvent
-{
-public:
- QSGD3D12JobEvent(QQuickWindow *c, QRunnable *postedJob)
- : QSGD3D12WindowEvent(c, WM_PostJob), job(postedJob) { }
- ~QSGD3D12JobEvent() { delete job; }
- QRunnable *job;
-};
-
-class QSGD3D12EventQueue : public QQueue<QEvent *>
-{
-public:
- void addEvent(QEvent *e) {
- mutex.lock();
- enqueue(e);
- if (waiting)
- condition.wakeOne();
- mutex.unlock();
- }
-
- QEvent *takeEvent(bool wait) {
- mutex.lock();
- if (isEmpty() && wait) {
- waiting = true;
- condition.wait(&mutex);
- waiting = false;
- }
- QEvent *e = dequeue();
- mutex.unlock();
- return e;
- }
-
- bool hasMoreEvents() {
- mutex.lock();
- bool has = !isEmpty();
- mutex.unlock();
- return has;
- }
-
-private:
- QMutex mutex;
- QWaitCondition condition;
- bool waiting = false;
-};
-
-static inline int qsgrl_animation_interval()
-{
- const qreal refreshRate = QGuiApplication::primaryScreen() ? QGuiApplication::primaryScreen()->refreshRate() : 0;
- return refreshRate < 1 ? 16 : int(1000 / refreshRate);
-}
-
-class QSGD3D12RenderThread : public QThread
-{
- Q_OBJECT
-
-public:
- QSGD3D12RenderThread(QSGD3D12RenderLoop *rl, QSGRenderContext *renderContext)
- : renderLoop(rl)
- {
- rc = static_cast<QSGD3D12RenderContext *>(renderContext);
- vsyncDelta = qsgrl_animation_interval();
- }
-
- ~QSGD3D12RenderThread()
- {
- delete rc;
- }
-
- bool event(QEvent *e);
- void run();
-
- void syncAndRender();
- void sync(bool inExpose);
-
- void requestRepaint()
- {
- if (sleeping)
- stopEventProcessing = true;
- if (exposedWindow)
- pendingUpdate |= RepaintRequest;
- }
-
- void processEventsAndWaitForMore();
- void processEvents();
- void postEvent(QEvent *e);
-
- enum UpdateRequest {
- SyncRequest = 0x01,
- RepaintRequest = 0x02,
- ExposeRequest = 0x04 | RepaintRequest | SyncRequest
- };
-
- QSGD3D12Engine *engine = nullptr;
- QSGD3D12RenderLoop *renderLoop;
- QSGD3D12RenderContext *rc;
- QAnimationDriver *rtAnim = nullptr;
- volatile bool active = false;
- uint pendingUpdate = 0;
- bool sleeping = false;
- bool syncResultedInChanges = false;
- float vsyncDelta;
- QMutex mutex;
- QWaitCondition waitCondition;
- QQuickWindow *exposedWindow = nullptr;
- bool stopEventProcessing = false;
- QSGD3D12EventQueue eventQueue;
- QElapsedTimer threadTimer;
- qint64 syncTime;
- qint64 renderTime;
- qint64 sinceLastTime;
-
-public slots:
- void onSceneGraphChanged() {
- syncResultedInChanges = true;
- }
-};
-
-bool QSGD3D12RenderThread::event(QEvent *e)
-{
- switch (e->type()) {
-
- case WM_Obscure:
- Q_ASSERT(!exposedWindow || exposedWindow == static_cast<QSGD3D12WindowEvent *>(e)->window);
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "RT - WM_Obscure" << exposedWindow;
- mutex.lock();
- if (exposedWindow) {
- QQuickWindowPrivate::get(exposedWindow)->fireAboutToStop();
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_Obscure - window removed");
- exposedWindow = nullptr;
- }
- waitCondition.wakeOne();
- mutex.unlock();
- return true;
-
- case WM_RequestSync: {
- QSGD3D12SyncEvent *wme = static_cast<QSGD3D12SyncEvent *>(e);
- if (sleeping)
- stopEventProcessing = true;
- if (!engine->window()) {
- const int samples = wme->window->format().samples();
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "RT - WM_RequestSync - initializing D3D12 engine" << wme->window
- << wme->size << wme->dpr << samples;
- engine->attachToWindow(wme->window->winId(), wme->size, wme->dpr, samples);
- }
- exposedWindow = wme->window;
- Q_ASSERT(exposedWindow->winId() == engine->window()); // one thread+engine for each window
- engine->setWindowSize(wme->size, wme->dpr);
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "RT - WM_RequestSync" << exposedWindow;
- pendingUpdate |= SyncRequest;
- if (wme->syncInExpose) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_RequestSync - triggered from expose");
- pendingUpdate |= ExposeRequest;
- }
- if (wme->forceRenderPass) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_RequestSync - repaint regardless");
- pendingUpdate |= RepaintRequest;
- }
- return true;
- }
-
- case WM_TryRelease: {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_TryRelease");
- mutex.lock();
- renderLoop->lockedForSync = true;
- QSGD3D12TryReleaseEvent *wme = static_cast<QSGD3D12TryReleaseEvent *>(e);
- // Only when no windows are exposed anymore or we are shutting down.
- if (!exposedWindow || wme->destroying) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_TryRelease - invalidating rc");
- if (wme->window) {
- QQuickWindowPrivate *wd = QQuickWindowPrivate::get(wme->window);
- if (wme->destroying)
- wd->cleanupNodesOnShutdown();
- rc->invalidate();
- QCoreApplication::processEvents();
- QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
- if (wme->destroying)
- delete wd->animationController;
- }
- if (wme->destroying)
- active = false;
- if (sleeping)
- stopEventProcessing = true;
- } else {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_TryRelease - not releasing because window is still active");
- }
- waitCondition.wakeOne();
- renderLoop->lockedForSync = false;
- mutex.unlock();
- return true;
- }
-
- case WM_Grab: {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_Grab");
- QSGD3D12GrabEvent *wme = static_cast<QSGD3D12GrabEvent *>(e);
- Q_ASSERT(wme->window);
- Q_ASSERT(wme->window == exposedWindow || !exposedWindow);
- mutex.lock();
- if (wme->window) {
- // ###
- Q_UNREACHABLE();
- }
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_Grab - waking gui to handle result");
- waitCondition.wakeOne();
- mutex.unlock();
- return true;
- }
-
- case WM_PostJob: {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_PostJob");
- QSGD3D12JobEvent *wme = static_cast<QSGD3D12JobEvent *>(e);
- Q_ASSERT(wme->window == exposedWindow);
- if (exposedWindow) {
- wme->job->run();
- delete wme->job;
- wme->job = nullptr;
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_PostJob - job done");
- }
- return true;
- }
-
- case WM_RequestRepaint:
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_RequestPaint");
- // When GUI posts this event, it is followed by a polishAndSync, so we
- // must not exit the event loop yet.
- pendingUpdate |= RepaintRequest;
- break;
-
- default:
- break;
- }
-
- return QThread::event(e);
-}
-
-void QSGD3D12RenderThread::postEvent(QEvent *e)
-{
- eventQueue.addEvent(e);
-}
-
-void QSGD3D12RenderThread::processEvents()
-{
- while (eventQueue.hasMoreEvents()) {
- QEvent *e = eventQueue.takeEvent(false);
- event(e);
- delete e;
- }
-}
-
-void QSGD3D12RenderThread::processEventsAndWaitForMore()
-{
- stopEventProcessing = false;
- while (!stopEventProcessing) {
- QEvent *e = eventQueue.takeEvent(true);
- event(e);
- delete e;
- }
-}
-
-void QSGD3D12RenderThread::run()
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - run()");
-
- engine = new QSGD3D12Engine;
- rc->setEngine(engine);
-
- rtAnim = rc->sceneGraphContext()->createAnimationDriver(nullptr);
- rtAnim->install();
-
- if (QQmlDebugConnector::service<QQmlProfilerService>())
- QQuickProfiler::registerAnimationCallback();
-
- while (active) {
- if (exposedWindow)
- syncAndRender();
-
- processEvents();
- QCoreApplication::processEvents();
-
- if (pendingUpdate == 0 || !exposedWindow) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - done drawing, sleep");
- sleeping = true;
- processEventsAndWaitForMore();
- sleeping = false;
- }
- }
-
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - run() exiting");
-
- delete rtAnim;
- rtAnim = nullptr;
-
- rc->moveToThread(renderLoop->thread());
- moveToThread(renderLoop->thread());
-
- rc->setEngine(nullptr);
- delete engine;
- engine = nullptr;
-}
-
-void QSGD3D12RenderThread::sync(bool inExpose)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - sync");
-
- mutex.lock();
- Q_ASSERT_X(renderLoop->lockedForSync, "QSGD3D12RenderThread::sync()", "sync triggered with gui not locked");
-
- // Recover from device loss.
- if (!engine->hasResources()) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - sync - device was lost, resetting scenegraph");
- QQuickWindowPrivate::get(exposedWindow)->cleanupNodesOnShutdown();
- rc->invalidate();
- }
-
- if (engine->window()) {
- QQuickWindowPrivate *wd = QQuickWindowPrivate::get(exposedWindow);
- bool hadRenderer = wd->renderer != nullptr;
- // If the scene graph was touched since the last sync() make sure it sends the
- // changed signal.
- if (wd->renderer)
- wd->renderer->clearChangedFlag();
-
- wd->syncSceneGraph();
-
- if (!hadRenderer && wd->renderer) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - created renderer");
- syncResultedInChanges = true;
- connect(wd->renderer, &QSGRenderer::sceneGraphChanged, this,
- &QSGD3D12RenderThread::onSceneGraphChanged, Qt::DirectConnection);
- }
-
- // Process deferred deletes now, directly after the sync as deleteLater
- // on the GUI must now also have resulted in SG changes and the delete
- // is a safe operation.
- QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
- }
-
- if (!inExpose) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - sync complete, waking gui");
- waitCondition.wakeOne();
- mutex.unlock();
- }
-}
-
-void QSGD3D12RenderThread::syncAndRender()
-{
- bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled();
- if (profileFrames) {
- sinceLastTime = threadTimer.nsecsElapsed();
- threadTimer.start();
- }
- Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphRenderLoopFrame);
-
- QElapsedTimer waitTimer;
- waitTimer.start();
-
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - syncAndRender()");
-
- syncResultedInChanges = false;
- QQuickWindowPrivate *wd = QQuickWindowPrivate::get(exposedWindow);
-
- const bool repaintRequested = (pendingUpdate & RepaintRequest) || wd->customRenderStage;
- const bool syncRequested = pendingUpdate & SyncRequest;
- const bool exposeRequested = (pendingUpdate & ExposeRequest) == ExposeRequest;
- pendingUpdate = 0;
-
- if (syncRequested)
- sync(exposeRequested);
-
-#ifndef QSG_NO_RENDER_TIMING
- if (profileFrames)
- syncTime = threadTimer.nsecsElapsed();
-#endif
- Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame);
-
- if (!syncResultedInChanges && !repaintRequested) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - no changes, render aborted");
- int waitTime = vsyncDelta - (int) waitTimer.elapsed();
- if (waitTime > 0)
- msleep(waitTime);
- return;
- }
-
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - rendering started");
-
- if (rtAnim->isRunning()) {
- wd->animationController->lock();
- rtAnim->advance();
- wd->animationController->unlock();
- }
-
- bool canRender = wd->renderer != nullptr;
- // Recover from device loss.
- if (!engine->hasResources()) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - syncAndRender - device was lost, posting FullUpdateRequest");
- // Cannot do anything here because gui is not locked. Request a new
- // sync+render round on the gui thread and let the sync handle it.
- QCoreApplication::postEvent(exposedWindow, new QEvent(QEvent::Type(QQuickWindowPrivate::FullUpdateRequest)));
- canRender = false;
- }
-
- if (canRender) {
- wd->renderSceneGraph(engine->windowSize());
- if (profileFrames)
- renderTime = threadTimer.nsecsElapsed();
- Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame);
-
- // The engine is able to have multiple frames in flight. This in effect is
- // similar to BufferQueueingOpenGL. Provide an env var to force the
- // traditional blocking swap behavior, just in case.
- static bool blockOnEachFrame = qEnvironmentVariableIntValue("QT_D3D_BLOCKING_PRESENT") != 0;
-
- if (!wd->customRenderStage || !wd->customRenderStage->swap())
- engine->present();
-
- if (blockOnEachFrame)
- engine->waitGPU();
-
- // The concept of "frame swaps" is quite misleading by default, when
- // blockOnEachFrame is not used, but emit it for compatibility.
- wd->fireFrameSwapped();
- } else {
- Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame, 1);
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - window not ready, skipping render");
- }
-
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - rendering done");
-
- if (exposeRequested) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - wake gui after initial expose");
- waitCondition.wakeOne();
- mutex.unlock();
- }
-
- if (Q_UNLIKELY(debug_time()))
- qDebug("Frame rendered with 'd3d12' renderloop in %dms, sync=%d, render=%d, swap=%d - (on render thread)",
- int(threadTimer.elapsed()),
- int((syncTime/1000000)),
- int((renderTime - syncTime) / 1000000),
- int(threadTimer.elapsed() - renderTime / 1000000));
-
- Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame);
-}
-
-template<class T> T *windowFor(const QVector<T> &list, QQuickWindow *window)
-{
- for (const T &t : list) {
- if (t.window == window)
- return const_cast<T *>(&t);
- }
- return nullptr;
-}
-
-QSGD3D12RenderLoop::QSGD3D12RenderLoop()
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug("new d3d12 render loop ctor");
-
- sg = new QSGD3D12Context;
-
- anim = sg->createAnimationDriver(this);
- connect(anim, &QAnimationDriver::started, this, &QSGD3D12RenderLoop::onAnimationStarted);
- connect(anim, &QAnimationDriver::stopped, this, &QSGD3D12RenderLoop::onAnimationStopped);
- anim->install();
-}
-
-QSGD3D12RenderLoop::~QSGD3D12RenderLoop()
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug("new d3d12 render loop dtor");
-
- delete sg;
-}
-
-void QSGD3D12RenderLoop::show(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "show" << window;
-}
-
-void QSGD3D12RenderLoop::hide(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "hide" << window;
-
- if (window->isExposed())
- handleObscurity(windowFor(windows, window));
-
- releaseResources(window);
-}
-
-void QSGD3D12RenderLoop::resize(QQuickWindow *window)
-{
- if (!window->isExposed() || window->size().isEmpty())
- return;
-
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "resize" << window << window->size();
-}
-
-void QSGD3D12RenderLoop::windowDestroyed(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "window destroyed" << window;
-
- WindowData *w = windowFor(windows, window);
- if (!w)
- return;
-
- handleObscurity(w);
- handleResourceRelease(w, true);
-
- QSGD3D12RenderThread *thread = w->thread;
- while (thread->isRunning())
- QThread::yieldCurrentThread();
-
- Q_ASSERT(thread->thread() == QThread::currentThread());
- delete thread;
-
- for (int i = 0; i < windows.size(); ++i) {
- if (windows.at(i).window == window) {
- windows.removeAt(i);
- break;
- }
- }
-}
-
-void QSGD3D12RenderLoop::exposureChanged(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "exposure changed" << window;
-
- if (window->isExposed()) {
- handleExposure(window);
- } else {
- WindowData *w = windowFor(windows, window);
- if (w)
- handleObscurity(w);
- }
-}
-
-QImage QSGD3D12RenderLoop::grab(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "grab" << window;
-
- WindowData *w = windowFor(windows, window);
- Q_ASSERT(w);
-
- if (!w->thread->isRunning())
- return QImage();
-
- if (!window->handle())
- window->create();
-
- QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window);
- wd->polishItems();
-
- QImage result;
- w->thread->mutex.lock();
- lockedForSync = true;
- w->thread->postEvent(new QSGD3D12GrabEvent(window, &result));
- w->thread->waitCondition.wait(&w->thread->mutex);
- lockedForSync = false;
- w->thread->mutex.unlock();
-
- return result;
-}
-
-void QSGD3D12RenderLoop::update(QQuickWindow *window)
-{
- WindowData *w = windowFor(windows, window);
- if (!w)
- return;
-
- if (w->thread == QThread::currentThread()) {
- w->thread->requestRepaint();
- return;
- }
-
- // We set forceRenderPass because we want to make sure the QQuickWindow
- // actually does a full render pass after the next sync.
- w->forceRenderPass = true;
- scheduleUpdate(w);
-}
-
-void QSGD3D12RenderLoop::maybeUpdate(QQuickWindow *window)
-{
- WindowData *w = windowFor(windows, window);
- if (w)
- scheduleUpdate(w);
-}
-
-// called in response to window->requestUpdate()
-void QSGD3D12RenderLoop::handleUpdateRequest(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "handleUpdateRequest" << window;
-
- WindowData *w = windowFor(windows, window);
- if (w)
- polishAndSync(w, false);
-}
-
-QAnimationDriver *QSGD3D12RenderLoop::animationDriver() const
-{
- return anim;
-}
-
-QSGContext *QSGD3D12RenderLoop::sceneGraphContext() const
-{
- return sg;
-}
-
-QSGRenderContext *QSGD3D12RenderLoop::createRenderContext(QSGContext *) const
-{
- return sg->createRenderContext();
-}
-
-void QSGD3D12RenderLoop::releaseResources(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "releaseResources" << window;
-
- WindowData *w = windowFor(windows, window);
- if (w)
- handleResourceRelease(w, false);
-}
-
-void QSGD3D12RenderLoop::postJob(QQuickWindow *window, QRunnable *job)
-{
- WindowData *w = windowFor(windows, window);
- if (w && w->thread && w->thread->exposedWindow)
- w->thread->postEvent(new QSGD3D12JobEvent(window, job));
- else
- delete job;
-}
-
-QSurface::SurfaceType QSGD3D12RenderLoop::windowSurfaceType() const
-{
- return QSurface::OpenGLSurface;
-}
-
-bool QSGD3D12RenderLoop::interleaveIncubation() const
-{
- bool somethingVisible = false;
- for (const WindowData &w : windows) {
- if (w.window->isVisible() && w.window->isExposed()) {
- somethingVisible = true;
- break;
- }
- }
- return somethingVisible && anim->isRunning();
-}
-
-bool QSGD3D12RenderLoop::event(QEvent *e)
-{
- if (e->type() == QEvent::Timer) {
- QTimerEvent *te = static_cast<QTimerEvent *>(e);
- if (te->timerId() == animationTimer) {
- anim->advance();
- emit timeToIncubate();
- return true;
- }
- }
-
- return QObject::event(e);
-}
-
-void QSGD3D12RenderLoop::onAnimationStarted()
-{
- startOrStopAnimationTimer();
-
- for (const WindowData &w : qAsConst(windows))
- w.window->requestUpdate();
-}
-
-void QSGD3D12RenderLoop::onAnimationStopped()
-{
- startOrStopAnimationTimer();
-}
-
-void QSGD3D12RenderLoop::startOrStopAnimationTimer()
-{
- int exposedWindowCount = 0;
- const WindowData *exposed = nullptr;
-
- for (int i = 0; i < windows.size(); ++i) {
- const WindowData &w(windows[i]);
- if (w.window->isVisible() && w.window->isExposed()) {
- ++exposedWindowCount;
- exposed = &w;
- }
- }
-
- if (animationTimer && (exposedWindowCount == 1 || !anim->isRunning())) {
- killTimer(animationTimer);
- animationTimer = 0;
- // If animations are running, make sure we keep on animating
- if (anim->isRunning())
- exposed->window->requestUpdate();
- } else if (!animationTimer && exposedWindowCount != 1 && anim->isRunning()) {
- animationTimer = startTimer(qsgrl_animation_interval());
- }
-}
-
-void QSGD3D12RenderLoop::handleExposure(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "handleExposure" << window;
-
- WindowData *w = windowFor(windows, window);
- if (!w) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("adding window to list");
- WindowData win;
- win.window = window;
- QSGRenderContext *rc = QQuickWindowPrivate::get(window)->context; // will transfer ownership
- win.thread = new QSGD3D12RenderThread(this, rc);
- win.updateDuringSync = false;
- win.forceRenderPass = true; // also covered by polishAndSync(inExpose=true), but doesn't hurt
- windows.append(win);
- w = &windows.last();
- }
-
- // set this early as we'll be rendering shortly anyway and this avoids
- // special casing exposure in polishAndSync.
- w->thread->exposedWindow = window;
-
- if (w->window->size().isEmpty()
- || (w->window->isTopLevel() && !w->window->geometry().intersects(w->window->screen()->availableGeometry()))) {
-#ifndef QT_NO_DEBUG
- qWarning().noquote().nospace() << "QSGD3D12RenderLoop: expose event received for window "
- << w->window << " with invalid geometry: " << w->window->geometry()
- << " on " << w->window->screen();
-#endif
- }
-
- if (!w->window->handle())
- w->window->create();
-
- // Start render thread if it is not running
- if (!w->thread->isRunning()) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("starting render thread");
- // Push a few things to the render thread.
- QQuickAnimatorController *controller = QQuickWindowPrivate::get(w->window)->animationController;
- if (controller->thread() != w->thread)
- controller->moveToThread(w->thread);
- if (w->thread->thread() == QThread::currentThread()) {
- w->thread->rc->moveToThread(w->thread);
- w->thread->moveToThread(w->thread);
- }
-
- w->thread->active = true;
- w->thread->start();
-
- if (!w->thread->isRunning())
- qFatal("Render thread failed to start, aborting application.");
- }
-
- polishAndSync(w, true);
-
- startOrStopAnimationTimer();
-}
-
-void QSGD3D12RenderLoop::handleObscurity(WindowData *w)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "handleObscurity" << w->window;
-
- if (w->thread->isRunning()) {
- w->thread->mutex.lock();
- w->thread->postEvent(new QSGD3D12WindowEvent(w->window, WM_Obscure));
- w->thread->waitCondition.wait(&w->thread->mutex);
- w->thread->mutex.unlock();
- }
-
- startOrStopAnimationTimer();
-}
-
-void QSGD3D12RenderLoop::scheduleUpdate(WindowData *w)
-{
- if (!QCoreApplication::instance())
- return;
-
- if (!w || !w->thread->isRunning())
- return;
-
- QThread *current = QThread::currentThread();
- if (current != QCoreApplication::instance()->thread() && (current != w->thread || !lockedForSync)) {
- qWarning() << "Updates can only be scheduled from GUI thread or from QQuickItem::updatePaintNode()";
- return;
- }
-
- if (current == w->thread) {
- w->updateDuringSync = true;
- return;
- }
-
- w->window->requestUpdate();
-}
-
-void QSGD3D12RenderLoop::handleResourceRelease(WindowData *w, bool destroying)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "handleResourceRelease" << (destroying ? "destroying" : "hide/releaseResources") << w->window;
-
- w->thread->mutex.lock();
- if (w->thread->isRunning() && w->thread->active) {
- QQuickWindow *window = w->window;
-
- // Note that window->handle() is typically null by this time because
- // the platform window is already destroyed. This should not be a
- // problem for the D3D cleanup.
-
- w->thread->postEvent(new QSGD3D12TryReleaseEvent(window, destroying));
- w->thread->waitCondition.wait(&w->thread->mutex);
-
- // Avoid a shutdown race condition.
- // If SG is invalidated and 'active' becomes false, the thread's run()
- // method will exit. handleExposure() relies on QThread::isRunning() (because it
- // potentially needs to start the thread again) and our mutex cannot be used to
- // track the thread stopping, so we wait a few nanoseconds extra so the thread
- // can exit properly.
- if (!w->thread->active)
- w->thread->wait();
- }
- w->thread->mutex.unlock();
-}
-
-void QSGD3D12RenderLoop::polishAndSync(WindowData *w, bool inExpose)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "polishAndSync" << (inExpose ? "(in expose)" : "(normal)") << w->window;
-
- QQuickWindow *window = w->window;
- if (!w->thread || !w->thread->exposedWindow) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("polishAndSync - not exposed, abort");
- return;
- }
-
- // Flush pending touch events.
- QQuickWindowPrivate::get(window)->flushDelayedTouchEvent();
- // The delivery of the event might have caused the window to stop rendering
- w = windowFor(windows, window);
- if (!w || !w->thread || !w->thread->exposedWindow) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("polishAndSync - removed after touch event flushing, abort");
- return;
- }
-
- QElapsedTimer timer;
- qint64 polishTime = 0;
- qint64 waitTime = 0;
- qint64 syncTime = 0;
- bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled();
- if (profileFrames)
- timer.start();
- Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishAndSync);
-
- QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window);
- wd->polishItems();
-
- if (profileFrames)
- polishTime = timer.nsecsElapsed();
- Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync);
-
- w->updateDuringSync = false;
-
- emit window->afterAnimating();
-
- if (Q_UNLIKELY(debug_loop()))
- qDebug("polishAndSync - lock for sync");
- w->thread->mutex.lock();
- lockedForSync = true;
- w->thread->postEvent(new QSGD3D12SyncEvent(window, inExpose, w->forceRenderPass));
- w->forceRenderPass = false;
-
- if (Q_UNLIKELY(debug_loop()))
- qDebug("polishAndSync - wait for sync");
- if (profileFrames)
- waitTime = timer.nsecsElapsed();
- Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync);
- w->thread->waitCondition.wait(&w->thread->mutex);
- lockedForSync = false;
- w->thread->mutex.unlock();
- if (Q_UNLIKELY(debug_loop()))
- qDebug("polishAndSync - unlock after sync");
-
- if (profileFrames)
- syncTime = timer.nsecsElapsed();
- Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync);
-
- if (!animationTimer && anim->isRunning()) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("polishAndSync - advancing animations");
- anim->advance();
- // We need to trigger another sync to keep animations running...
- w->window->requestUpdate();
- emit timeToIncubate();
- } else if (w->updateDuringSync) {
- w->window->requestUpdate();
- }
-
- if (Q_UNLIKELY(debug_time()))
- qDebug().nospace()
- << "Frame prepared with 'd3d12' renderloop"
- << ", polish=" << (polishTime / 1000000)
- << ", lock=" << (waitTime - polishTime) / 1000000
- << ", blockedForSync=" << (syncTime - waitTime) / 1000000
- << ", animations=" << (timer.nsecsElapsed() - syncTime) / 1000000
- << " - (on gui thread) " << window;
-
- Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync);
-}
-
-#include "qsgd3d12renderloop.moc"
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop_p.h
deleted file mode 100644
index 56dcb1d490..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop_p.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12RENDERLOOP_P_H
-#define QSGD3D12RENDERLOOP_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qsgrenderloop_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12Engine;
-class QSGD3D12Context;
-class QSGD3D12RenderContext;
-class QSGD3D12RenderThread;
-
-class QSGD3D12RenderLoop : public QSGRenderLoop
-{
- Q_OBJECT
-
-public:
- QSGD3D12RenderLoop();
- ~QSGD3D12RenderLoop();
-
- void show(QQuickWindow *window) override;
- void hide(QQuickWindow *window) override;
- void resize(QQuickWindow *window) override;
-
- void windowDestroyed(QQuickWindow *window) override;
-
- void exposureChanged(QQuickWindow *window) override;
-
- QImage grab(QQuickWindow *window) override;
-
- void update(QQuickWindow *window) override;
- void maybeUpdate(QQuickWindow *window) override;
- void handleUpdateRequest(QQuickWindow *window) override;
-
- QAnimationDriver *animationDriver() const override;
-
- QSGContext *sceneGraphContext() const override;
- QSGRenderContext *createRenderContext(QSGContext *) const override;
-
- void releaseResources(QQuickWindow *window) override;
- void postJob(QQuickWindow *window, QRunnable *job) override;
-
- QSurface::SurfaceType windowSurfaceType() const override;
-
- bool interleaveIncubation() const override;
-
- bool event(QEvent *e) override;
-
-public Q_SLOTS:
- void onAnimationStarted();
- void onAnimationStopped();
-
-private:
- struct WindowData {
- QQuickWindow *window;
- QSGD3D12RenderThread *thread;
- uint updateDuringSync : 1;
- uint forceRenderPass : 1;
- };
-
- void startOrStopAnimationTimer();
- void handleExposure(QQuickWindow *window);
- void handleObscurity(WindowData *w);
- void scheduleUpdate(WindowData *w);
- void handleResourceRelease(WindowData *w, bool destroying);
- void polishAndSync(WindowData *w, bool inExpose);
-
- QSGD3D12Context *sg;
- QAnimationDriver *anim;
- int animationTimer = 0;
- bool lockedForSync = false;
- QVector<WindowData> windows;
-
- friend class QSGD3D12RenderThread;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12RENDERLOOP_P_H
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture.cpp
deleted file mode 100644
index 0250023fdf..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12texture_p.h"
-#include "qsgd3d12engine_p.h"
-#include <private/qsgcontext_p.h>
-
-QT_BEGIN_NAMESPACE
-
-void QSGD3D12Texture::setImage(const QImage &image, uint flags)
-{
- // ### atlas?
-
- const bool alphaRequest = flags & QSGRenderContext::CreateTexture_Alpha;
- m_alphaWanted = alphaRequest && image.hasAlphaChannel();
-
- m_image = image;
- m_size = image.size();
-
- m_id = m_engine->genTexture();
- Q_ASSERT(m_id);
-
- // We could kick off the texture creation and the async upload right here.
- // Unfortunately we cannot tell at this stage if mipmaps will be enabled
- // via an Image element's mipmap property...so defer to bind().
- m_createPending = true;
-}
-
-QSGD3D12Texture::~QSGD3D12Texture()
-{
- if (m_id)
- m_engine->releaseTexture(m_id);
-}
-
-int QSGD3D12Texture::textureId() const
-{
- return m_id;
-}
-
-QSize QSGD3D12Texture::textureSize() const
-{
- return m_size;
-}
-
-bool QSGD3D12Texture::hasAlphaChannel() const
-{
- return m_alphaWanted;
-}
-
-bool QSGD3D12Texture::hasMipmaps() const
-{
- return mipmapFiltering() != QSGTexture::None;
-}
-
-QRectF QSGD3D12Texture::normalizedTextureSubRect() const
-{
- return QRectF(0, 0, 1, 1);
-}
-
-void QSGD3D12Texture::bind()
-{
- // Called when the texture material updates the pipeline state.
-
- if (!m_createPending && hasMipmaps() != m_createdWithMipMaps) {
- m_engine->releaseTexture(m_id);
- m_id = m_engine->genTexture();
- Q_ASSERT(m_id);
- m_createPending = true;
- }
-
- if (m_createPending) {
- m_createPending = false;
-
- QSGD3D12Engine::TextureCreateFlags createFlags = 0;
- if (m_alphaWanted)
- createFlags |= QSGD3D12Engine::CreateWithAlpha;
-
- m_createdWithMipMaps = hasMipmaps();
- if (m_createdWithMipMaps)
- createFlags |= QSGD3D12Engine::CreateWithMipMaps;
-
- m_engine->createTexture(m_id, m_image.size(), m_image.format(), createFlags);
- m_engine->queueTextureUpload(m_id, m_image);
- }
-
- // Here we know that the texture is going to be used in the current frame
- // by the next draw call. Notify the engine so that it can wait for
- // possible pending uploads and set up the pipeline accordingly.
- m_engine->activateTexture(m_id);
-}
-
-SIZE_T QSGD3D12Texture::srv() const
-{
- Q_ASSERT(m_id);
- return m_engine->textureSRV(m_id);
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture_p.h
deleted file mode 100644
index b9d53dd1e6..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture_p.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12TEXTURE_P_H
-#define QSGD3D12TEXTURE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qsgtexture.h>
-#include <basetsd.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12Engine;
-
-class QSGD3D12Texture : public QSGTexture
-{
-public:
- QSGD3D12Texture(QSGD3D12Engine *engine) : m_engine(engine) { }
- ~QSGD3D12Texture();
-
- void setImage(const QImage &image, uint flags);
-
- int textureId() const override;
- QSize textureSize() const override;
- bool hasAlphaChannel() const override;
- bool hasMipmaps() const override;
- QRectF normalizedTextureSubRect() const override;
- void bind() override;
-
- SIZE_T srv() const;
-
-private:
- QSGD3D12Engine *m_engine;
- QImage m_image;
- bool m_createPending = false;
- bool m_createdWithMipMaps = false;
- uint m_id = 0;
- bool m_alphaWanted = false;
- QSize m_size;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/quick/scenegraph/adaptations/d3d12/shaders/mipmapgen.hlsl b/src/quick/scenegraph/adaptations/d3d12/shaders/mipmapgen.hlsl
deleted file mode 100644
index 6793b534b0..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/shaders/mipmapgen.hlsl
+++ /dev/null
@@ -1,60 +0,0 @@
-static const uint GROUP_DIM = 8; // 2 ^ (out_mip_count - 1)
-
-Texture2D tex : register(t0);
-SamplerState samp : register(s0);
-
-cbuffer ConstantBuffer : register(b0)
-{
- uint2 mip1Size;
- uint sampleLevel;
- uint totalMips;
-}
-
-RWTexture2D<float4> mip1 : register(u0);
-RWTexture2D<float4> mip2 : register(u1);
-RWTexture2D<float4> mip3 : register(u2);
-RWTexture2D<float4> mip4 : register(u3);
-
-groupshared float4 groupColor[GROUP_DIM][GROUP_DIM];
-
-[numthreads(GROUP_DIM, GROUP_DIM, 1)]
-void CS_Generate4MipMaps(uint3 localId: SV_GroupThreadId, uint3 globalId: SV_DispatchThreadID)
-{
- const float2 coord = float2(1.0f / float(mip1Size.x), 1.0f / float(mip1Size.y)) * (globalId.xy + 0.5);
- float4 c = tex.SampleLevel(samp, coord, sampleLevel);
-
- mip1[globalId.xy] = c;
- groupColor[localId.y][localId.x] = c;
-
- if (sampleLevel + 1 >= totalMips)
- return;
-
- GroupMemoryBarrierWithGroupSync();
-
- if ((localId.x & 1) == 0 && (localId.y & 1) == 0) {
- c = (c + groupColor[localId.y][localId.x + 1] + groupColor[localId.y + 1][localId.x] + groupColor[localId.y + 1][localId.x + 1]) / 4.0;
- mip2[globalId.xy / 2] = c;
- groupColor[localId.y][localId.x] = c;
- }
-
- if (sampleLevel + 2 >= totalMips)
- return;
-
- GroupMemoryBarrierWithGroupSync();
-
- if ((localId.x & 3) == 0 && (localId.y & 3) == 0) {
- c = (c + groupColor[localId.y][localId.x + 2] + groupColor[localId.y + 2][localId.x] + groupColor[localId.y + 2][localId.x + 2]) / 4.0;
- mip3[globalId.xy / 4] = c;
- groupColor[localId.y][localId.x] = c;
- }
-
- if (sampleLevel + 3 >= totalMips)
- return;
-
- GroupMemoryBarrierWithGroupSync();
-
- if ((localId.x & 7) == 0 && (localId.y & 7) == 0) {
- c = (c + groupColor[localId.y][localId.x + 3] + groupColor[localId.y + 3][localId.x] + groupColor[localId.y + 3][localId.x + 3]) / 4.0;
- mip4[globalId.xy / 8] = c;
- }
-}
diff --git a/src/quick/scenegraph/adaptations/d3d12/shaders/shaders.pri b/src/quick/scenegraph/adaptations/d3d12/shaders/shaders.pri
deleted file mode 100644
index 02786e2606..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/shaders/shaders.pri
+++ /dev/null
@@ -1,101 +0,0 @@
-vertexcolor_VSPS = $$PWD/vertexcolor.hlsl
-vertexcolor_vshader.input = vertexcolor_VSPS
-vertexcolor_vshader.header = vs_vertexcolor.hlslh
-vertexcolor_vshader.entry = VS_VertexColor
-vertexcolor_vshader.type = vs_5_0
-vertexcolor_pshader.input = vertexcolor_VSPS
-vertexcolor_pshader.header = ps_vertexcolor.hlslh
-vertexcolor_pshader.entry = PS_VertexColor
-vertexcolor_pshader.type = ps_5_0
-
-stencilclip_VSPS = $$PWD/stencilclip.hlsl
-stencilclip_vshader.input = stencilclip_VSPS
-stencilclip_vshader.header = vs_stencilclip.hlslh
-stencilclip_vshader.entry = VS_StencilClip
-stencilclip_vshader.type = vs_5_0
-stencilclip_pshader.input = stencilclip_VSPS
-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
-
-texture_VSPS = $$PWD/texture.hlsl
-texture_vshader.input = texture_VSPS
-texture_vshader.header = vs_texture.hlslh
-texture_vshader.entry = VS_Texture
-texture_vshader.type = vs_5_0
-texture_pshader.input = texture_VSPS
-texture_pshader.header = ps_texture.hlslh
-texture_pshader.entry = PS_Texture
-texture_pshader.type = ps_5_0
-
-smoothtexture_VSPS = $$PWD/smoothtexture.hlsl
-smoothtexture_vshader.input = smoothtexture_VSPS
-smoothtexture_vshader.header = vs_smoothtexture.hlslh
-smoothtexture_vshader.entry = VS_SmoothTexture
-smoothtexture_vshader.type = vs_5_0
-smoothtexture_pshader.input = smoothtexture_VSPS
-smoothtexture_pshader.header = ps_smoothtexture.hlslh
-smoothtexture_pshader.entry = PS_SmoothTexture
-smoothtexture_pshader.type = ps_5_0
-
-mipmapgen_CS = $$PWD/mipmapgen.hlsl
-mipmapgen_cshader.input = mipmapgen_CS
-mipmapgen_cshader.header = cs_mipmapgen.hlslh
-mipmapgen_cshader.entry = CS_Generate4MipMaps
-mipmapgen_cshader.type = cs_5_0
-
-textmask_VSPS = $$PWD/textmask.hlsl
-textmask_vshader.input = textmask_VSPS
-textmask_vshader.header = vs_textmask.hlslh
-textmask_vshader.entry = VS_TextMask
-textmask_vshader.type = vs_5_0
-textmask_pshader24.input = textmask_VSPS
-textmask_pshader24.header = ps_textmask24.hlslh
-textmask_pshader24.entry = PS_TextMask24
-textmask_pshader24.type = ps_5_0
-textmask_pshader32.input = textmask_VSPS
-textmask_pshader32.header = ps_textmask32.hlslh
-textmask_pshader32.entry = PS_TextMask32
-textmask_pshader32.type = ps_5_0
-textmask_pshader8.input = textmask_VSPS
-textmask_pshader8.header = ps_textmask8.hlslh
-textmask_pshader8.entry = PS_TextMask8
-textmask_pshader8.type = ps_5_0
-styledtext_vshader.input = textmask_VSPS
-styledtext_vshader.header = vs_styledtext.hlslh
-styledtext_vshader.entry = VS_StyledText
-styledtext_vshader.type = vs_5_0
-styledtext_pshader.input = textmask_VSPS
-styledtext_pshader.header = ps_styledtext.hlslh
-styledtext_pshader.entry = PS_StyledText
-styledtext_pshader.type = ps_5_0
-outlinedtext_vshader.input = textmask_VSPS
-outlinedtext_vshader.header = vs_outlinedtext.hlslh
-outlinedtext_vshader.entry = VS_OutlinedText
-outlinedtext_vshader.type = vs_5_0
-outlinedtext_pshader.input = textmask_VSPS
-outlinedtext_pshader.header = ps_outlinedtext.hlslh
-outlinedtext_pshader.entry = PS_OutlinedText
-outlinedtext_pshader.type = ps_5_0
-
-HLSL_SHADERS = \
- vertexcolor_vshader vertexcolor_pshader \
- stencilclip_vshader stencilclip_pshader \
- smoothcolor_vshader smoothcolor_pshader \
- texture_vshader texture_pshader \
- smoothtexture_vshader smoothtexture_pshader \
- mipmapgen_cshader \
- textmask_vshader textmask_pshader24 textmask_pshader32 textmask_pshader8 \
- styledtext_vshader styledtext_pshader outlinedtext_vshader outlinedtext_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
deleted file mode 100644
index 4f69eea60f..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/shaders/smoothcolor.hlsl
+++ /dev/null
@@ -1,64 +0,0 @@
-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/adaptations/d3d12/shaders/smoothtexture.hlsl b/src/quick/scenegraph/adaptations/d3d12/shaders/smoothtexture.hlsl
deleted file mode 100644
index 05b1c6e9d4..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/shaders/smoothtexture.hlsl
+++ /dev/null
@@ -1,77 +0,0 @@
-struct VSInput
-{
- float4 position : POSITION;
- float2 coord : TEXCOORD0;
- float2 offset : TEXCOORD1;
- float2 coordOffset : TEXCOORD2;
-};
-
-cbuffer ConstantBuffer : register(b0)
-{
- float4x4 mvp;
- float opacity;
- float2 pixelSize;
-};
-
-struct PSInput
-{
- float4 position : SV_POSITION;
- float2 coord : TEXCOORD0;
- float vertexOpacity : TEXCOORD3;
-};
-
-Texture2D tex : register(t0);
-SamplerState samp : register(s0);
-
-PSInput VS_SmoothTexture(VSInput input)
-{
- PSInput result;
-
- float4 pos = mul(mvp, input.position);
- float2 coord = input.coord;
-
- 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;
- coord.x += scale * input.coordOffset.x;
- }
-
- 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;
- coord.y += scale * input.coordOffset.y;
- }
-
- if ((input.offset.x != 0.0 || input.offset.y != 0.0) && (input.coordOffset.x == 0.0 && input.coordOffset.y == 0.0))
- result.vertexOpacity = 0.0;
- else
- result.vertexOpacity = opacity;
-
- result.position = pos;
- result.coord = coord;
- return result;
-}
-
-float4 PS_SmoothTexture(PSInput input) : SV_TARGET
-{
- return tex.Sample(samp, input.coord) * input.vertexOpacity;
-}
diff --git a/src/quick/scenegraph/adaptations/d3d12/shaders/stencilclip.hlsl b/src/quick/scenegraph/adaptations/d3d12/shaders/stencilclip.hlsl
deleted file mode 100644
index 9aff84d261..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/shaders/stencilclip.hlsl
+++ /dev/null
@@ -1,26 +0,0 @@
-struct VSInput
-{
- float4 position : POSITION;
-};
-
-cbuffer ConstantBuffer : register(b0)
-{
- float4x4 mvp;
-};
-
-struct PSInput
-{
- float4 position : SV_POSITION;
-};
-
-PSInput VS_StencilClip(VSInput input)
-{
- PSInput result;
- result.position = mul(mvp, input.position);
- return result;
-}
-
-float4 PS_StencilClip(PSInput input) : SV_TARGET
-{
- return float4(0.81, 0.83, 0.12, 1.0); // Trolltech green ftw!
-}
diff --git a/src/quick/scenegraph/adaptations/d3d12/shaders/textmask.hlsl b/src/quick/scenegraph/adaptations/d3d12/shaders/textmask.hlsl
deleted file mode 100644
index f9d92e8ee9..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/shaders/textmask.hlsl
+++ /dev/null
@@ -1,104 +0,0 @@
-struct VSInput
-{
- float4 position : POSITION;
- float2 coord : TEXCOORD0;
-};
-
-cbuffer ConstantBuffer : register(b0)
-{
- float4x4 mvp;
- float2 textureScale;
- float dpr;
- float color; // for TextMask24 and 32
- float4 colorVec; // for TextMask8 and Styled and Outlined
- float2 shift; // for Styled
- float4 styleColor; // for Styled and Outlined
-};
-
-struct PSInput
-{
- float4 position : SV_POSITION;
- float2 coord : TEXCOORD0;
-};
-
-Texture2D tex : register(t0);
-SamplerState samp : register(s0);
-
-PSInput VS_TextMask(VSInput input)
-{
- PSInput result;
- result.position = mul(mvp, floor(input.position * dpr + 0.5) / dpr);
- result.coord = input.coord * textureScale;
- return result;
-}
-
-float4 PS_TextMask24(PSInput input) : SV_TARGET
-{
- float4 glyph = tex.Sample(samp, input.coord);
- return float4(glyph.rgb * color, glyph.a);
-}
-
-float4 PS_TextMask32(PSInput input) : SV_TARGET
-{
- return tex.Sample(samp, input.coord) * color;
-}
-
-float4 PS_TextMask8(PSInput input) : SV_TARGET
-{
- return colorVec * tex.Sample(samp, input.coord).r;
-}
-
-struct StyledPSInput
-{
- float4 position : SV_POSITION;
- float2 coord : TEXCOORD0;
- float2 shiftedCoord : TEXCOORD1;
-};
-
-StyledPSInput VS_StyledText(VSInput input)
-{
- StyledPSInput result;
- result.position = mul(mvp, floor(input.position * dpr + 0.5) / dpr);
- result.coord = input.coord * textureScale;
- result.shiftedCoord = (input.coord - shift) * textureScale;
- return result;
-}
-
-float4 PS_StyledText(StyledPSInput input) : SV_TARGET
-{
- float glyph = tex.Sample(samp, input.coord).r;
- float style = clamp(tex.Sample(samp, input.shiftedCoord).r - glyph, 0.0, 1.0);
- return style * styleColor + glyph * colorVec;
-}
-
-struct OutlinedPSInput
-{
- float4 position : SV_POSITION;
- float2 coord : TEXCOORD0;
- float2 coordUp : TEXCOORD1;
- float2 coordDown : TEXCOORD2;
- float2 coordLeft : TEXCOORD3;
- float2 coordRight : TEXCOORD4;
-};
-
-OutlinedPSInput VS_OutlinedText(VSInput input)
-{
- OutlinedPSInput result;
- result.position = mul(mvp, floor(input.position * dpr + 0.5) / dpr);
- result.coord = input.coord * textureScale;
- result.coordUp = (input.coord - float2(0.0, -1.0)) * textureScale;
- result.coordDown = (input.coord - float2(0.0, 1.0)) * textureScale;
- result.coordLeft = (input.coord - float2(-1.0, 0.0)) * textureScale;
- result.coordRight = (input.coord - float2(1.0, 0.0)) * textureScale;
- return result;
-}
-
-float4 PS_OutlinedText(OutlinedPSInput input) : SV_TARGET
-{
- float glyph = tex.Sample(samp, input.coord).r;
- float outline = clamp(clamp(tex.Sample(samp, input.coordUp).r
- + tex.Sample(samp, input.coordDown).r
- + tex.Sample(samp, input.coordLeft).r
- + tex.Sample(samp, input.coordRight).r, 0.0, 1.0) - glyph, 0.0, 1.0);
- return outline * styleColor + glyph * colorVec;
-}
diff --git a/src/quick/scenegraph/adaptations/d3d12/shaders/texture.hlsl b/src/quick/scenegraph/adaptations/d3d12/shaders/texture.hlsl
deleted file mode 100644
index 1ae6579e8d..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/shaders/texture.hlsl
+++ /dev/null
@@ -1,33 +0,0 @@
-struct VSInput
-{
- float4 position : POSITION;
- float2 coord : TEXCOORD0;
-};
-
-cbuffer ConstantBuffer : register(b0)
-{
- float4x4 mvp;
- float opacity;
-};
-
-struct PSInput
-{
- float4 position : SV_POSITION;
- float2 coord : TEXCOORD0;
-};
-
-Texture2D tex : register(t0);
-SamplerState samp : register(s0);
-
-PSInput VS_Texture(VSInput input)
-{
- PSInput result;
- result.position = mul(mvp, input.position);
- result.coord = input.coord;
- return result;
-}
-
-float4 PS_Texture(PSInput input) : SV_TARGET
-{
- return tex.Sample(samp, input.coord) * opacity;
-}
diff --git a/src/quick/scenegraph/adaptations/d3d12/shaders/vertexcolor.hlsl b/src/quick/scenegraph/adaptations/d3d12/shaders/vertexcolor.hlsl
deleted file mode 100644
index a0569bb5c1..0000000000
--- a/src/quick/scenegraph/adaptations/d3d12/shaders/vertexcolor.hlsl
+++ /dev/null
@@ -1,32 +0,0 @@
-struct VSInput
-{
- float4 position : POSITION;
- float4 color : COLOR;
-};
-
-cbuffer ConstantBuffer : register(b0)
-{
- float4x4 mvp;
- float opacity;
-};
-
-struct PSInput
-{
- float4 position : SV_POSITION;
- float4 color : COLOR;
-};
-
-PSInput VS_VertexColor(VSInput input)
-{
- PSInput result;
-
- result.position = mul(mvp, input.position);
- result.color = input.color * opacity;
-
- return result;
-}
-
-float4 PS_VertexColor(PSInput input) : SV_TARGET
-{
- return input.color;
-}
diff --git a/src/quick/scenegraph/qsgbasicglyphnode_p.h b/src/quick/scenegraph/qsgbasicglyphnode_p.h
index 6c6e1d7cc6..1d09367ea5 100644
--- a/src/quick/scenegraph/qsgbasicglyphnode_p.h
+++ b/src/quick/scenegraph/qsgbasicglyphnode_p.h
@@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE
class QSGMaterial;
-class QSGBasicGlyphNode: public QSGGlyphNode
+class Q_QUICK_PRIVATE_EXPORT QSGBasicGlyphNode: public QSGGlyphNode
{
public:
QSGBasicGlyphNode();
diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp
index 646798efe2..5a5a16e005 100644
--- a/src/quick/scenegraph/qsgcontextplugin.cpp
+++ b/src/quick/scenegraph/qsgcontextplugin.cpp
@@ -45,9 +45,6 @@
// Built-in adaptations
#include <QtQuick/private/qsgsoftwareadaptation_p.h>
-#ifdef QSG_D3D12
-#include <QtQuick/private/qsgd3d12adaptation_p.h>
-#endif
#ifndef QT_NO_OPENGL
#include <QtQuick/private/qsgdefaultcontext_p.h>
#endif
@@ -89,9 +86,6 @@ QSGAdaptionBackendData::QSGAdaptionBackendData()
{
// Fill in the table with the built-in adaptations.
builtIns.append(new QSGSoftwareAdaptation);
-#ifdef QSG_D3D12
- builtIns.append(new QSGD3D12Adaptation);
-#endif
}
Q_GLOBAL_STATIC(QSGAdaptionBackendData, qsg_adaptation_data)