aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h')
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h394
1 files changed, 394 insertions, 0 deletions
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h
new file mode 100644
index 0000000000..b30994fe0d
--- /dev/null
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h
@@ -0,0 +1,394 @@
+/****************************************************************************
+**
+** 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 <qsgrendererinterface.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;
+}
+
+const int QSGD3D12_MAX_TEXTURE_VIEWS = 8;
+
+struct QSGD3D12RootSignature
+{
+ int textureViewCount = 0;
+ QSGD3D12TextureView textureViews[QSGD3D12_MAX_TEXTURE_VIEWS];
+
+ bool operator==(const QSGD3D12RootSignature &other) const {
+ if (textureViewCount != other.textureViewCount)
+ return false;
+ for (int i = 0; i < textureViewCount; ++i)
+ if (!(textureViews[i] == other.textureViews[i]))
+ return false;
+ return true;
+ }
+};
+
+inline uint qHash(const QSGD3D12RootSignature &key, uint seed = 0)
+{
+ return key.textureViewCount + (key.textureViewCount > 0 ? qHash(key.textureViews[0], seed) : 0);
+}
+
+// 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);
+}
+
+const int QSGD3D12_MAX_INPUT_ELEMENTS = 8;
+
+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;
+
+ int inputElementCount = 0;
+ QSGD3D12InputElement inputElements[QSGD3D12_MAX_INPUT_ELEMENTS];
+
+ 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 {
+ bool eq = shaders == other.shaders
+ && inputElementCount == other.inputElementCount
+ && 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;
+ if (eq) {
+ for (int i = 0; i < inputElementCount; ++i) {
+ if (!(inputElements[i] == other.inputElements[i])) {
+ eq = false;
+ break;
+ }
+ }
+ }
+ return eq;
+ }
+};
+
+inline uint qHash(const QSGD3D12PipelineState &key, uint seed = 0)
+{
+ return qHash(key.shaders, seed) + key.inputElementCount
+ + 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 surfaceFormatSamples, bool alpha);
+ void releaseResources();
+ bool hasResources() const;
+ void setWindowSize(const QSize &size, float dpr);
+ WId window() const;
+ QSize windowSize() const;
+ float windowDevicePixelRatio() const;
+ uint windowSamples() const;
+
+ void beginFrame();
+ void endFrame();
+ void beginLayer();
+ void endLayer();
+ void invalidateCachedFrameState();
+ void restoreFrameState(bool minimal = false);
+
+ 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 {
+ TextureWithAlpha = 0x01,
+ TextureWithMipMaps = 0x02,
+ TextureAlways32Bit = 0x04
+ };
+ Q_DECLARE_FLAGS(TextureCreateFlags, TextureCreateFlag)
+
+ enum TextureUploadFlag {
+ TextureUploadAlways32Bit = 0x01
+ };
+ Q_DECLARE_FLAGS(TextureUploadFlags, TextureUploadFlag)
+
+ 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(), TextureUploadFlags flags = 0);
+ void queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos, TextureUploadFlags flags = 0);
+ void releaseTexture(uint id);
+ void useTexture(uint id);
+
+ uint genRenderTarget();
+ void createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, uint samples);
+ void releaseRenderTarget(uint id);
+ void useRenderTargetAsTexture(uint id);
+ uint activeRenderTarget() const;
+
+ QImage executeAndWaitReadbackRenderTarget(uint id = 0);
+
+ void simulateDeviceLoss();
+
+ void *getResource(QQuickWindow *window, QSGRendererInterface::Resource resource) const;
+
+private:
+ QSGD3D12EnginePrivate *d;
+ Q_DISABLE_COPY(QSGD3D12Engine)
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Engine::ClearFlags)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Engine::TextureCreateFlags)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Engine::TextureUploadFlags)
+
+QT_END_NAMESPACE
+
+#endif // QSGD3D12ENGINE_P_H