diff options
-rw-r--r-- | src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine.cpp | 54 | ||||
-rw-r--r-- | src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext.cpp | 1 | ||||
-rw-r--r-- | src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp | 6 | ||||
-rw-r--r-- | src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop.cpp | 40 | ||||
-rw-r--r-- | tests/manual/nodetypes/LotsOfRects.qml | 250 | ||||
-rw-r--r-- | tests/manual/nodetypes/main.qml | 2 | ||||
-rw-r--r-- | tests/manual/nodetypes/nodetypes.cpp | 1 | ||||
-rw-r--r-- | tests/manual/nodetypes/nodetypes.qrc | 1 |
8 files changed, 325 insertions, 30 deletions
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine.cpp index db452810c0..6b7e01726e 100644 --- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine.cpp +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine.cpp @@ -44,6 +44,14 @@ 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) + // Recommended reading before moving further: https://github.com/Microsoft/DirectXTK/wiki/ComPtr // Note esp. operator= vs. Attach and operator& vs. GetAddressOf @@ -80,7 +88,8 @@ QSGD3D12DescriptorHandle QSGD3D12DescriptorHeapManager::allocate(D3D12_DESCRIPTO } heap.start.cpu = heap.heap->GetCPUDescriptorHandleForHeapStart(); - qDebug("type %x start is %llu", type, heap.start.cpu.ptr); + if (Q_UNLIKELY(debug_render())) + qDebug("type %x start is %llu", type, heap.start.cpu.ptr); if (flags & ShaderVisible) heap.start.gpu = heap.heap->GetGPUDescriptorHandleForHeapStart(); @@ -162,7 +171,8 @@ ID3D12Device *QSGD3D12DeviceManager::ref() void QSGD3D12DeviceManager::unref() { if (!m_ref.deref()) { - qDebug("destroying d3d device"); + if (Q_UNLIKELY(debug_render())) + qDebug("destroying d3d device"); m_device = nullptr; m_factory = nullptr; } @@ -600,7 +610,8 @@ void QSGD3D12EnginePrivate::resize() if (!initialized) return; - qDebug() << window->size(); + if (Q_UNLIKELY(debug_render())) + qDebug() << window->size(); // Clear these, otherwise resizing will fail. depthStencil = nullptr; @@ -710,9 +721,11 @@ D3D12_CPU_DESCRIPTOR_HANDLE QSGD3D12EnginePrivate::backBufferRTV() const void QSGD3D12EnginePrivate::beginFrame() { - static int cnt = 0; - qDebug() << "***** begin frame" << cnt; - ++cnt; + if (Q_UNLIKELY(debug_render())) { + static int cnt = 0; + qDebug() << "***** begin frame" << cnt; + ++cnt; + } // The device may have been lost. This is the point to attempt to start again from scratch. if (!initialized && window) @@ -737,7 +750,8 @@ void QSGD3D12EnginePrivate::updateBuffer(StagingBufferRef *br, ID3D12Resource *r return; } for (const auto &r : qAsConst(br->dirty)) { - qDebug("%s o %d s %d", dbgstr, r.first, r.second); + if (Q_UNLIKELY(debug_render())) + qDebug("%s o %d s %d", dbgstr, r.first, r.second); memcpy(p + r.first, br->p + r.first, r.second); } r->Unmap(0, nullptr); @@ -747,7 +761,8 @@ void QSGD3D12EnginePrivate::updateBuffer(StagingBufferRef *br, ID3D12Resource *r void QSGD3D12EnginePrivate::endFrame() { - qDebug() << "***** end frame"; + if (Q_UNLIKELY(debug_render())) + qDebug() << "***** end frame"; // Now is the time to sync all the changed areas in the buffers. updateBuffer(&vertexData, vertexBuffer.Get(), "vertex"); @@ -801,7 +816,9 @@ void QSGD3D12EnginePrivate::setPipelineState(const QSGD3D12PipelineState &pipeli ComPtr<ID3D12PipelineState> pso = m_psoCache[pipelineState]; if (!pso) { - qDebug("NEW PSO"); + if (Q_UNLIKELY(debug_render())) + qDebug("NEW PSO"); + D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; D3D12_INPUT_ELEMENT_DESC inputElements[8]; @@ -814,7 +831,8 @@ void QSGD3D12EnginePrivate::setPipelineState(const QSGD3D12PipelineState &pipeli ieDesc.InputSlot = ie.slot; ieDesc.AlignedByteOffset = ie.offset; ieDesc.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA; - qDebug("input [%d]: %s %d 0x%x %d", ieIdx, ie.name, ie.offset, ie.format, ie.slot); + if (Q_UNLIKELY(debug_render())) + qDebug("input [%d]: %s %d 0x%x %d", ieIdx, ie.name, ie.offset, ie.format, ie.slot); inputElements[ieIdx++] = ieDesc; } @@ -968,7 +986,8 @@ void QSGD3D12EnginePrivate::queueDraw(QSGGeometry::DrawingMode mode, int count, // Only enlarge, never shrink const bool newBufferNeeded = vertexBuffer ? (vertexData.size > vertexBuffer->GetDesc().Width) : true; if (newBufferNeeded) { - qDebug("new vertex buffer of size %d", vertexData.size); + if (Q_UNLIKELY(debug_render())) + qDebug("new vertex buffer of size %d", vertexData.size); vertexBuffer.Attach(createBuffer(vertexData.size)); } vertexData.dirty.clear(); @@ -983,7 +1002,8 @@ void QSGD3D12EnginePrivate::queueDraw(QSGGeometry::DrawingMode mode, int count, if (indexData.size > 0) { const bool newBufferNeeded = indexBuffer ? (indexData.size > indexBuffer->GetDesc().Width) : true; if (newBufferNeeded) { - qDebug("new index buffer of size %d", indexData.size); + if (Q_UNLIKELY(debug_render())) + qDebug("new index buffer of size %d", indexData.size); indexBuffer.Attach(createBuffer(indexData.size)); } indexData.dirty.clear(); @@ -1000,7 +1020,8 @@ void QSGD3D12EnginePrivate::queueDraw(QSGGeometry::DrawingMode mode, int count, constantData.fullChange = false; const bool newBufferNeeded = constantBuffer ? (constantData.size > constantBuffer->GetDesc().Width) : true; if (newBufferNeeded) { - qDebug("new constant buffer of size %d", constantData.size); + if (Q_UNLIKELY(debug_render())) + qDebug("new constant buffer of size %d", constantData.size); constantBuffer.Attach(createBuffer(constantData.size)); } constantData.dirty.clear(); @@ -1071,7 +1092,8 @@ void QSGD3D12EnginePrivate::present() if (!initialized) return; - qDebug("--- present with vsync ---"); + if (Q_UNLIKELY(debug_render())) + qDebug("--- present with vsync ---"); HRESULT hr = swapChain->Present(1, 0); if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) { @@ -1088,7 +1110,9 @@ void QSGD3D12EnginePrivate::waitGPU() if (!initialized) return; - qDebug("--- blocking wait for GPU ---"); + if (Q_UNLIKELY(debug_render())) + qDebug("--- blocking wait for GPU ---"); + waitForGPU(presentFence); } diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext.cpp index a9dea49200..4c002fcc6a 100644 --- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext.cpp +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext.cpp @@ -45,7 +45,6 @@ QT_BEGIN_NAMESPACE QSGD3D12RenderContext::QSGD3D12RenderContext(QSGContext *ctx) : QSGRenderContext(ctx) { - qDebug("new d3d12 render context"); } void QSGD3D12RenderContext::initialize(QOpenGLContext *) diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp index 589b363f59..6d0910c5ae 100644 --- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp @@ -50,6 +50,8 @@ 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; } @@ -458,7 +460,9 @@ void QSGD3D12Renderer::renderElement(int elementIndex) if (e.cboSize > 0) cboPtr = m_cboData.data() + e.cboOffset; - qDebug() << "dirtystate for" << e.node << "is" << dirtyState; + if (Q_UNLIKELY(debug_render())) + qDebug() << "dirty state for" << e.node << "is" << dirtyState; + QSGD3D12Material::UpdateResults updRes = m->updatePipeline(QSGD3D12Material::makeRenderState(this, dirtyState), &m_pipelineState.shaders, cboPtr); diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop.cpp index e0ee5e02dd..6c7b546c95 100644 --- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop.cpp +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop.cpp @@ -47,9 +47,19 @@ 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) + QSGD3D12RenderLoop::QSGD3D12RenderLoop() { - qDebug("new d3d12 render loop"); + if (Q_UNLIKELY(debug_render())) + qDebug("new d3d12 render loop"); + sg = new QSGD3D12Context; rc = new QSGD3D12RenderContext(sg); } @@ -62,7 +72,8 @@ QSGD3D12RenderLoop::~QSGD3D12RenderLoop() void QSGD3D12RenderLoop::show(QQuickWindow *window) { - qDebug() << "show" << window; + if (Q_UNLIKELY(debug_render())) + qDebug() << "show" << window; WindowData data; data.engine = new QSGD3D12Engine; @@ -75,7 +86,8 @@ void QSGD3D12RenderLoop::show(QQuickWindow *window) void QSGD3D12RenderLoop::hide(QQuickWindow *window) { - qDebug() << "hide" << window; + if (Q_UNLIKELY(debug_render())) + qDebug() << "hide" << window; QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window); wd->fireAboutToStop(); @@ -86,7 +98,8 @@ void QSGD3D12RenderLoop::resize(QQuickWindow *window) if (!window->isExposed() || window->size().isEmpty()) return; - qDebug() << "resize" << window; + if (Q_UNLIKELY(debug_render())) + qDebug() << "resize" << window; WindowData &data(m_windows[window]); if (data.engine) @@ -95,7 +108,8 @@ void QSGD3D12RenderLoop::resize(QQuickWindow *window) void QSGD3D12RenderLoop::windowDestroyed(QQuickWindow *window) { - qDebug() << "window destroyed" << window; + if (Q_UNLIKELY(debug_render())) + qDebug() << "window destroyed" << window; WindowData &data(m_windows[window]); delete data.engine; @@ -114,7 +128,8 @@ void QSGD3D12RenderLoop::windowDestroyed(QQuickWindow *window) void QSGD3D12RenderLoop::exposureChanged(QQuickWindow *window) { - qDebug() << "exposure changed" << window; + if (Q_UNLIKELY(debug_render())) + qDebug() << "exposure changed" << window; if (window->isExposed()) { m_windows[window].updatePending = true; @@ -131,8 +146,6 @@ QImage QSGD3D12RenderLoop::grab(QQuickWindow *window) void QSGD3D12RenderLoop::update(QQuickWindow *window) { - //qDebug() << "update" << window; - if (!m_windows.contains(window)) return; @@ -142,15 +155,14 @@ void QSGD3D12RenderLoop::update(QQuickWindow *window) void QSGD3D12RenderLoop::maybeUpdate(QQuickWindow *window) { - //qDebug() << "maybeUpdate" << window; - update(window); } // called in response to window->requestUpdate() void QSGD3D12RenderLoop::handleUpdateRequest(QQuickWindow *window) { - qDebug() << "handleUpdateRequest" << window; + if (Q_UNLIKELY(debug_render())) + qDebug() << "handleUpdateRequest" << window; renderWindow(window); } @@ -172,7 +184,8 @@ QSGRenderContext *QSGD3D12RenderLoop::createRenderContext(QSGContext *) const void QSGD3D12RenderLoop::releaseResources(QQuickWindow *window) { - qDebug() << "releaseResources" << window; + if (Q_UNLIKELY(debug_render())) + qDebug() << "releaseResources" << window; } void QSGD3D12RenderLoop::postJob(QQuickWindow *window, QRunnable *job) @@ -189,7 +202,8 @@ QSurface::SurfaceType QSGD3D12RenderLoop::windowSurfaceType() const void QSGD3D12RenderLoop::renderWindow(QQuickWindow *window) { - qDebug() << "renderWindow" << window; + if (Q_UNLIKELY(debug_render())) + qDebug() << "renderWindow" << window; QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window); if (!wd->isRenderable() || !m_windows.contains(window)) diff --git a/tests/manual/nodetypes/LotsOfRects.qml b/tests/manual/nodetypes/LotsOfRects.qml new file mode 100644 index 0000000000..46a05a2453 --- /dev/null +++ b/tests/manual/nodetypes/LotsOfRects.qml @@ -0,0 +1,250 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + Rectangle { + anchors.margins: 4 + anchors.fill: parent + + // Background + gradient: Gradient { + GradientStop { position: 0; color: "steelblue" } + GradientStop { position: 1; color: "black" } + } + + // Animated gradient stops. + // NB! Causes a full buffer rebuild on every animated change due to the geometry change! + Row { + spacing: 10 + Repeater { + model: 20 + Rectangle { + width: 20 + height: 20 + gradient: Gradient { + GradientStop { position: 0.0; color: "red" } + GradientStop { NumberAnimation on position { from: 0.01; to: 0.99; duration: 5000; loops: Animation.Infinite } color: "yellow" } + GradientStop { position: 1.0; color: "green" } + } + } + } + } + + // Rounded rects with border (smooth material) + Row { + spacing: 10 + Repeater { + model: 5 + Rectangle { + color: "blue" + width: 100 + height: 50 + y: 50 + radius: 16 + border.color: "red" + border.width: 4 + + SequentialAnimation on y { + loops: Animation.Infinite + NumberAnimation { + from: 50 + to: 150 + duration: 7000 + } + NumberAnimation { + from: 150 + to: 50 + duration: 3000 + } + } + } + } + } + + // Clip using scissor + Row { + spacing: 10 + Repeater { + model: 5 + Rectangle { + color: "green" + width: 100 + height: 100 + y: 150 + NumberAnimation on y { + from: 150 + to: 200 + duration: 2000 + loops: Animation.Infinite + } + clip: true + Rectangle { + color: "lightGreen" + width: 50 + height: 50 + x: 75 + y: 75 + } + } + } + } + + // Clip using scissor + Row { + spacing: 10 + Repeater { + model: 5 + Rectangle { + color: "green" + width: 100 + height: 100 + y: 300 + NumberAnimation on y { + from: 300 + to: 400 + duration: 2000 + loops: Animation.Infinite + } + clip: true + Rectangle { + color: "lightGreen" + width: 50 + height: 50 + x: 75 + y: 75 + NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } + } + } + } + } + + // Clip using stencil + Row { + spacing: 10 + Repeater { + model: 5 + Rectangle { + color: "green" + width: 100 + height: 100 + y: 450 + NumberAnimation on y { + from: 450 + to: 550 + duration: 2000 + loops: Animation.Infinite + } + NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } + clip: true + Rectangle { + color: "lightGreen" + width: 50 + height: 50 + x: 75 + y: 75 + } + } + } + } + + // The signature red square with another item with animated opacity blended on top + Rectangle { + width: 100 + height: 100 + anchors.centerIn: parent + color: "red" + NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } + + Rectangle { + color: "gray" + width: 50 + height: 50 + anchors.centerIn: parent + + SequentialAnimation on opacity { + loops: Animation.Infinite + NumberAnimation { + from: 1.0 + to: 0.0 + duration: 4000 + } + NumberAnimation { + from: 0.0 + to: 1.0 + duration: 4000 + easing.type: Easing.InOutQuad + } + } + } + } + + // Animated size and color. + // NB! Causes a full buffer rebuild on every animated change due to the geometry change! + Rectangle { + anchors.right: parent.right + anchors.bottom: parent.bottom + width: 10 + height: 100 + ColorAnimation on color { + from: "blue" + to: "purple" + duration: 5000 + loops: Animation.Infinite + } + NumberAnimation on width { + from: 10 + to: 300 + duration: 5000 + loops: Animation.Infinite + } + } + + // Semi-transparent rect on top. + Rectangle { + anchors.centerIn: parent + opacity: 0.2 + color: "black" + anchors.fill: parent + anchors.margins: 10 + } + } +} diff --git a/tests/manual/nodetypes/main.qml b/tests/manual/nodetypes/main.qml index 8e816fac28..3639b8c5b2 100644 --- a/tests/manual/nodetypes/main.qml +++ b/tests/manual/nodetypes/main.qml @@ -54,5 +54,7 @@ Item { if (event.key === Qt.Key_R) loader.source = "qrc:/Rects.qml"; + if (event.key === Qt.Key_4) + loader.source = "qrc:/LotsOfRects.qml"; } } diff --git a/tests/manual/nodetypes/nodetypes.cpp b/tests/manual/nodetypes/nodetypes.cpp index f1ad15a92d..bd9d1937d8 100644 --- a/tests/manual/nodetypes/nodetypes.cpp +++ b/tests/manual/nodetypes/nodetypes.cpp @@ -49,6 +49,7 @@ int main(int argc, char **argv) qDebug("Available tests:"); qDebug(" [R] - Rectangles"); + qDebug(" [4] - A lot of rectangles (perf)"); qDebug("\nPress S to stop the currently running test\n"); QQuickView view; diff --git a/tests/manual/nodetypes/nodetypes.qrc b/tests/manual/nodetypes/nodetypes.qrc index ce582ab75a..d942ee2396 100644 --- a/tests/manual/nodetypes/nodetypes.qrc +++ b/tests/manual/nodetypes/nodetypes.qrc @@ -2,5 +2,6 @@ <qresource prefix="/"> <file>main.qml</file> <file>Rects.qml</file> + <file>LotsOfRects.qml</file> </qresource> </RCC> |