diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-04-23 09:40:59 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-07-04 10:44:26 +0200 |
commit | 341ab7708049b1a3f559b76f16393e688951a938 (patch) | |
tree | 0203da53d1adf5025fa85ecc38e0e37bce35c46f /src/plugins | |
parent | 1f01b44d20471a7f4a5029a4c0049e8296749fef (diff) |
Add the graphics api independent scenegraph port
Opt in via environment variables:
QSG_RHI=1 -> enable using QRhi instead of GL
QSG_RHI_BACKEND -> set to vulkan, metal, d3d11, gl to override the default
(the default is d3d11 on Windows, metal on Mac, gl elsewhere)
Or force a given rhi backend via the existing
QQuickWindow::setSceneGraphBackend().
Otherwise the default behavior is the same as before, the rhi code path
is never active by default.
-no-opengl builds are supported in the sense that they work and default
to the software backend. However, the rhi code path cannot currently be
used in such builds, even though QRhi from qtbase is fully functional
with Vulkan, D3D, or Metal even when qtbase was configured with
-no-opengl. This cannot be utilized by Quick atm due to OpenGL usage
being all over the place in the sources corresponding to the default
backend, and those host the rhi code path as well. This will be cleaned up
hopefully in Qt 6, with the removal all direct OpenGL usage.
Other env.vars.:
QSG_RHI_DEBUG_LAYER=1 -> enable D3D debug or Vulkan validation layer
(assuming the system is set up for this)
QSG_RHI_SHADEREFFECT_DEBUG=1 -> print stuff from ShaderEffect
QSG_SAMPLES=1,2,4,... -> MSAA sample count (but QSurfaceFormat works too)
QT_D3D_ADAPTER_INDEX=0,1,... -> D3D adapter index
QT_VK_PHYSICAL_DEVICE_INDEX=0,1,... -> Vulkan physical device index
QSG_RHI_UINT32_INDEX=1 -> always use uint index data (both
merged/unmerged, convert when needed - with some rhi backends this is
implicit)
QSG_RENDER_LOOP -> to override the render loop as usual. The default
with RHI is threaded for Metal, threaded for Vulkan on Windows, basic
for Vulkan on Linux and Android (to be checked later), while the existing
rules apply for OpenGL.
Not supported when running with QRhi:
- particles
- compressed atlases (though this is transparent to the apps)
- QSGRenderNode
- QQuickRenderControl
- QQuickFramebufferObject
- certain QQuickWindow functionality that depends directly on OpenGL
- anisotropic filtering for textures
- native text may lack some gamma correction
- QSGEngine applicability unclear
- some QML profiler logs may be incorrect or irrelevant
Change-Id: I7822e99ad79e342e4166275da6e9e66498d76521
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/plugins')
10 files changed, 47 insertions, 61 deletions
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12context.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12context.cpp index 9b88af995d..f9bd04aa54 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12context.cpp +++ b/src/plugins/scenegraph/d3d12/qsgd3d12context.cpp @@ -61,8 +61,9 @@ QSGInternalRectangleNode *QSGD3D12Context::createInternalRectangleNode() return new QSGD3D12InternalRectangleNode; } -QSGInternalImageNode *QSGD3D12Context::createInternalImageNode() +QSGInternalImageNode *QSGD3D12Context::createInternalImageNode(QSGRenderContext *renderContext) { + Q_UNUSED(renderContext); return new QSGD3D12InternalImageNode; } diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12context_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12context_p.h index 70cc606b52..382183fef6 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12context_p.h +++ b/src/plugins/scenegraph/d3d12/qsgd3d12context_p.h @@ -62,7 +62,7 @@ public: QSGRenderContext *createRenderContext() override; QSGInternalRectangleNode *createInternalRectangleNode() override; - QSGInternalImageNode *createInternalImageNode() override; + QSGInternalImageNode *createInternalImageNode(QSGRenderContext *renderContext) override; QSGPainterNode *createPainterNode(QQuickPaintedItem *item) override; QSGGlyphNode *createGlyphNode(QSGRenderContext *renderContext, bool preferNativeGlyphNode) override; QSGLayer *createLayer(QSGRenderContext *renderContext) override; diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12layer.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12layer.cpp index faa6f7566a..b9d3a180cf 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12layer.cpp +++ b/src/plugins/scenegraph/d3d12/qsgd3d12layer.cpp @@ -53,7 +53,8 @@ QT_BEGIN_NAMESPACE DECLARE_DEBUG_VAR(render) QSGD3D12Layer::QSGD3D12Layer(QSGD3D12RenderContext *rc) - : m_rc(rc) + : QSGLayer(*(new QSGD3D12LayerPrivate)), + m_rc(rc) { if (Q_UNLIKELY(debug_render())) qDebug("new layer %p", this); @@ -74,6 +75,12 @@ int QSGD3D12Layer::textureId() const return m_rt; // not a texture id per se but will do } +int QSGD3D12LayerPrivate::comparisonKey() const +{ + Q_Q(const QSGD3D12Layer); + return q->m_rt; +} + QSize QSGD3D12Layer::textureSize() const { return m_size; diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12layer_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12layer_p.h index f828843227..42a56877cf 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12layer_p.h +++ b/src/plugins/scenegraph/d3d12/qsgd3d12layer_p.h @@ -52,13 +52,16 @@ // #include <private/qsgadaptationlayer_p.h> +#include <private/qsgtexture_p.h> QT_BEGIN_NAMESPACE class QSGD3D12RenderContext; +class QSGD3D12LayerPrivate; class QSGD3D12Layer : public QSGLayer { + Q_DECLARE_PRIVATE(QSGD3D12Layer) Q_OBJECT public: @@ -114,6 +117,13 @@ private: bool m_updateContentPending = false; }; +class QSGD3D12LayerPrivate : public QSGTexturePrivate +{ + Q_DECLARE_PUBLIC(QSGD3D12Layer) +public: + int comparisonKey() const override; +}; + QT_END_NAMESPACE #endif // QSGD3D12LAYER_P_H diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext.cpp index 4ee4656e63..48693207c6 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext.cpp +++ b/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext.cpp @@ -64,7 +64,7 @@ bool QSGD3D12RenderContext::isValid() const return m_engine != nullptr; } -void QSGD3D12RenderContext::initialize(void *) +void QSGD3D12RenderContext::initialize(const InitParams *) { if (m_initialized) return; diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext_p.h index 35aca100f4..c555c0808e 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext_p.h +++ b/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext_p.h @@ -63,7 +63,7 @@ class QSGD3D12RenderContext : public QSGRenderContext, public QSGRendererInterfa public: QSGD3D12RenderContext(QSGContext *ctx); bool isValid() const override; - void initialize(void *context) override; + void initialize(const InitParams *params) override; void invalidate() override; void renderNextFrame(QSGRenderer *renderer, uint fbo) override; QSGTexture *createTexture(const QImage &image, uint flags) const override; diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp index b4fb721a8b..1f574a9802 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp +++ b/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp @@ -78,32 +78,6 @@ void QSGD3D12ShaderLinker::reset(const QByteArray &vertBlob, const QByteArray &f textureNameMap.clear(); } -void QSGD3D12ShaderLinker::feedVertexInput(const QSGShaderEffectNode::ShaderData &shader) -{ - bool foundPos = false, foundTexCoord = false; - - for (const auto &ip : qAsConst(shader.shaderInfo.inputParameters)) { - if (ip.semanticName == QByteArrayLiteral("POSITION")) - foundPos = true; - else if (ip.semanticName == QByteArrayLiteral("TEXCOORD")) - foundTexCoord = true; - } - - if (!foundPos) { - qWarning("ShaderEffect: No POSITION input found."); - error = true; - } - if (!foundTexCoord) { - qWarning("ShaderEffect: No TEXCOORD input found."); - error = true; - } - - // Nothing else to do here, the QSGGeometry::AttributeSet decides anyway - // and that is already generated by QQuickShaderEffectMesh via - // QSGGeometry::defaultAttributes_TexturedPoint2D() and has the semantics - // so it will just work. -} - void QSGD3D12ShaderLinker::feedConstants(const QSGShaderEffectNode::ShaderData &shader, const QSet<int> *dirtyIndices) { Q_ASSERT(shader.shaderInfo.variables.count() == shader.varData.count()); @@ -634,19 +608,12 @@ void QSGD3D12ShaderEffectNode::syncMaterial(SyncData *syncData) m_material.linker.reset(vertBlob, fragBlob); if (m_material.hasCustomVertexShader) { - m_material.linker.feedVertexInput(*syncData->vertex.shader); m_material.linker.feedConstants(*syncData->vertex.shader); } else { QSGShaderEffectNode::ShaderData defaultSD; defaultSD.shaderInfo.blob = vertBlob; defaultSD.shaderInfo.type = QSGGuiThreadShaderEffectManager::ShaderInfo::TypeVertex; - QSGGuiThreadShaderEffectManager::ShaderInfo::InputParameter ip; - ip.semanticName = QByteArrayLiteral("POSITION"); - defaultSD.shaderInfo.inputParameters.append(ip); - ip.semanticName = QByteArrayLiteral("TEXCOORD"); - defaultSD.shaderInfo.inputParameters.append(ip); - // { float4x4 qt_Matrix; float qt_Opacity; } where only the matrix is used QSGGuiThreadShaderEffectManager::ShaderInfo::Variable v; v.name = QByteArrayLiteral("qt_Matrix"); @@ -656,10 +623,7 @@ void QSGD3D12ShaderEffectNode::syncMaterial(SyncData *syncData) QSGShaderEffectNode::VariableData vd; vd.specialType = QSGShaderEffectNode::VariableData::Matrix; defaultSD.varData.append(vd); - defaultSD.shaderInfo.constantDataSize = (16 + 1) * sizeof(float); - - m_material.linker.feedVertexInput(defaultSD); m_material.linker.feedConstants(defaultSD); } @@ -943,20 +907,6 @@ bool QSGD3D12GuiThreadShaderEffectManager::reflect(ShaderInfo *result) qDebug("Shader reflection size %d type %d v%u.%u input elems %d cbuffers %d boundres %d", result->blob.size(), result->type, major, minor, ieCount, cbufferCount, boundResCount); - for (int i = 0; i < ieCount; ++i) { - D3D12_SIGNATURE_PARAMETER_DESC desc; - if (FAILED(reflector->GetInputParameterDesc(i, &desc))) { - qWarning("D3D reflection: Failed to query input parameter %d", i); - return false; - } - if (desc.SystemValueType != D3D_NAME_UNDEFINED) - continue; - ShaderInfo::InputParameter param; - param.semanticName = QByteArray(desc.SemanticName); - param.semanticIndex = desc.SemanticIndex; - result->inputParameters.append(param); - } - for (int i = 0; i < boundResCount; ++i) { D3D12_SHADER_INPUT_BIND_DESC desc; if (FAILED(reflector->GetResourceBindingDesc(i, &desc))) { @@ -1036,10 +986,8 @@ bool QSGD3D12GuiThreadShaderEffectManager::reflect(ShaderInfo *result) } } - if (Q_UNLIKELY(debug_shader())) { - qDebug() << "Input:" << result->inputParameters; + if (Q_UNLIKELY(debug_shader())) qDebug() << "Variables:" << result->variables << "cbuffer size" << result->constantDataSize; - } return true; } diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode_p.h index ee17e59130..dec85fd782 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode_p.h +++ b/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode_p.h @@ -67,7 +67,6 @@ class QSGD3D12ShaderLinker public: void reset(const QByteArray &vertBlob, const QByteArray &fragBlob); - void feedVertexInput(const QSGShaderEffectNode::ShaderData &shader); void feedConstants(const QSGShaderEffectNode::ShaderData &shader, const QSet<int> *dirtyIndices = nullptr); void feedSamplers(const QSGShaderEffectNode::ShaderData &shader); void feedTextures(const QSGShaderEffectNode::ShaderData &shader, const QSet<int> *dirtyIndices = nullptr); diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12texture.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12texture.cpp index a5f3eb7a31..b49b851c23 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12texture.cpp +++ b/src/plugins/scenegraph/d3d12/qsgd3d12texture.cpp @@ -69,6 +69,12 @@ void QSGD3D12Texture::create(const QImage &image, uint flags) m_createPending = true; } +QSGD3D12Texture::QSGD3D12Texture(QSGD3D12Engine *engine) + : QSGTexture(*(new QSGD3D12TexturePrivate)), + m_engine(engine) +{ +} + QSGD3D12Texture::~QSGD3D12Texture() { if (m_id) @@ -80,6 +86,12 @@ int QSGD3D12Texture::textureId() const return m_id; } +int QSGD3D12TexturePrivate::comparisonKey() const +{ + Q_Q(const QSGD3D12Texture); + return q->m_id; +} + QSize QSGD3D12Texture::textureSize() const { return m_image.size(); diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12texture_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12texture_p.h index 3d0e226ddb..f6a5257773 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12texture_p.h +++ b/src/plugins/scenegraph/d3d12/qsgd3d12texture_p.h @@ -51,17 +51,19 @@ // We mean it. // -#include <qsgtexture.h> +#include <private/qsgtexture_p.h> #include <basetsd.h> QT_BEGIN_NAMESPACE class QSGD3D12Engine; +class QSGD3D12TexturePrivate; class QSGD3D12Texture : public QSGTexture { + Q_DECLARE_PRIVATE(QSGD3D12Texture) public: - QSGD3D12Texture(QSGD3D12Engine *engine) : m_engine(engine) { } + QSGD3D12Texture(QSGD3D12Engine *engine); ~QSGD3D12Texture(); void create(const QImage &image, uint flags); @@ -82,6 +84,13 @@ protected: bool m_alphaWanted = false; }; +class QSGD3D12TexturePrivate : public QSGTexturePrivate +{ + Q_DECLARE_PUBLIC(QSGD3D12Texture) +public: + int comparisonKey() const override; +}; + QT_END_NAMESPACE #endif |