diff options
Diffstat (limited to 'tests/manual/rhi')
105 files changed, 1458 insertions, 126 deletions
diff --git a/tests/manual/rhi/CMakeLists.txt b/tests/manual/rhi/CMakeLists.txt index ab4093e9a6..8f48bf219d 100644 --- a/tests/manual/rhi/CMakeLists.txt +++ b/tests/manual/rhi/CMakeLists.txt @@ -32,6 +32,8 @@ add_subdirectory(stereo) add_subdirectory(tex1d) add_subdirectory(displacement) add_subdirectory(imguirenderer) +add_subdirectory(multiview) +add_subdirectory(msaatextureresolve) if(QT_FEATURE_widgets) - add_subdirectory(rhiwidget) + add_subdirectory(rhiwidgetproto) endif() diff --git a/tests/manual/rhi/compressedtexture_bc1/compressedtexture_bc1.cpp b/tests/manual/rhi/compressedtexture_bc1/compressedtexture_bc1.cpp index 146a414924..80eb63783e 100644 --- a/tests/manual/rhi/compressedtexture_bc1/compressedtexture_bc1.cpp +++ b/tests/manual/rhi/compressedtexture_bc1/compressedtexture_bc1.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" #include "../shared/cube.h" diff --git a/tests/manual/rhi/compressedtexture_bc1_subupload/compressedtexture_bc1_subupload.cpp b/tests/manual/rhi/compressedtexture_bc1_subupload/compressedtexture_bc1_subupload.cpp index a916cd7742..a98744afc0 100644 --- a/tests/manual/rhi/compressedtexture_bc1_subupload/compressedtexture_bc1_subupload.cpp +++ b/tests/manual/rhi/compressedtexture_bc1_subupload/compressedtexture_bc1_subupload.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" #include "../shared/cube.h" diff --git a/tests/manual/rhi/computebuffer/buildshaders.bat b/tests/manual/rhi/computebuffer/buildshaders.bat index 2768273b70..07a602e18b 100755 --- a/tests/manual/rhi/computebuffer/buildshaders.bat +++ b/tests/manual/rhi/computebuffer/buildshaders.bat @@ -1,3 +1,5 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 qsb --glsl "310 es,430" --hlsl 50 --msl 12 buffer.comp -o buffer.comp.qsb qsb --glsl "310 es,430" --hlsl 50 --msl 12 main.vert -o main.vert.qsb qsb --glsl "310 es,430" --hlsl 50 --msl 12 main.frag -o main.frag.qsb diff --git a/tests/manual/rhi/computebuffer/computebuffer.cpp b/tests/manual/rhi/computebuffer/computebuffer.cpp index bb5149bdb9..a54c0817b4 100644 --- a/tests/manual/rhi/computebuffer/computebuffer.cpp +++ b/tests/manual/rhi/computebuffer/computebuffer.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" #include <QRandomGenerator> diff --git a/tests/manual/rhi/computeimage/buildshaders.bat b/tests/manual/rhi/computeimage/buildshaders.bat index 41a324d2b2..253d05b625 100755 --- a/tests/manual/rhi/computeimage/buildshaders.bat +++ b/tests/manual/rhi/computeimage/buildshaders.bat @@ -1 +1,3 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only qsb --glsl "310 es,430" --hlsl 50 --msl 12 image.comp -o image.comp.qsb diff --git a/tests/manual/rhi/computeimage/computeimage.cpp b/tests/manual/rhi/computeimage/computeimage.cpp index c7414a0236..5da68e4a18 100644 --- a/tests/manual/rhi/computeimage/computeimage.cpp +++ b/tests/manual/rhi/computeimage/computeimage.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" diff --git a/tests/manual/rhi/cubemap/buildshaders.bat b/tests/manual/rhi/cubemap/buildshaders.bat index ebf673875d..314559490f 100644 --- a/tests/manual/rhi/cubemap/buildshaders.bat +++ b/tests/manual/rhi/cubemap/buildshaders.bat @@ -1,2 +1,4 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 qsb --glsl "100 es,120" --hlsl 50 --msl 12 -c cubemap.vert -o cubemap.vert.qsb qsb --glsl "100 es,120" --hlsl 50 --msl 12 -c cubemap.frag -o cubemap.frag.qsb diff --git a/tests/manual/rhi/cubemap/cubemap.cpp b/tests/manual/rhi/cubemap/cubemap.cpp index 579da73633..bf027b49de 100644 --- a/tests/manual/rhi/cubemap/cubemap.cpp +++ b/tests/manual/rhi/cubemap/cubemap.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" #include "../shared/cube.h" diff --git a/tests/manual/rhi/cubemap_render/buildshaders.bat b/tests/manual/rhi/cubemap_render/buildshaders.bat index 3886c138d8..4bee01d8cd 100644 --- a/tests/manual/rhi/cubemap_render/buildshaders.bat +++ b/tests/manual/rhi/cubemap_render/buildshaders.bat @@ -1,3 +1,5 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 qsb --glsl "300 es,120" --hlsl 50 --msl 12 cubemap_oneface.vert -o cubemap_oneface.vert.qsb qsb --glsl "300 es,120" --hlsl 50 --msl 12 cubemap_oneface.frag -o cubemap_oneface.frag.qsb qsb --glsl "300 es,120" --hlsl 50 --msl 12 cubemap_mrt.vert -o cubemap_mrt.vert.qsb diff --git a/tests/manual/rhi/cubemap_render/cubemap_render.cpp b/tests/manual/rhi/cubemap_render/cubemap_render.cpp index ed01404e86..3eb013937f 100644 --- a/tests/manual/rhi/cubemap_render/cubemap_render.cpp +++ b/tests/manual/rhi/cubemap_render/cubemap_render.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only // Demonstrates rendering to two cubemaps in two different ways: // - one by one, to each face, diff --git a/tests/manual/rhi/cubemap_scissor/cubemap_scissor.cpp b/tests/manual/rhi/cubemap_scissor/cubemap_scissor.cpp index 8e69b48d40..78933830a1 100644 --- a/tests/manual/rhi/cubemap_scissor/cubemap_scissor.cpp +++ b/tests/manual/rhi/cubemap_scissor/cubemap_scissor.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only // This is a test for scissoring. Based on the cubemap test (because there the // rendering covers the entire viewport which is what we need here). The diff --git a/tests/manual/rhi/displacement/buildshaders.bat b/tests/manual/rhi/displacement/buildshaders.bat index 552277491d..95a51c0e91 100644 --- a/tests/manual/rhi/displacement/buildshaders.bat +++ b/tests/manual/rhi/displacement/buildshaders.bat @@ -1,3 +1,5 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 qsb --glsl 320es,410 --hlsl 50 --msl 12 --msltess material.vert -o material.vert.qsb qsb --glsl 320es,410 --hlsl 50 --msl 12 material.frag -o material.frag.qsb diff --git a/tests/manual/rhi/displacement/displacement.cpp b/tests/manual/rhi/displacement/displacement.cpp index 7a25133faf..680ffa0628 100644 --- a/tests/manual/rhi/displacement/displacement.cpp +++ b/tests/manual/rhi/displacement/displacement.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2023 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #define EXAMPLEFW_IMGUI #include "../shared/examplefw.h" diff --git a/tests/manual/rhi/float16texture_with_compute/buildshaders.bat b/tests/manual/rhi/float16texture_with_compute/buildshaders.bat index d1ffecf49d..15f39256c7 100644 --- a/tests/manual/rhi/float16texture_with_compute/buildshaders.bat +++ b/tests/manual/rhi/float16texture_with_compute/buildshaders.bat @@ -1,2 +1,4 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 qsb --glsl "430,310 es" --hlsl 50 --msl 12 load.comp -o load.comp.qsb qsb --glsl "430,310 es" --hlsl 50 --msl 12 prefilter.comp -o prefilter.comp.qsb diff --git a/tests/manual/rhi/float16texture_with_compute/float16texture_with_compute.cpp b/tests/manual/rhi/float16texture_with_compute/float16texture_with_compute.cpp index 44ec3c742e..6bf3d222b4 100644 --- a/tests/manual/rhi/float16texture_with_compute/float16texture_with_compute.cpp +++ b/tests/manual/rhi/float16texture_with_compute/float16texture_with_compute.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only // An advanced version of floattexture. Instead of RGBA32F, we use RGBA16F, and // also generate the floating point data from rgba with compute. Then there's a diff --git a/tests/manual/rhi/floattexture/floattexture.cpp b/tests/manual/rhi/floattexture/floattexture.cpp index d580f933d9..8cd41bcc58 100644 --- a/tests/manual/rhi/floattexture/floattexture.cpp +++ b/tests/manual/rhi/floattexture/floattexture.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" #include <qmath.h> diff --git a/tests/manual/rhi/geometryshader/buildshaders.bat b/tests/manual/rhi/geometryshader/buildshaders.bat index 6da26a6a2a..a3b7296e16 100755 --- a/tests/manual/rhi/geometryshader/buildshaders.bat +++ b/tests/manual/rhi/geometryshader/buildshaders.bat @@ -1,3 +1,5 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 qsb --glsl 320es,410 --hlsl 50 test.vert -o test.vert.qsb qsb --glsl 320es,410 test.geom -o test.geom.qsb qsb -r hlsl,50,test_geom.hlsl test.geom.qsb diff --git a/tests/manual/rhi/geometryshader/geometryshader.cpp b/tests/manual/rhi/geometryshader/geometryshader.cpp index 1025ee1eb4..e03f247e9f 100644 --- a/tests/manual/rhi/geometryshader/geometryshader.cpp +++ b/tests/manual/rhi/geometryshader/geometryshader.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2022 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" diff --git a/tests/manual/rhi/hdr/CMakeLists.txt b/tests/manual/rhi/hdr/CMakeLists.txt new file mode 100644 index 0000000000..dc7bcb906c --- /dev/null +++ b/tests/manual/rhi/hdr/CMakeLists.txt @@ -0,0 +1,22 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause +qt_internal_add_manual_test(hdr + GUI + SOURCES + hdr.cpp + LIBRARIES + Qt::Gui + Qt::GuiPrivate +) + +qt_internal_add_resource(hdr "hdr" + PREFIX + "/" + FILES + "hdrtexture.vert.qsb" + "hdrtexture.frag.qsb" +) + +set(imgui_base ../shared/imgui) +set(imgui_target hdr) +include(${imgui_base}/imgui.cmakeinc) diff --git a/tests/manual/rhi/hdr/buildshaders.bat b/tests/manual/rhi/hdr/buildshaders.bat new file mode 100644 index 0000000000..fdae5d0eb7 --- /dev/null +++ b/tests/manual/rhi/hdr/buildshaders.bat @@ -0,0 +1,4 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +qsb --qt6 hdrtexture.vert -o hdrtexture.vert.qsb +qsb --qt6 hdrtexture.frag -o hdrtexture.frag.qsb diff --git a/tests/manual/rhi/hdr/hdr.cpp b/tests/manual/rhi/hdr/hdr.cpp new file mode 100644 index 0000000000..1ea3b276de --- /dev/null +++ b/tests/manual/rhi/hdr/hdr.cpp @@ -0,0 +1,457 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +// Test application for HDR with scRGB. +// Launch with the argument "scrgb" or "sdr", perhaps side-by-side even. + +#define EXAMPLEFW_PREINIT +#define EXAMPLEFW_IMGUI +#include "../shared/examplefw.h" + +#include "../shared/cube.h" + +QByteArray loadHdr(const QString &fn, QSize *size) +{ + QFile f(fn); + if (!f.open(QIODevice::ReadOnly)) { + qWarning("Failed to open %s", qPrintable(fn)); + return QByteArray(); + } + + char sig[256]; + f.read(sig, 11); + if (strncmp(sig, "#?RADIANCE\n", 11)) + return QByteArray(); + + QByteArray buf = f.readAll(); + const char *p = buf.constData(); + const char *pEnd = p + buf.size(); + + // Process lines until the empty one. + QByteArray line; + while (p < pEnd) { + char c = *p++; + if (c == '\n') { + if (line.isEmpty()) + break; + if (line.startsWith(QByteArrayLiteral("FORMAT="))) { + const QByteArray format = line.mid(7).trimmed(); + if (format != QByteArrayLiteral("32-bit_rle_rgbe")) { + qWarning("HDR format '%s' is not supported", format.constData()); + return QByteArray(); + } + } + line.clear(); + } else { + line.append(c); + } + } + if (p == pEnd) { + qWarning("Malformed HDR image data at property strings"); + return QByteArray(); + } + + // Get the resolution string. + while (p < pEnd) { + char c = *p++; + if (c == '\n') + break; + line.append(c); + } + if (p == pEnd) { + qWarning("Malformed HDR image data at resolution string"); + return QByteArray(); + } + + int w = 0, h = 0; + // We only care about the standard orientation. + if (!sscanf(line.constData(), "-Y %d +X %d", &h, &w)) { + qWarning("Unsupported HDR resolution string '%s'", line.constData()); + return QByteArray(); + } + if (w <= 0 || h <= 0) { + qWarning("Invalid HDR resolution"); + return QByteArray(); + } + + // output is RGBA32F + const int blockSize = 4 * sizeof(float); + QByteArray data; + data.resize(w * h * blockSize); + + typedef unsigned char RGBE[4]; + RGBE *scanline = new RGBE[w]; + + for (int y = 0; y < h; ++y) { + if (pEnd - p < 4) { + qWarning("Unexpected end of HDR data"); + delete[] scanline; + return QByteArray(); + } + + scanline[0][0] = *p++; + scanline[0][1] = *p++; + scanline[0][2] = *p++; + scanline[0][3] = *p++; + + if (scanline[0][0] == 2 && scanline[0][1] == 2 && scanline[0][2] < 128) { + // new rle, the first pixel was a dummy + for (int channel = 0; channel < 4; ++channel) { + for (int x = 0; x < w && p < pEnd; ) { + unsigned char c = *p++; + if (c > 128) { // run + if (p < pEnd) { + int repCount = c & 127; + c = *p++; + while (repCount--) + scanline[x++][channel] = c; + } + } else { // not a run + while (c-- && p < pEnd) + scanline[x++][channel] = *p++; + } + } + } + } else { + // old rle + scanline[0][0] = 2; + int bitshift = 0; + int x = 1; + while (x < w && pEnd - p >= 4) { + scanline[x][0] = *p++; + scanline[x][1] = *p++; + scanline[x][2] = *p++; + scanline[x][3] = *p++; + + if (scanline[x][0] == 1 && scanline[x][1] == 1 && scanline[x][2] == 1) { // run + int repCount = scanline[x][3] << bitshift; + while (repCount--) { + memcpy(scanline[x], scanline[x - 1], 4); + ++x; + } + bitshift += 8; + } else { // not a run + ++x; + bitshift = 0; + } + } + } + + // adjust for -Y orientation + float *fp = reinterpret_cast<float *>(data.data() + (h - 1 - y) * blockSize * w); + for (int x = 0; x < w; ++x) { + float d = qPow(2.0f, float(scanline[x][3]) - 128.0f); + float r = scanline[x][0] / 256.0f * d; + float g = scanline[x][1] / 256.0f * d; + float b = scanline[x][2] / 256.0f * d; + float a = 1.0f; + *fp++ = r; + *fp++ = g; + *fp++ = b; + *fp++ = a; + } + } + + delete[] scanline; + + *size = QSize(w, h); + + return data; +} + +struct { + QMatrix4x4 winProj; + QList<QRhiResource *> releasePool; + QRhiResourceUpdateBatch *initialUpdates = nullptr; + QRhiBuffer *vbuf = nullptr; + QRhiBuffer *ubuf = nullptr; + QRhiTexture *tex = nullptr; + QRhiSampler *sampler = nullptr; + QRhiShaderResourceBindings *srb = nullptr; + QRhiGraphicsPipeline *ps = nullptr; + bool showDemoWindow = true; + QVector3D rotation; + + bool usingHDRWindow; + bool adjustSDR = false; + float SDRWhiteLevelInNits = 200.0f; + bool tonemapHDR = false; + float tonemapInMax = 2.5f; + float tonemapOutMax = 0.0f; + + QString imageFile; +} d; + +void preInit() +{ + QStringList args = QCoreApplication::arguments(); + if (args.contains("scrgb")) { + d.usingHDRWindow = true; + swapchainFormat = QRhiSwapChain::HDRExtendedSrgbLinear; + } else if (args.contains("p3")) { + d.usingHDRWindow = true; + swapchainFormat = QRhiSwapChain::HDRExtendedDisplayP3Linear; + } else if (args.contains("sdr")) { + d.usingHDRWindow = false; + swapchainFormat = QRhiSwapChain::SDR; + } else { + qFatal("Missing command line argument, specify scrgb or sdr"); + } + + if (args.contains("file")) { + d.imageFile = args[args.indexOf("file") + 1]; + qDebug("Using HDR image file %s", qPrintable(d.imageFile)); + } else { + qFatal("Missing command line argument, specify 'file' followed by a .hdr file. " + "Download for example the original .exr from https://viewer.openhdr.org/i/5fcb9a595812624a99d24c62/linear " + "and use ImageMagick's 'convert' to convert from .exr to .hdr"); + } +} + +void Window::customInit() +{ + if (!m_r->isTextureFormatSupported(QRhiTexture::RGBA32F)) + qWarning("RGBA32F texture format is not supported"); + + d.initialUpdates = m_r->nextResourceUpdateBatch(); + + d.vbuf = m_r->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(cube)); + d.vbuf->create(); + d.releasePool << d.vbuf; + + d.initialUpdates->uploadStaticBuffer(d.vbuf, cube); + + d.ubuf = m_r->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64 + 4 * 4); + d.ubuf->create(); + d.releasePool << d.ubuf; + + qint32 flip = 1; + d.initialUpdates->updateDynamicBuffer(d.ubuf, 64, 4, &flip); + + qint32 doLinearToSRGBInShader = !d.usingHDRWindow; + d.initialUpdates->updateDynamicBuffer(d.ubuf, 68, 4, &doLinearToSRGBInShader); + + QSize size; + QByteArray floatData = loadHdr(d.imageFile, &size); + + d.tex = m_r->newTexture(QRhiTexture::RGBA32F, size); + d.releasePool << d.tex; + d.tex->create(); + QRhiTextureUploadDescription desc({ 0, 0, { floatData.constData(), quint32(floatData.size()) } }); + d.initialUpdates->uploadTexture(d.tex, desc); + + d.sampler = m_r->newSampler(QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None, + QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge); + d.releasePool << d.sampler; + d.sampler->create(); + + d.srb = m_r->newShaderResourceBindings(); + d.releasePool << d.srb; + d.srb->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, d.ubuf), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, d.tex, d.sampler) + }); + d.srb->create(); + + d.ps = m_r->newGraphicsPipeline(); + d.releasePool << d.ps; + d.ps->setCullMode(QRhiGraphicsPipeline::Back); + const QRhiShaderStage stages[] = { + { QRhiShaderStage::Vertex, getShader(QLatin1String(":/hdrtexture.vert.qsb")) }, + { QRhiShaderStage::Fragment, getShader(QLatin1String(":/hdrtexture.frag.qsb")) } + }; + d.ps->setShaderStages(stages, stages + 2); + QRhiVertexInputLayout inputLayout; + inputLayout.setBindings({ + { 3 * sizeof(float) }, + { 2 * sizeof(float) } + }); + inputLayout.setAttributes({ + { 0, 0, QRhiVertexInputAttribute::Float3, 0 }, + { 1, 1, QRhiVertexInputAttribute::Float2, 0 } + }); + d.ps->setVertexInputLayout(inputLayout); + d.ps->setShaderResourceBindings(d.srb); + d.ps->setRenderPassDescriptor(m_rp); + d.ps->create(); +} + +void Window::customRelease() +{ + qDeleteAll(d.releasePool); + d.releasePool.clear(); +} + +void Window::customRender() +{ + if (d.tonemapOutMax == 0.0f) { + QRhiSwapChainHdrInfo info = m_sc->hdrInfo(); + switch (info.limitsType) { + case QRhiSwapChainHdrInfo::LuminanceInNits: + d.tonemapOutMax = info.limits.luminanceInNits.maxLuminance / 80.0f; + break; + case QRhiSwapChainHdrInfo::ColorComponentValue: + // because on macOS it changes dynamically when starting up, so retry in next frame if it's still just 1.0 + if (info.limits.colorComponentValue.maxColorComponentValue > 1.0f) + d.tonemapOutMax = info.limits.colorComponentValue.maxColorComponentValue; + break; + } + } + + QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer(); + QRhiResourceUpdateBatch *u = m_r->nextResourceUpdateBatch(); + if (d.initialUpdates) { + u->merge(d.initialUpdates); + d.initialUpdates->release(); + d.initialUpdates = nullptr; + } + + QMatrix4x4 mvp = m_proj; + mvp.rotate(d.rotation.x(), 1, 0, 0); + mvp.rotate(d.rotation.y(), 0, 1, 0); + mvp.rotate(d.rotation.z(), 0, 0, 1); + u->updateDynamicBuffer(d.ubuf, 0, 64, mvp.constData()); + + if (d.usingHDRWindow && d.tonemapHDR) { + u->updateDynamicBuffer(d.ubuf, 72, 4, &d.tonemapInMax); + u->updateDynamicBuffer(d.ubuf, 76, 4, &d.tonemapOutMax); + } else { + float zero[2] = {}; + u->updateDynamicBuffer(d.ubuf, 72, 8, zero); + } + + QColor clearColor = Qt::green; // sRGB + if (d.usingHDRWindow && d.adjustSDR) { + float sdrMultiplier = d.SDRWhiteLevelInNits / 80.0f; // scRGB 1.0 = 80 nits (and linear gamma) + clearColor = QColor::fromRgbF(clearColor.redF() * sdrMultiplier, + clearColor.greenF() * sdrMultiplier, + clearColor.blueF() * sdrMultiplier, + 1.0f); + } + + const QSize outputSizeInPixels = m_sc->currentPixelSize(); + cb->beginPass(m_sc->currentFrameRenderTarget(), clearColor, { 1.0f, 0 }, u); + + cb->setGraphicsPipeline(d.ps); + cb->setViewport(QRhiViewport(0, 0, outputSizeInPixels.width(), outputSizeInPixels.height())); + cb->setShaderResources(); + const QRhiCommandBuffer::VertexInput vbufBindings[] = { + { d.vbuf, 0 }, + { d.vbuf, quint32(36 * 3 * sizeof(float)) } + }; + cb->setVertexInput(0, 2, vbufBindings); + cb->draw(36); + + m_imguiRenderer->render(); + + cb->endPass(); +} + +static void addTip(const char *s) +{ + ImGui::SameLine(); + ImGui::TextDisabled("(?)"); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(300); + ImGui::TextUnformatted(s); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } +} + +void Window::customGui() +{ + ImGui::SetNextWindowBgAlpha(1.0f); + ImGui::SetNextWindowPos(ImVec2(10, 420), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(800, 300), ImGuiCond_FirstUseEver); + ImGui::Begin("HDR test"); + + if (d.usingHDRWindow) { + if (swapchainFormat == QRhiSwapChain::HDRExtendedDisplayP3Linear) { + ImGui::Text("The window is now Extended Linear Display P3 + FP16 color buffer,\n" + "the ImGui UI and the green background are considered SDR content,\n" + "the cube is using a HDR texture."); + } else { + ImGui::Text("The window is now scRGB (Extended Linear sRGB) + FP16 color buffer,\n" + "the ImGui UI and the green background are considered SDR content,\n" + "the cube is using a HDR texture."); + } + ImGui::Checkbox("Adjust SDR content", &d.adjustSDR); + addTip("Multiplies fragment colors for non-HDR content with sdr_white_level / 80. " + "Not relevant with macOS (due to EDR being display-referred)."); + if (d.adjustSDR) { + ImGui::SliderFloat("SDR white level (nits)", &d.SDRWhiteLevelInNits, 0.0f, 1000.0f); + imguiHDRMultiplier = d.SDRWhiteLevelInNits / 80.0f; // scRGB 1.0 = 80 nits (and linear gamma) + } else { + imguiHDRMultiplier = 1.0f; // 0 would mean linear to sRGB; don't want that with HDR + } + ImGui::Separator(); + ImGui::Checkbox("Tonemap HDR content", &d.tonemapHDR); + addTip("Perform some most basic Reinhard tonemapping (changed to suit HDR) on the 3D content (the cube). " + "Display max luminance is set to the max color component value (macOS) or max luminance in nits / 80 (Windows) by default."); + if (d.tonemapHDR) { + ImGui::SliderFloat("Content max luminance\n(color component value)", &d.tonemapInMax, 0.0f, 20.0f); + ImGui::SliderFloat("Display max luminance\n(color component value)", &d.tonemapOutMax, 0.0f, 20.0f); + } + } else { + ImGui::Text("The window is standard dynamic range (no HDR, so non-linear sRGB effectively).\n" + "Here we just do linear -> sRGB for everything (UI, textured cube)\n" + "at the end of the pipeline, while the Qt::green background is already sRGB."); + } + + ImGui::End(); + + ImGui::SetNextWindowPos(ImVec2(850, 560), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(420, 140), ImGuiCond_FirstUseEver); + ImGui::Begin("Misc"); + float *rot = reinterpret_cast<float *>(&d.rotation); + ImGui::SliderFloat("Rotation X", &rot[0], 0.0f, 360.0f); + ImGui::SliderFloat("Rotation Y", &rot[1], 0.0f, 360.0f); + ImGui::SliderFloat("Rotation Z", &rot[2], 0.0f, 360.0f); + ImGui::End(); + + if (d.usingHDRWindow) { + ImGui::SetNextWindowPos(ImVec2(850, 10), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(420, 180), ImGuiCond_FirstUseEver); + ImGui::Begin("Actual platform info"); + QRhiSwapChainHdrInfo info = m_sc->hdrInfo(); + switch (info.limitsType) { + case QRhiSwapChainHdrInfo::LuminanceInNits: + ImGui::Text("Platform provides luminance in nits"); + addTip("Windows/D3D: On laptops this will be screen brightness dependent. Increasing brightness implies the max luminance decreases. " + "It also seems to be affected by HDR Content Brightness in the Settings, if there is one (e.g. on laptops; not to be confused with SDR Content Brightess). " + "(note that the DXGI query does not seem to return changed values if there are runtime changes unless restarting the app)."); + ImGui::Text("Min luminance: %.4f\nMax luminance: %.4f", + info.limits.luminanceInNits.minLuminance, + info.limits.luminanceInNits.maxLuminance); + break; + case QRhiSwapChainHdrInfo::ColorComponentValue: + ImGui::Text("Platform provides color component values"); + addTip("macOS/Metal: On laptops this will be screen brightness dependent. Increasing brightness decreases the max color value. " + "Max brightness may bring it down to 1.0."); + ImGui::Text("maxColorComponentValue: %.4f\nmaxPotentialColorComponentValue: %.4f", + info.limits.colorComponentValue.maxColorComponentValue, + info.limits.colorComponentValue.maxPotentialColorComponentValue); + break; + } + ImGui::Separator(); + switch (info.luminanceBehavior) { + case QRhiSwapChainHdrInfo::SceneReferred: + ImGui::Text("Luminance behavior is scene-referred"); + break; + case QRhiSwapChainHdrInfo::DisplayReferred: + ImGui::Text("Luminance behavior is display-referred"); + break; + } + addTip("Windows (DWM) HDR is scene-referred: 1.0 = 80 nits.\n\n" + "Apple EDR is display-referred: the value of 1.0 refers to whatever the system's current SDR white level is (100, 200, ... nits depending on the brightness)."); + if (info.luminanceBehavior == QRhiSwapChainHdrInfo::SceneReferred) { + ImGui::Text("SDR white level: %.4f nits", info.sdrWhiteLevel); + addTip("On Windows this is queried from DISPLAYCONFIG_SDR_WHITE_LEVEL. " + "Affected by the slider in the Windows Settings (System/Display/HDR/[S|H]DR Content Brightness). " + "With max screen brightness (laptops) the value will likely be the same as the max luminance."); + } + ImGui::End(); + } +} diff --git a/tests/manual/rhi/hdr/hdrtexture.frag b/tests/manual/rhi/hdr/hdrtexture.frag new file mode 100644 index 0000000000..9d5e12005a --- /dev/null +++ b/tests/manual/rhi/hdr/hdrtexture.frag @@ -0,0 +1,44 @@ +#version 440 + +layout(location = 0) in vec2 v_texcoord; + +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 mvp; + int flip; + int sdr; + float tonemapInMax; + float tonemapOutMax; +} ubuf; + +layout(binding = 1) uniform sampler2D tex; + +vec3 linearToSRGB(vec3 color) +{ + vec3 S1 = sqrt(color); + vec3 S2 = sqrt(S1); + vec3 S3 = sqrt(S2); + return 0.585122381 * S1 + 0.783140355 * S2 - 0.368262736 * S3; +} + +// https://learn.microsoft.com/en-us/windows/win32/direct3darticles/high-dynamic-range +vec3 simpleReinhardTonemapper(vec3 c, float inMax, float outMax) +{ + c /= vec3(inMax); + c.r = c.r / (1 + c.r); + c.g = c.g / (1 + c.g); + c.b = c.b / (1 + c.b); + c *= vec3(outMax); + return c; +} + +void main() +{ + vec4 c = texture(tex, v_texcoord); + if (ubuf.tonemapInMax != 0) + c.rgb = simpleReinhardTonemapper(c.rgb, ubuf.tonemapInMax, ubuf.tonemapOutMax); + else if (ubuf.sdr != 0) + c.rgb = linearToSRGB(c.rgb); + fragColor = vec4(c.rgb * c.a, c.a); +} diff --git a/tests/manual/rhi/hdr/hdrtexture.frag.qsb b/tests/manual/rhi/hdr/hdrtexture.frag.qsb Binary files differnew file mode 100644 index 0000000000..441b660f0b --- /dev/null +++ b/tests/manual/rhi/hdr/hdrtexture.frag.qsb diff --git a/tests/manual/rhi/hdr/hdrtexture.vert b/tests/manual/rhi/hdr/hdrtexture.vert new file mode 100644 index 0000000000..336d5f8cfb --- /dev/null +++ b/tests/manual/rhi/hdr/hdrtexture.vert @@ -0,0 +1,22 @@ +#version 440 + +layout(location = 0) in vec4 position; +layout(location = 1) in vec2 texcoord; + +layout(location = 0) out vec2 v_texcoord; + +layout(std140, binding = 0) uniform buf { + mat4 mvp; + int flip; + int sdr; + float tonemapInMaxNits; + float tonemapOutMaxNits; +}; + +void main() +{ + v_texcoord = vec2(texcoord.x, texcoord.y); + if (flip != 0) + v_texcoord.y = 1.0 - v_texcoord.y; + gl_Position = mvp * position; +} diff --git a/tests/manual/rhi/hdr/hdrtexture.vert.qsb b/tests/manual/rhi/hdr/hdrtexture.vert.qsb Binary files differnew file mode 100644 index 0000000000..bcfb0da273 --- /dev/null +++ b/tests/manual/rhi/hdr/hdrtexture.vert.qsb diff --git a/tests/manual/rhi/hellominimalcrossgfxtriangle/hellowindow.cpp b/tests/manual/rhi/hellominimalcrossgfxtriangle/hellowindow.cpp index 895d7f0007..2fb7405fa7 100644 --- a/tests/manual/rhi/hellominimalcrossgfxtriangle/hellowindow.cpp +++ b/tests/manual/rhi/hellominimalcrossgfxtriangle/hellowindow.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "hellowindow.h" #include <QFile> diff --git a/tests/manual/rhi/hellominimalcrossgfxtriangle/hellowindow.h b/tests/manual/rhi/hellominimalcrossgfxtriangle/hellowindow.h index 41e433d8fa..f3a91aeb09 100644 --- a/tests/manual/rhi/hellominimalcrossgfxtriangle/hellowindow.h +++ b/tests/manual/rhi/hellominimalcrossgfxtriangle/hellowindow.h @@ -1,5 +1,5 @@ // Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef HELLOWINDOW_H #define HELLOWINDOW_H diff --git a/tests/manual/rhi/hellominimalcrossgfxtriangle/main.cpp b/tests/manual/rhi/hellominimalcrossgfxtriangle/main.cpp index 949ac585cd..89926c19cc 100644 --- a/tests/manual/rhi/hellominimalcrossgfxtriangle/main.cpp +++ b/tests/manual/rhi/hellominimalcrossgfxtriangle/main.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only // This is a compact, minimal demo of deciding the backend at runtime while // using the exact same shaders and rendering code without any branching @@ -37,7 +37,7 @@ int main(int argc, char **argv) QRhi::Implementation graphicsApi; #if defined(Q_OS_WIN) graphicsApi = QRhi::D3D11; -#elif defined(Q_OS_MACOS) || defined(Q_OS_IOS) +#elif QT_CONFIG(metal) graphicsApi = QRhi::Metal; #elif QT_CONFIG(vulkan) graphicsApi = QRhi::Vulkan; diff --git a/tests/manual/rhi/hellominimalcrossgfxtriangle/window.cpp b/tests/manual/rhi/hellominimalcrossgfxtriangle/window.cpp index f8bacc078b..edbd048c63 100644 --- a/tests/manual/rhi/hellominimalcrossgfxtriangle/window.cpp +++ b/tests/manual/rhi/hellominimalcrossgfxtriangle/window.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "window.h" #include <QPlatformSurfaceEvent> @@ -120,7 +120,7 @@ void Window::init() } #endif -#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) +#if QT_CONFIG(metal) if (m_graphicsApi == QRhi::Metal) { QRhiMetalInitParams params; m_rhi.reset(QRhi::create(QRhi::Metal, ¶ms, rhiFlags)); diff --git a/tests/manual/rhi/hellominimalcrossgfxtriangle/window.h b/tests/manual/rhi/hellominimalcrossgfxtriangle/window.h index 5f0fc09941..eb43809096 100644 --- a/tests/manual/rhi/hellominimalcrossgfxtriangle/window.h +++ b/tests/manual/rhi/hellominimalcrossgfxtriangle/window.h @@ -1,5 +1,5 @@ // Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef WINDOW_H #define WINDOW_H diff --git a/tests/manual/rhi/imguirenderer/CMakeLists.txt b/tests/manual/rhi/imguirenderer/CMakeLists.txt index 619c351d7f..8c04918d06 100644 --- a/tests/manual/rhi/imguirenderer/CMakeLists.txt +++ b/tests/manual/rhi/imguirenderer/CMakeLists.txt @@ -1,3 +1,5 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause qt_internal_add_manual_test(imguirenderer GUI SOURCES diff --git a/tests/manual/rhi/imguirenderer/imguirenderer.cpp b/tests/manual/rhi/imguirenderer/imguirenderer.cpp index 8c3438a724..ef675c2e5b 100644 --- a/tests/manual/rhi/imguirenderer/imguirenderer.cpp +++ b/tests/manual/rhi/imguirenderer/imguirenderer.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2023 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #define EXAMPLEFW_IMGUI #include "../shared/examplefw.h" diff --git a/tests/manual/rhi/instancing/buildshaders.bat b/tests/manual/rhi/instancing/buildshaders.bat index 9053a1c54a..af18c09602 100644 --- a/tests/manual/rhi/instancing/buildshaders.bat +++ b/tests/manual/rhi/instancing/buildshaders.bat @@ -1,2 +1,4 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 qsb --glsl "330,300 es" --hlsl 50 --msl 12 inst.vert -o inst.vert.qsb qsb --glsl "330,300 es" --hlsl 50 --msl 12 inst.frag -o inst.frag.qsb diff --git a/tests/manual/rhi/instancing/instancing.cpp b/tests/manual/rhi/instancing/instancing.cpp index c6f89b593c..320cc2d6c7 100644 --- a/tests/manual/rhi/instancing/instancing.cpp +++ b/tests/manual/rhi/instancing/instancing.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" #include "../shared/cube.h" diff --git a/tests/manual/rhi/mrt/buildshaders.bat b/tests/manual/rhi/mrt/buildshaders.bat index 75741448b1..b23e01d00e 100644 --- a/tests/manual/rhi/mrt/buildshaders.bat +++ b/tests/manual/rhi/mrt/buildshaders.bat @@ -1,2 +1,4 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 qsb --glsl "100 es,120" --hlsl 50 --msl 12 -c mrt.vert -o mrt.vert.qsb qsb --glsl "100 es,120" --hlsl 50 --msl 12 -c mrt.frag -o mrt.frag.qsb diff --git a/tests/manual/rhi/mrt/mrt.cpp b/tests/manual/rhi/mrt/mrt.cpp index d03b3db1cc..a548ed1592 100644 --- a/tests/manual/rhi/mrt/mrt.cpp +++ b/tests/manual/rhi/mrt/mrt.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" diff --git a/tests/manual/rhi/msaarenderbuffer/msaarenderbuffer.cpp b/tests/manual/rhi/msaarenderbuffer/msaarenderbuffer.cpp index 11274466f2..539a1b42e1 100644 --- a/tests/manual/rhi/msaarenderbuffer/msaarenderbuffer.cpp +++ b/tests/manual/rhi/msaarenderbuffer/msaarenderbuffer.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" diff --git a/tests/manual/rhi/msaatexture/msaatexture.cpp b/tests/manual/rhi/msaatexture/msaatexture.cpp index ef7044b6d5..9edc8f5714 100644 --- a/tests/manual/rhi/msaatexture/msaatexture.cpp +++ b/tests/manual/rhi/msaatexture/msaatexture.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" diff --git a/tests/manual/rhi/msaatextureresolve/CMakeLists.txt b/tests/manual/rhi/msaatextureresolve/CMakeLists.txt new file mode 100644 index 0000000000..fb14b119de --- /dev/null +++ b/tests/manual/rhi/msaatextureresolve/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(msaatextureresolve LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + +qt_internal_add_manual_test(msaatextureresolve + GUI + SOURCES + msaatextureresolve.cpp + LIBRARIES + Qt::Gui + Qt::GuiPrivate +) + +# Resources: +set_source_files_properties("../shared/color.frag.qsb" + PROPERTIES QT_RESOURCE_ALIAS "color.frag.qsb" +) +set_source_files_properties("../shared/color.vert.qsb" + PROPERTIES QT_RESOURCE_ALIAS "color.vert.qsb" +) +set_source_files_properties("../shared/texture.frag.qsb" + PROPERTIES QT_RESOURCE_ALIAS "texture.frag.qsb" +) +set_source_files_properties("../shared/texture.vert.qsb" + PROPERTIES QT_RESOURCE_ALIAS "texture.vert.qsb" +) + +qt_internal_add_resource(msaatextureresolve "msaatextureresolve" + PREFIX + "/" + FILES + "../shared/color.frag.qsb" + "../shared/color.vert.qsb" + "../shared/texture.frag.qsb" + "../shared/texture.vert.qsb" +) diff --git a/tests/manual/rhi/msaatextureresolve/msaatextureresolve.cpp b/tests/manual/rhi/msaatextureresolve/msaatextureresolve.cpp new file mode 100644 index 0000000000..128cecf707 --- /dev/null +++ b/tests/manual/rhi/msaatextureresolve/msaatextureresolve.cpp @@ -0,0 +1,235 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "../shared/examplefw.h" + +// Uses a multisample texture both for color and depth-stencil, renders into +// those, and then resolves into non-multisample textures. Also the +// depth-stencil, in order to exercise that rarely used path. If that is +// functional, will not be visible on-screen. Frame captures with tools such as +// RenderDoc can be used to verify that there is indeed a non-multisample depth +// texture generated. + +static float vertexData[] = +{ // Y up, CCW + -0.5f, 0.5f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.0f, 1.0f, + 0.5f, -0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, 1.0f, 0.0f +}; + +static quint16 indexData[] = +{ + 0, 1, 2, 0, 2, 3 +}; + +static float triangleData[] = +{ // Y up, CCW + 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, +}; + +struct { + QList<QRhiResource *> releasePool; + QRhiBuffer *vbuf = nullptr; + QRhiBuffer *ibuf = nullptr; + QRhiBuffer *ubuf = nullptr; + QRhiTexture *msaaColorTexture = nullptr; + QRhiTexture *msaaDepthTexture = nullptr; + QRhiTextureRenderTarget *rt = nullptr; + QRhiRenderPassDescriptor *rtRp = nullptr; + QRhiTexture *tex = nullptr; + QRhiTexture *depthTex = nullptr; + QRhiSampler *sampler = nullptr; + QRhiBuffer *triUbuf = nullptr; + QRhiShaderResourceBindings *triSrb = nullptr; + QRhiGraphicsPipeline *triPs = nullptr; + QRhiShaderResourceBindings *srb = nullptr; + QRhiGraphicsPipeline *ps = nullptr; + QRhiResourceUpdateBatch *initialUpdates = nullptr; + QMatrix4x4 triBaseMvp; + float triRot = 0; + QMatrix4x4 winProj; +} d; + +void Window::customInit() +{ + if (!m_r->isFeatureSupported(QRhi::MultisampleTexture)) + qFatal("Multisample textures not supported by this backend"); + + // Skip the check for ResolveDepthStencil, and let it run regardless. When + // not supported, it won't be functional, but should be handled somewhat + // gracefully. + + d.vbuf = m_r->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertexData) + sizeof(triangleData)); + d.vbuf->create(); + d.releasePool << d.vbuf; + + d.ibuf = m_r->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::IndexBuffer, sizeof(indexData)); + d.ibuf->create(); + d.releasePool << d.ibuf; + + d.ubuf = m_r->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 68); + d.ubuf->create(); + d.releasePool << d.ubuf; + + d.msaaColorTexture = m_r->newTexture(QRhiTexture::RGBA8, QSize(512, 512), 4, QRhiTexture::RenderTarget); // 4x MSAA + d.msaaColorTexture->create(); + d.releasePool << d.msaaColorTexture; + + d.msaaDepthTexture = m_r->newTexture(QRhiTexture::D24S8, QSize(512, 512), 4, QRhiTexture::RenderTarget); // 4x MSAA + d.msaaDepthTexture->create(); + d.releasePool << d.msaaDepthTexture; + + // the non-msaa texture that will be the destination in the resolve + d.tex = m_r->newTexture(QRhiTexture::RGBA8, d.msaaColorTexture->pixelSize(), 1, QRhiTexture::RenderTarget); + d.releasePool << d.tex; + d.tex->create(); + + d.depthTex = m_r->newTexture(QRhiTexture::D24S8, d.msaaDepthTexture->pixelSize(), 1, QRhiTexture::RenderTarget); + d.releasePool << d.depthTex; + d.depthTex->create(); + + QRhiTextureRenderTargetDescription rtDesc; + QRhiColorAttachment rtAtt(d.msaaColorTexture); + rtAtt.setResolveTexture(d.tex); + rtDesc.setColorAttachments({ rtAtt }); + rtDesc.setDepthTexture(d.msaaDepthTexture); + rtDesc.setDepthResolveTexture(d.depthTex); + + d.rt = m_r->newTextureRenderTarget(rtDesc); + d.releasePool << d.rt; + d.rtRp = d.rt->newCompatibleRenderPassDescriptor(); + d.releasePool << d.rtRp; + d.rt->setRenderPassDescriptor(d.rtRp); + d.rt->create(); + + d.triUbuf = m_r->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 68); + d.releasePool << d.triUbuf; + d.triUbuf->create(); + + d.triSrb = m_r->newShaderResourceBindings(); + d.releasePool << d.triSrb; + d.triSrb->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, d.triUbuf) + }); + d.triSrb->create(); + + d.triPs = m_r->newGraphicsPipeline(); + d.releasePool << d.triPs; + d.triPs->setDepthTest(true); + d.triPs->setDepthWrite(true); + d.triPs->setSampleCount(4); // must match the render target + d.triPs->setShaderStages({ + { QRhiShaderStage::Vertex, getShader(QLatin1String(":/color.vert.qsb")) }, + { QRhiShaderStage::Fragment, getShader(QLatin1String(":/color.frag.qsb")) } + }); + QRhiVertexInputLayout inputLayout; + inputLayout.setBindings({ + { 5 * sizeof(float) } + }); + inputLayout.setAttributes({ + { 0, 0, QRhiVertexInputAttribute::Float2, 0 }, + { 0, 1, QRhiVertexInputAttribute::Float3, quint32(2 * sizeof(float)) } + }); + d.triPs->setVertexInputLayout(inputLayout); + d.triPs->setShaderResourceBindings(d.triSrb); + d.triPs->setRenderPassDescriptor(d.rtRp); + d.triPs->create(); + + d.sampler = m_r->newSampler(QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None, + QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge); + d.releasePool << d.sampler; + d.sampler->create(); + + d.srb = m_r->newShaderResourceBindings(); + d.releasePool << d.srb; + d.srb->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, d.ubuf), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, d.tex, d.sampler) + }); + d.srb->create(); + + d.ps = m_r->newGraphicsPipeline(); + d.releasePool << d.ps; + d.ps->setShaderStages({ + { QRhiShaderStage::Vertex, getShader(QLatin1String(":/texture.vert.qsb")) }, + { QRhiShaderStage::Fragment, getShader(QLatin1String(":/texture.frag.qsb")) } + }); + inputLayout.setBindings({ + { 4 * sizeof(float) } + }); + inputLayout.setAttributes({ + { 0, 0, QRhiVertexInputAttribute::Float2, 0 }, + { 0, 1, QRhiVertexInputAttribute::Float2, quint32(2 * sizeof(float)) } + }); + d.ps->setVertexInputLayout(inputLayout); + d.ps->setShaderResourceBindings(d.srb); + d.ps->setRenderPassDescriptor(m_rp); + d.ps->create(); + + d.initialUpdates = m_r->nextResourceUpdateBatch(); + d.initialUpdates->uploadStaticBuffer(d.vbuf, 0, sizeof(vertexData), vertexData); + d.initialUpdates->uploadStaticBuffer(d.vbuf, sizeof(vertexData), sizeof(triangleData), triangleData); + d.initialUpdates->uploadStaticBuffer(d.ibuf, indexData); + + d.triBaseMvp = m_r->clipSpaceCorrMatrix(); + d.triBaseMvp.perspective(45.0f, d.msaaColorTexture->pixelSize().width() / float(d.msaaColorTexture->pixelSize().height()), 0.01f, 1000.0f); + d.triBaseMvp.translate(0, 0, -2); + float opacity = 1.0f; + d.initialUpdates->updateDynamicBuffer(d.triUbuf, 64, 4, &opacity); + + qint32 flip = m_r->isYUpInFramebuffer() ? 1 : 0; + d.initialUpdates->updateDynamicBuffer(d.ubuf, 64, 4, &flip); +} + +void Window::customRelease() +{ + qDeleteAll(d.releasePool); + d.releasePool.clear(); +} + +void Window::customRender() +{ + QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer(); + QRhiResourceUpdateBatch *u = m_r->nextResourceUpdateBatch(); + if (d.initialUpdates) { + u->merge(d.initialUpdates); + d.initialUpdates->release(); + d.initialUpdates = nullptr; + } + + QMatrix4x4 triMvp = d.triBaseMvp; + triMvp.rotate(d.triRot, 0, 1, 0); + d.triRot += 1; + u->updateDynamicBuffer(d.triUbuf, 0, 64, triMvp.constData()); + + if (d.winProj != m_proj) { + d.winProj = m_proj; + QMatrix4x4 mvp = m_proj; + mvp.scale(2.5f); + u->updateDynamicBuffer(d.ubuf, 0, 64, mvp.constData()); + } + + // offscreen (triangle, msaa) + cb->beginPass(d.rt, QColor::fromRgbF(0.5f, 0.2f, 0.0f, 1.0f), { 1.0f, 0 }, u); + cb->setGraphicsPipeline(d.triPs); + cb->setViewport({ 0, 0, float(d.msaaColorTexture->pixelSize().width()), float(d.msaaColorTexture->pixelSize().height()) }); + cb->setShaderResources(); + QRhiCommandBuffer::VertexInput vbufBinding(d.vbuf, quint32(sizeof(vertexData))); + cb->setVertexInput(0, 1, &vbufBinding); + cb->draw(3); + cb->endPass(); + + // onscreen (quad) + const QSize outputSizeInPixels = m_sc->currentPixelSize(); + cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }); + cb->setGraphicsPipeline(d.ps); + cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) }); + cb->setShaderResources(); + vbufBinding.second = 0; + cb->setVertexInput(0, 1, &vbufBinding, d.ibuf, 0, QRhiCommandBuffer::IndexUInt16); + cb->drawIndexed(6); + cb->endPass(); +} diff --git a/tests/manual/rhi/multiview/CMakeLists.txt b/tests/manual/rhi/multiview/CMakeLists.txt new file mode 100644 index 0000000000..1e2efa02cb --- /dev/null +++ b/tests/manual/rhi/multiview/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_manual_test(multiview + GUI + SOURCES + multiview.cpp + LIBRARIES + Qt::Gui + Qt::GuiPrivate +) + +qt_internal_add_resource(multiview "multiview" + PREFIX + "/" + FILES + "multiview.vert.qsb" + "multiview.frag.qsb" + "texture.vert.qsb" + "texture.frag.qsb" +) diff --git a/tests/manual/rhi/multiview/buildshaders.bat b/tests/manual/rhi/multiview/buildshaders.bat new file mode 100644 index 0000000000..d9d2825218 --- /dev/null +++ b/tests/manual/rhi/multiview/buildshaders.bat @@ -0,0 +1,6 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +qsb --view-count 2 --glsl "300 es,330" --hlsl 61 -c --msl 12 multiview.vert -o multiview.vert.qsb +qsb --glsl "300 es,330" --hlsl 61 -c --msl 12 multiview.frag -o multiview.frag.qsb +qsb --glsl "300 es,330" --hlsl 61 -c --msl 12 texture.vert -o texture.vert.qsb +qsb --glsl "300 es,330" --hlsl 61 -c --msl 12 texture.frag -o texture.frag.qsb diff --git a/tests/manual/rhi/multiview/multiview.cpp b/tests/manual/rhi/multiview/multiview.cpp new file mode 100644 index 0000000000..a89821eb8e --- /dev/null +++ b/tests/manual/rhi/multiview/multiview.cpp @@ -0,0 +1,305 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "../shared/examplefw.h" + +// Multiview rendering. Renders the same geometry (a triangle) with two +// different transforms into two layers of a texture array object in a *single* +// draw call. (NB under the hood it is at the hardware/driver's discretion what +// happens; it may very well map to some simple looping and still drawing +// twice, whereas with modern hardware it can be expected to be implemented +// more efficiently, but that's hidden from us) + +// Toggle this to exercise 4x MSAA for the texture array that is the render +// target of the multiview render pass. The elements written by the multiview +// render pass get resolved to a non-multisample texture array at the end of +// the pass. +static bool MSAA = false; + +static float quadVertexData[] = +{ // Y up, CCW + -0.5f, 0.5f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.0f, 1.0f, + 0.5f, -0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, 1.0f, 0.0f +}; + +static quint16 quadIndexData[] = +{ + 0, 1, 2, 0, 2, 3 +}; + +static float triangleData[] = +{ // Y up, CCW + 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, -0.5f, 0.0f, 0.0f, 1.0f +}; + +static const int INSTANCE_COUNT = 5; + +static float instanceData[INSTANCE_COUNT * 3] = +{ + 0.4f, 0.0f, 0.0f, + 0.2f, 0.0f, 0.1f, + 0.0f, 0.0f, 0.2f, + -0.2f, 0.0f, 0.3f, + -0.4f, 0.0f, 0.4f +}; + +struct { + QList<QRhiResource *> releasePool; + QRhiBuffer *vbuf = nullptr; + QRhiBuffer *instanceBuf = nullptr; + QRhiBuffer *ibuf = nullptr; + QRhiBuffer *ubuf = nullptr; + QRhiTextureRenderTarget *rt = nullptr; + QRhiRenderPassDescriptor *rtRp = nullptr; + QRhiSampler *sampler = nullptr; + QRhiGraphicsPipeline *ps = nullptr; + QRhiResourceUpdateBatch *initialUpdates = nullptr; + QMatrix4x4 winProj; + QRhiTexture *tex = nullptr; + QRhiTexture *resolveTex = nullptr; // only if MSAA is true + QRhiTexture *ds = nullptr; + QRhiShaderResourceBindings *srb[2] = {}; + + QRhiBuffer *triUbuf = nullptr; + QRhiShaderResourceBindings *triSrb = nullptr; + QRhiGraphicsPipeline *triPs = nullptr; + QMatrix4x4 triBaseMvp; +} d; + +void Window::customInit() +{ + if (!m_r->isFeatureSupported(QRhi::MultiView)) + qFatal("Multiview is not supported"); + + int sampleCount = 1; + if (MSAA) { + qDebug("Using 4x MSAA for the multiview render pass"); + sampleCount = 4; + } + + // texture array with 2 elements, e.g. 0 is left eye, 1 is right + d.tex = m_r->newTextureArray(QRhiTexture::RGBA8, 2, QSize(512, 512), sampleCount, QRhiTexture::RenderTarget); + d.releasePool << d.tex; + d.tex->create(); + + if (MSAA) { + d.resolveTex = m_r->newTextureArray(QRhiTexture::RGBA8, 2, QSize(512, 512), 1, QRhiTexture::RenderTarget); + d.releasePool << d.resolveTex; + d.resolveTex->create(); + } + + // Have a depth-stencil buffer, just to exercise it, the triangles will be + // rendered with depth test/write enabled. The catch here is that we must + // use a texture array for depth/stencil as well, so QRhiRenderBuffer is + // not an option anymore. + d.ds = m_r->newTextureArray(QRhiTexture::D24S8, 2, QSize(512, 512), sampleCount, QRhiTexture::RenderTarget); + d.releasePool << d.ds; + d.ds->create(); + + // set up the multiview render target + QRhiColorAttachment multiViewAtt(d.tex); + // using array elements 0 and 1 + multiViewAtt.setLayer(0); + multiViewAtt.setMultiViewCount(2); // the view count must be set both on the render target and the pipeline + + // On-screen we work with a non-MSAA texture array, so the fragment shader + // does not need to deal with sampler2DMSArray, but can use sampler2DArray + // regardless of using multisampling or not. This means using an extra + // non-MSAA 2D texture array into which both array elements get resolved at + // the end of the multiview render pass. + QRhiTexture *textureForOnscreenView = d.tex; + if (MSAA) { + multiViewAtt.setResolveTexture(d.resolveTex); + textureForOnscreenView = d.resolveTex; + } + + QRhiTextureRenderTargetDescription rtDesc(multiViewAtt); + rtDesc.setDepthTexture(d.ds); + + d.rt = m_r->newTextureRenderTarget(rtDesc); + d.releasePool << d.rt; + d.rtRp = d.rt->newCompatibleRenderPassDescriptor(); + d.releasePool << d.rtRp; + d.rt->setRenderPassDescriptor(d.rtRp); + d.rt->create(); + + // vertex buffer used by both passes + d.vbuf = m_r->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(quadVertexData) + sizeof(triangleData)); + d.vbuf->create(); + d.releasePool << d.vbuf; + + // data for the instanced translation attribute + d.instanceBuf = m_r->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(instanceData)); + d.instanceBuf->create(); + d.releasePool << d.instanceBuf; + + // resources for the on-screen visualizer + d.ibuf = m_r->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::IndexBuffer, sizeof(quadIndexData)); + d.ibuf->create(); + d.releasePool << d.ibuf; + + const int oneRoundedUniformBlockSize = m_r->ubufAligned(72); + d.ubuf = m_r->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, oneRoundedUniformBlockSize * 2); + d.ubuf->create(); + d.releasePool << d.ubuf; + + d.sampler = m_r->newSampler(QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None, + QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge); + d.releasePool << d.sampler; + d.sampler->create(); + + // two srbs, just for the quad positioning on-screen + for (int i = 0; i < 2; ++i) { + QRhiShaderResourceBindings *srb = m_r->newShaderResourceBindings(); + d.releasePool << srb; + srb->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, + d.ubuf, i * oneRoundedUniformBlockSize, 72), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, + textureForOnscreenView, d.sampler) + }); + srb->create(); + d.srb[i] = srb; + } + + d.ps = m_r->newGraphicsPipeline(); + d.releasePool << d.ps; + d.ps->setShaderStages({ + { QRhiShaderStage::Vertex, getShader(QLatin1String(":/texture.vert.qsb")) }, + { QRhiShaderStage::Fragment, getShader(QLatin1String(":/texture.frag.qsb")) } + }); + QRhiVertexInputLayout inputLayout; + inputLayout.setBindings({ + { 4 * sizeof(float) } + }); + inputLayout.setAttributes({ + { 0, 0, QRhiVertexInputAttribute::Float2, 0 }, + { 0, 1, QRhiVertexInputAttribute::Float2, quint32(2 * sizeof(float)) } + }); + d.ps->setVertexInputLayout(inputLayout); + d.ps->setShaderResourceBindings(d.srb[0]); // all of them are layout-compatible + d.ps->setRenderPassDescriptor(m_rp); + d.ps->create(); + + d.initialUpdates = m_r->nextResourceUpdateBatch(); + d.initialUpdates->uploadStaticBuffer(d.vbuf, 0, sizeof(quadVertexData), quadVertexData); + d.initialUpdates->uploadStaticBuffer(d.vbuf, sizeof(quadVertexData), sizeof(triangleData), triangleData); + d.initialUpdates->uploadStaticBuffer(d.instanceBuf, instanceData); + d.initialUpdates->uploadStaticBuffer(d.ibuf, quadIndexData); + + qint32 flip = m_r->isYUpInFramebuffer() ? 1 : 0; + for (int i = 0; i < 2; ++i) { + d.initialUpdates->updateDynamicBuffer(d.ubuf, i * oneRoundedUniformBlockSize + 64, 4, &flip); + float layer = i; + d.initialUpdates->updateDynamicBuffer(d.ubuf, i * oneRoundedUniformBlockSize + 68, 4, &layer); + } + + // create resources for the multiview render pass + d.triUbuf = m_r->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 128); // mat4 mvp[2] + d.releasePool << d.triUbuf; + d.triUbuf->create(); + + d.triSrb = m_r->newShaderResourceBindings(); + d.releasePool << d.triSrb; + d.triSrb->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, d.triUbuf) + }); + d.triSrb->create(); + + d.triPs = m_r->newGraphicsPipeline(); + d.releasePool << d.triPs; + d.triPs->setShaderStages({ + { QRhiShaderStage::Vertex, getShader(QLatin1String(":/multiview.vert.qsb")) }, + { QRhiShaderStage::Fragment, getShader(QLatin1String(":/multiview.frag.qsb")) } + }); + d.triPs->setMultiViewCount(2); // the view count must be set both on the render target and the pipeline + inputLayout.setBindings({ + { 5 * sizeof(float) }, + { 3 * sizeof(float), QRhiVertexInputBinding::PerInstance } + }); + inputLayout.setAttributes({ + { 0, 0, QRhiVertexInputAttribute::Float2, 0 }, + { 0, 1, QRhiVertexInputAttribute::Float3, quint32(2 * sizeof(float)) }, + { 1, 2, QRhiVertexInputAttribute::Float3, 0 } + }); + d.triPs->setDepthTest(true); + d.triPs->setDepthWrite(true); + d.triPs->setSampleCount(sampleCount); + d.triPs->setVertexInputLayout(inputLayout); + d.triPs->setShaderResourceBindings(d.triSrb); + d.triPs->setRenderPassDescriptor(d.rtRp); + d.triPs->create(); + + d.triBaseMvp = m_r->clipSpaceCorrMatrix(); + d.triBaseMvp.perspective(45.0f, d.rt->pixelSize().width() / float(d.rt->pixelSize().height()), 0.01f, 1000.0f); + d.triBaseMvp.translate(0, 0, -2); +} + +void Window::customRelease() +{ + qDeleteAll(d.releasePool); + d.releasePool.clear(); +} + +void Window::customRender() +{ + QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer(); + QRhiResourceUpdateBatch *u = m_r->nextResourceUpdateBatch(); + if (d.initialUpdates) { + u->merge(d.initialUpdates); + d.initialUpdates->release(); + d.initialUpdates = nullptr; + } + + QMatrix4x4 triMvp = d.triBaseMvp; + // let's say this is the left eye, make the triangle point left for now + triMvp.rotate(90, 0, 0, 1); + u->updateDynamicBuffer(d.triUbuf, 0, 64, triMvp.constData()); + triMvp = d.triBaseMvp; + // right for the right eye + triMvp.rotate(270, 0, 0, 1); + u->updateDynamicBuffer(d.triUbuf, 64, 64, triMvp.constData()); + + cb->beginPass(d.rt, QColor::fromRgbF(0.5f, 0.2f, 0.0f, 1.0f), { 1.0f, 0 }, u); + cb->setGraphicsPipeline(d.triPs); + cb->setViewport({ 0, 0, float(d.rt->pixelSize().width()), float(d.rt->pixelSize().height()) }); + cb->setShaderResources(); + const QRhiCommandBuffer::VertexInput multiViewPassVbufBindings[] = { + { d.vbuf, quint32(sizeof(quadVertexData)) }, + { d.instanceBuf, 0 } + }; + cb->setVertexInput(0, 2, multiViewPassVbufBindings); + cb->draw(3, INSTANCE_COUNT); + cb->endPass(); + + // "blit" the two texture layers on-screen just to visualize the contents + u = m_r->nextResourceUpdateBatch(); + if (d.winProj != m_proj) { + d.winProj = m_proj; + const int oneRoundedUniformBlockSize = m_r->ubufAligned(72); + for (int i = 0; i < 2; ++i) { + QMatrix4x4 mvp = m_proj; + mvp.translate(0, 0, 1); + if (i == 0) + mvp.translate(-1.0f, 0, 0); + else + mvp.translate(1.0f, 0, 0); + u->updateDynamicBuffer(d.ubuf, i * oneRoundedUniformBlockSize, 64, mvp.constData()); + } + } + const QSize outputSizeInPixels = m_sc->currentPixelSize(); + cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u); + cb->setGraphicsPipeline(d.ps); + cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) }); + const QRhiCommandBuffer::VertexInput quadPassVBufBindings[] = { { d.vbuf, 0 } }; + cb->setVertexInput(0, 1, quadPassVBufBindings, d.ibuf, 0, QRhiCommandBuffer::IndexUInt16); + for (int i = 0; i < 2; ++i) { + cb->setShaderResources(d.srb[i]); + cb->drawIndexed(6); + } + cb->endPass(); +} diff --git a/tests/manual/rhi/multiview/multiview.frag b/tests/manual/rhi/multiview/multiview.frag new file mode 100644 index 0000000000..afcbff3504 --- /dev/null +++ b/tests/manual/rhi/multiview/multiview.frag @@ -0,0 +1,11 @@ +#version 440 + +layout(location = 0) in vec3 v_color; +layout(location = 1) in flat uint v_viewIndex; + +layout(location = 0) out vec4 fragColor; + +void main() +{ + fragColor = vec4(v_color + v_viewIndex * 0.5, 1.0); +} diff --git a/tests/manual/rhi/multiview/multiview.frag.qsb b/tests/manual/rhi/multiview/multiview.frag.qsb Binary files differnew file mode 100644 index 0000000000..c02a3cd4b9 --- /dev/null +++ b/tests/manual/rhi/multiview/multiview.frag.qsb diff --git a/tests/manual/rhi/multiview/multiview.pro b/tests/manual/rhi/multiview/multiview.pro new file mode 100644 index 0000000000..a9606f8898 --- /dev/null +++ b/tests/manual/rhi/multiview/multiview.pro @@ -0,0 +1,8 @@ +TEMPLATE = app + +QT += gui-private + +SOURCES = \ + multiview.cpp + +RESOURCES = multiview.qrc diff --git a/tests/manual/rhi/multiview/multiview.qrc b/tests/manual/rhi/multiview/multiview.qrc new file mode 100644 index 0000000000..e931dd8c11 --- /dev/null +++ b/tests/manual/rhi/multiview/multiview.qrc @@ -0,0 +1,8 @@ +<!DOCTYPE RCC><RCC version="1.0"> + <qresource> + <file>multiview.vert.qsb</file> + <file>multiview.frag.qsb</file> + <file>texture.vert.qsb</file> + <file>texture.frag.qsb</file> +</qresource> +</RCC> diff --git a/tests/manual/rhi/multiview/multiview.vert b/tests/manual/rhi/multiview/multiview.vert new file mode 100644 index 0000000000..3dd17578d2 --- /dev/null +++ b/tests/manual/rhi/multiview/multiview.vert @@ -0,0 +1,21 @@ +#version 440 +#extension GL_EXT_multiview : require + +layout(location = 0) in vec4 pos; +layout(location = 1) in vec3 color; +layout(location = 2) in vec3 translation; + +layout(location = 0) out vec3 v_color; +layout(location = 1) out flat uint v_viewIndex; + +layout(std140, binding = 0) uniform buf +{ + mat4 mvp[2]; +}; + +void main() +{ + v_color = color; + gl_Position = mvp[gl_ViewIndex] * (pos + vec4(translation, 0.0)); + v_viewIndex = gl_ViewIndex; +} diff --git a/tests/manual/rhi/multiview/multiview.vert.qsb b/tests/manual/rhi/multiview/multiview.vert.qsb Binary files differnew file mode 100644 index 0000000000..4903c54103 --- /dev/null +++ b/tests/manual/rhi/multiview/multiview.vert.qsb diff --git a/tests/manual/rhi/multiview/texture.frag b/tests/manual/rhi/multiview/texture.frag new file mode 100644 index 0000000000..148f4113c8 --- /dev/null +++ b/tests/manual/rhi/multiview/texture.frag @@ -0,0 +1,19 @@ +#version 440 + +layout(location = 0) in vec2 v_texcoord; + +layout(location = 0) out vec4 fragColor; + +layout(binding = 1) uniform sampler2DArray tex; + +layout(std140, binding = 0) uniform buf { + mat4 mvp; + int flip; + float layer; +}; + +void main() +{ + vec4 c = texture(tex, vec3(v_texcoord, layer)); + fragColor = vec4(c.rgb * c.a, c.a); +} diff --git a/tests/manual/rhi/multiview/texture.frag.qsb b/tests/manual/rhi/multiview/texture.frag.qsb Binary files differnew file mode 100644 index 0000000000..5d0de425d1 --- /dev/null +++ b/tests/manual/rhi/multiview/texture.frag.qsb diff --git a/tests/manual/rhi/multiview/texture.vert b/tests/manual/rhi/multiview/texture.vert new file mode 100644 index 0000000000..156dca0db6 --- /dev/null +++ b/tests/manual/rhi/multiview/texture.vert @@ -0,0 +1,20 @@ +#version 440 + +layout(location = 0) in vec4 position; +layout(location = 1) in vec2 texcoord; + +layout(location = 0) out vec2 v_texcoord; + +layout(std140, binding = 0) uniform buf { + mat4 mvp; + int flip; + float layer; +}; + +void main() +{ + v_texcoord = vec2(texcoord.x, texcoord.y); + if (flip != 0) + v_texcoord.y = 1.0 - v_texcoord.y; + gl_Position = mvp * position; +} diff --git a/tests/manual/rhi/multiview/texture.vert.qsb b/tests/manual/rhi/multiview/texture.vert.qsb Binary files differnew file mode 100644 index 0000000000..0d1078f394 --- /dev/null +++ b/tests/manual/rhi/multiview/texture.vert.qsb diff --git a/tests/manual/rhi/multiwindow/multiwindow.cpp b/tests/manual/rhi/multiwindow/multiwindow.cpp index 7ff6644e26..bea4af2d48 100644 --- a/tests/manual/rhi/multiwindow/multiwindow.cpp +++ b/tests/manual/rhi/multiwindow/multiwindow.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QApplication> #include <QWidget> @@ -91,7 +91,7 @@ void createRhi() } #endif -#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) +#if QT_CONFIG(metal) if (graphicsApi == Metal) { QRhiMetalInitParams params; r.r = QRhi::create(QRhi::Metal, ¶ms); @@ -469,7 +469,7 @@ int main(int argc, char **argv) #if defined(Q_OS_WIN) graphicsApi = D3D11; -#elif defined(Q_OS_MACOS) || defined(Q_OS_IOS) +#elif QT_CONFIG(metal) graphicsApi = Metal; #elif QT_CONFIG(vulkan) graphicsApi = Vulkan; diff --git a/tests/manual/rhi/multiwindow_threaded/multiwindow_threaded.cpp b/tests/manual/rhi/multiwindow_threaded/multiwindow_threaded.cpp index eff0b536d0..634caebd8d 100644 --- a/tests/manual/rhi/multiwindow_threaded/multiwindow_threaded.cpp +++ b/tests/manual/rhi/multiwindow_threaded/multiwindow_threaded.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QApplication> #include <QWidget> @@ -321,7 +321,7 @@ void Renderer::createRhi() } #endif -#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) +#if QT_CONFIG(metal) if (graphicsApi == Metal) { QRhiMetalInitParams params; r = QRhi::create(QRhi::Metal, ¶ms, rhiFlags); @@ -623,7 +623,7 @@ void createWindow() static QColor colors[] = { Qt::red, Qt::green, Qt::blue, Qt::yellow, Qt::cyan, Qt::gray }; const int n = windows.count(); Window *w = new Window(QString::asprintf("Window+Thread #%d (%s)", n, qPrintable(graphicsApiName())), graphicsApi); - Renderer *renderer = new Renderer(w, colors[n % 6], n % 3);; + Renderer *renderer = new Renderer(w, colors[n % 6], n % 3); QObject::connect(w, &Window::initRequested, w, [renderer] { renderer->sendInit(); }); @@ -654,7 +654,7 @@ int main(int argc, char **argv) #if defined(Q_OS_WIN) graphicsApi = D3D11; -#elif defined(Q_OS_MACOS) || defined(Q_OS_IOS) +#elif QT_CONFIG(metal) graphicsApi = Metal; #elif QT_CONFIG(vulkan) graphicsApi = Vulkan; diff --git a/tests/manual/rhi/multiwindow_threaded/window.cpp b/tests/manual/rhi/multiwindow_threaded/window.cpp index 7b5ecf1634..d9c7340237 100644 --- a/tests/manual/rhi/multiwindow_threaded/window.cpp +++ b/tests/manual/rhi/multiwindow_threaded/window.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "window.h" #include <QPlatformSurfaceEvent> diff --git a/tests/manual/rhi/multiwindow_threaded/window.h b/tests/manual/rhi/multiwindow_threaded/window.h index da1269283a..e55e51de7d 100644 --- a/tests/manual/rhi/multiwindow_threaded/window.h +++ b/tests/manual/rhi/multiwindow_threaded/window.h @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef WINDOW_H #define WINDOW_H diff --git a/tests/manual/rhi/noninstanced/buildshaders.bat b/tests/manual/rhi/noninstanced/buildshaders.bat index fc274eeec2..c1e0fb4722 100644 --- a/tests/manual/rhi/noninstanced/buildshaders.bat +++ b/tests/manual/rhi/noninstanced/buildshaders.bat @@ -1,2 +1,4 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 material.vert -o material.vert.qsb qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 material.frag -o material.frag.qsb diff --git a/tests/manual/rhi/noninstanced/noninstanced.cpp b/tests/manual/rhi/noninstanced/noninstanced.cpp index 59850e2616..830dd4c84b 100644 --- a/tests/manual/rhi/noninstanced/noninstanced.cpp +++ b/tests/manual/rhi/noninstanced/noninstanced.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #define EXAMPLEFW_PREINIT #include "../shared/examplefw.h" diff --git a/tests/manual/rhi/offscreen/offscreen.cpp b/tests/manual/rhi/offscreen/offscreen.cpp index 04ce8543ac..86bf5ad5a9 100644 --- a/tests/manual/rhi/offscreen/offscreen.cpp +++ b/tests/manual/rhi/offscreen/offscreen.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QGuiApplication> #include <QImage> @@ -68,7 +68,7 @@ int main(int argc, char **argv) #if defined(Q_OS_WIN) graphicsApi = D3D11; -#elif defined(Q_OS_MACOS) || defined(Q_OS_IOS) +#elif QT_CONFIG(metal) graphicsApi = Metal; #elif QT_CONFIG(vulkan) graphicsApi = Vulkan; @@ -154,7 +154,7 @@ int main(int argc, char **argv) } #endif -#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) +#if QT_CONFIG(metal) if (graphicsApi == Metal) { QRhiMetalInitParams params; r = QRhi::create(QRhi::Metal, ¶ms, rhiFlags); diff --git a/tests/manual/rhi/polygonmode/buildshaders.bat b/tests/manual/rhi/polygonmode/buildshaders.bat index 3cd87ed7a2..d1c184109e 100755 --- a/tests/manual/rhi/polygonmode/buildshaders.bat +++ b/tests/manual/rhi/polygonmode/buildshaders.bat @@ -1,2 +1,4 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 qsb --glsl 320es,410,120 test.vert --msl 12 --hlsl 50 -o test.vert.qsb qsb --glsl 320es,410,120 test.frag --msl 12 --hlsl 50 -o test.frag.qsb diff --git a/tests/manual/rhi/polygonmode/polygonmode.cpp b/tests/manual/rhi/polygonmode/polygonmode.cpp index 88e9b47e39..466657ab03 100644 --- a/tests/manual/rhi/polygonmode/polygonmode.cpp +++ b/tests/manual/rhi/polygonmode/polygonmode.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" diff --git a/tests/manual/rhi/rhi.pro b/tests/manual/rhi/rhi.pro deleted file mode 100644 index 9238de6fc2..0000000000 --- a/tests/manual/rhi/rhi.pro +++ /dev/null @@ -1,30 +0,0 @@ -TEMPLATE = subdirs - -SUBDIRS += \ - hellominimalcrossgfxtriangle \ - compressedtexture_bc1 \ - compressedtexture_bc1_subupload \ - texuploads \ - msaatexture \ - msaarenderbuffer \ - cubemap \ - cubemap_scissor \ - cubemap_render \ - multiwindow \ - multiwindow_threaded \ - triquadcube \ - offscreen \ - floattexture \ - float16texture_with_compute \ - mrt \ - shadowmap \ - computebuffer \ - computeimage \ - instancing \ - noninstanced \ - tex3d - -qtConfig(widgets) { - SUBDIRS += \ - qrhiprof -} diff --git a/tests/manual/rhi/rhiwidget/CMakeLists.txt b/tests/manual/rhi/rhiwidgetproto/CMakeLists.txt index 97bfea5590..5b62ef557d 100644 --- a/tests/manual/rhi/rhiwidget/CMakeLists.txt +++ b/tests/manual/rhi/rhiwidgetproto/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause -qt_internal_add_manual_test(rhiwidget +qt_internal_add_manual_test(rhiwidgetproto GUI SOURCES examplewidget.cpp examplewidget.h @@ -20,14 +20,14 @@ set_source_files_properties("../shared/texture.vert.qsb" set_source_files_properties("../shared/texture.frag.qsb" PROPERTIES QT_RESOURCE_ALIAS "texture.frag.qsb" ) -set(rhiwidget_resource_files +set(rhiwidgetproto_resource_files "../shared/texture.vert.qsb" "../shared/texture.frag.qsb" ) -qt_internal_add_resource(rhiwidget "rhiwidget" +qt_internal_add_resource(rhiwidgetproto "rhiwidgetproto" PREFIX "/" FILES - ${rhiwidget_resource_files} + ${rhiwidgetproto_resource_files} ) diff --git a/tests/manual/rhi/rhiwidget/examplewidget.cpp b/tests/manual/rhi/rhiwidgetproto/examplewidget.cpp index 942766ac5c..6a6fd5b326 100644 --- a/tests/manual/rhi/rhiwidget/examplewidget.cpp +++ b/tests/manual/rhi/rhiwidgetproto/examplewidget.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "examplewidget.h" #include "../shared/cube.h" diff --git a/tests/manual/rhi/rhiwidget/examplewidget.h b/tests/manual/rhi/rhiwidgetproto/examplewidget.h index b85ae6f1f7..a17fe7bce1 100644 --- a/tests/manual/rhi/rhiwidget/examplewidget.h +++ b/tests/manual/rhi/rhiwidgetproto/examplewidget.h @@ -1,5 +1,5 @@ // Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef EXAMPLEWIDGET_H #define EXAMPLEWIDGET_H diff --git a/tests/manual/rhi/rhiwidget/main.cpp b/tests/manual/rhi/rhiwidgetproto/main.cpp index 8af531cd3b..a3b1741855 100644 --- a/tests/manual/rhi/rhiwidget/main.cpp +++ b/tests/manual/rhi/rhiwidgetproto/main.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QApplication> #include <QVBoxLayout> diff --git a/tests/manual/rhi/rhiwidget/rhiwidget.cpp b/tests/manual/rhi/rhiwidgetproto/rhiwidget.cpp index 2ba8721102..d535c655d0 100644 --- a/tests/manual/rhi/rhiwidget/rhiwidget.cpp +++ b/tests/manual/rhi/rhiwidgetproto/rhiwidget.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "rhiwidget_p.h" @@ -155,14 +155,7 @@ QPlatformBackingStoreRhiConfig QRhiWidgetPrivate::rhiConfig() const void QRhiWidgetPrivate::ensureRhi() { Q_Q(QRhiWidget); - // the QRhi and infrastructure belongs to the top-level widget, not to this widget - QWidget *tlw = q->window(); - QWidgetPrivate *wd = get(tlw); - - QRhi *currentRhi = nullptr; - if (QWidgetRepaintManager *repaintManager = wd->maybeRepaintManager()) - currentRhi = repaintManager->rhi(); - + QRhi *currentRhi = QWidgetPrivate::rhi(); if (currentRhi && currentRhi->backend() != QBackingStoreRhiSupport::apiToRhiBackend(config.api())) { qWarning("The top-level window is already using another graphics API for composition, " "'%s' is not compatible with this widget", diff --git a/tests/manual/rhi/rhiwidget/rhiwidget.h b/tests/manual/rhi/rhiwidgetproto/rhiwidget.h index 94cc108e28..0ac947b058 100644 --- a/tests/manual/rhi/rhiwidget/rhiwidget.h +++ b/tests/manual/rhi/rhiwidgetproto/rhiwidget.h @@ -1,5 +1,5 @@ // Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef RHIWIDGET_H #define RHIWIDGET_H diff --git a/tests/manual/rhi/rhiwidget/rhiwidget_p.h b/tests/manual/rhi/rhiwidgetproto/rhiwidget_p.h index b5cd058a94..da8ebc5c8f 100644 --- a/tests/manual/rhi/rhiwidget/rhiwidget_p.h +++ b/tests/manual/rhi/rhiwidgetproto/rhiwidget_p.h @@ -1,5 +1,5 @@ // Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef RHIWIDGET_P_H #define RHIWIDGET_P_H diff --git a/tests/manual/rhi/shadowmap/buildshaders.bat b/tests/manual/rhi/shadowmap/buildshaders.bat index 7b84cc0952..3e514a90b9 100644 --- a/tests/manual/rhi/shadowmap/buildshaders.bat +++ b/tests/manual/rhi/shadowmap/buildshaders.bat @@ -1,3 +1,5 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 qsb --glsl "120,300 es" --hlsl 50 --msl 12 -c shadowmap.vert -o shadowmap.vert.qsb qsb --glsl "120,300 es" --hlsl 50 --msl 12 -c shadowmap.frag -o shadowmap.frag.qsb qsb --glsl "120,300 es" --hlsl 50 --msl 12 -c main.vert -o main.vert.qsb diff --git a/tests/manual/rhi/shadowmap/shadowmap.cpp b/tests/manual/rhi/shadowmap/shadowmap.cpp index a37543b9fd..626d7d9c49 100644 --- a/tests/manual/rhi/shadowmap/shadowmap.cpp +++ b/tests/manual/rhi/shadowmap/shadowmap.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" #include "../shared/cube.h" diff --git a/tests/manual/rhi/shared/buildshaders.bat b/tests/manual/rhi/shared/buildshaders.bat index 59cd69716e..faa253c8bc 100644 --- a/tests/manual/rhi/shared/buildshaders.bat +++ b/tests/manual/rhi/shared/buildshaders.bat @@ -1,3 +1,5 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -c color.vert -o color.vert.qsb qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -c color.frag -o color.frag.qsb qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -c texture.vert -o texture.vert.qsb diff --git a/tests/manual/rhi/shared/dds_bc1.h b/tests/manual/rhi/shared/dds_bc1.h index aebf7fdac8..6d7236d068 100644 --- a/tests/manual/rhi/shared/dds_bc1.h +++ b/tests/manual/rhi/shared/dds_bc1.h @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only static const quint32 DDS_MAGIC = 0x20534444; // 'DDS ' static const quint32 DDS_FOURCC = 4; diff --git a/tests/manual/rhi/shared/examplefw.h b/tests/manual/rhi/shared/examplefw.h index 2bab0a9e68..f2ca57341c 100644 --- a/tests/manual/rhi/shared/examplefw.h +++ b/tests/manual/rhi/shared/examplefw.h @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only // Adapted from hellominimalcrossgfxtriangle with the frame rendering stripped out. // Include this file and implement Window::customInit, release and render. @@ -80,6 +80,8 @@ QRhi::BeginFrameFlags beginFrameFlags; QRhi::EndFrameFlags endFrameFlags; bool transparentBackground = false; bool debugLayer = true; +QRhiSwapChain::Format swapchainFormat = QRhiSwapChain::SDR; +float imguiHDRMultiplier = 0.0f; class Window : public QWindow { @@ -259,7 +261,7 @@ void Window::init() } #endif -#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) +#if QT_CONFIG(metal) if (graphicsApi == Metal) { QRhiMetalInitParams params; m_r = QRhi::create(QRhi::Metal, ¶ms, rhiFlags); @@ -280,6 +282,10 @@ void Window::init() m_sc->setDepthStencil(m_ds); m_sc->setSampleCount(sampleCount); m_sc->setFlags(scFlags); + if (!m_sc->isFormatSupported(swapchainFormat)) + qWarning("Swapchain reports that requested format %d is not supported", int(swapchainFormat)); + else + m_sc->setFormat(swapchainFormat); m_rp = m_sc->newCompatibleRenderPassDescriptor(); m_sc->setRenderPassDescriptor(m_rp); @@ -398,7 +404,7 @@ void Window::render() QMatrix4x4 guiMvp = m_r->clipSpaceCorrMatrix(); guiMvp.ortho(0, outputSizeInPixels.width() / dpr, outputSizeInPixels.height() / dpr, 0, 1, -1); - m_imguiRenderer->prepare(m_r, rt, cb, guiMvp, 1.0f); + m_imguiRenderer->prepare(m_r, rt, cb, guiMvp, 1.0f, imguiHDRMultiplier); #endif customRender(); @@ -420,7 +426,7 @@ int main(int argc, char **argv) // Defaults. #if defined(Q_OS_WIN) graphicsApi = D3D11; -#elif defined(Q_OS_MACOS) || defined(Q_OS_IOS) +#elif QT_CONFIG(metal) graphicsApi = Metal; #elif QT_CONFIG(vulkan) graphicsApi = Vulkan; diff --git a/tests/manual/rhi/shared/imgui/buildshaders.bat b/tests/manual/rhi/shared/imgui/buildshaders.bat index eec4e3a070..560c634134 100644 --- a/tests/manual/rhi/shared/imgui/buildshaders.bat +++ b/tests/manual/rhi/shared/imgui/buildshaders.bat @@ -1,2 +1,4 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -c imgui.vert -o imgui.vert.qsb qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -c imgui.frag -o imgui.frag.qsb diff --git a/tests/manual/rhi/shared/imgui/imgui.frag b/tests/manual/rhi/shared/imgui/imgui.frag index 51bd615deb..6169dd639f 100644 --- a/tests/manual/rhi/shared/imgui/imgui.frag +++ b/tests/manual/rhi/shared/imgui/imgui.frag @@ -8,14 +8,30 @@ layout(location = 0) out vec4 fragColor; layout(std140, binding = 0) uniform buf { mat4 mvp; float opacity; + // Windows HDR: set to SDR_white_level_in_nits / 80 + // macOS/iOS EDR: set to 1.0 + // No HDR: set to 0.0, will do linear to sRGB at the end then. + float hdrWhiteLevelMult; }; layout(binding = 1) uniform sampler2D tex; +vec3 linearToSRGB(vec3 color) +{ + vec3 S1 = sqrt(color); + vec3 S2 = sqrt(S1); + vec3 S3 = sqrt(S2); + return 0.585122381 * S1 + 0.783140355 * S2 - 0.368262736 * S3; +} + void main() { vec4 c = v_color * texture(tex, v_texcoord); c.a *= opacity; - c.rgb *= c.a; + if (hdrWhiteLevelMult > 0.0) + c.rgb *= hdrWhiteLevelMult; + else + c.rgb = linearToSRGB(c.rgb); + c.rgb *= c.a; // premultiplied alpha fragColor = c; } diff --git a/tests/manual/rhi/shared/imgui/imgui.frag.qsb b/tests/manual/rhi/shared/imgui/imgui.frag.qsb Binary files differindex 2abf236f56..09b1e44697 100644 --- a/tests/manual/rhi/shared/imgui/imgui.frag.qsb +++ b/tests/manual/rhi/shared/imgui/imgui.frag.qsb diff --git a/tests/manual/rhi/shared/imgui/imgui.vert b/tests/manual/rhi/shared/imgui/imgui.vert index bb24a22c13..45510ea0fe 100644 --- a/tests/manual/rhi/shared/imgui/imgui.vert +++ b/tests/manual/rhi/shared/imgui/imgui.vert @@ -10,6 +10,7 @@ layout(location = 1) out vec4 v_color; layout(std140, binding = 0) uniform buf { mat4 mvp; float opacity; + float sdrMult; }; void main() diff --git a/tests/manual/rhi/shared/imgui/imgui.vert.qsb b/tests/manual/rhi/shared/imgui/imgui.vert.qsb Binary files differindex 0f2300f676..3ee5a7b716 100644 --- a/tests/manual/rhi/shared/imgui/imgui.vert.qsb +++ b/tests/manual/rhi/shared/imgui/imgui.vert.qsb diff --git a/tests/manual/rhi/shared/imgui/qrhiimgui.cpp b/tests/manual/rhi/shared/imgui/qrhiimgui.cpp index d4330238b9..88b0a5d897 100644 --- a/tests/manual/rhi/shared/imgui/qrhiimgui.cpp +++ b/tests/manual/rhi/shared/imgui/qrhiimgui.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2022 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "qrhiimgui_p.h" #include <QtCore/qfile.h> @@ -48,7 +48,12 @@ void QRhiImguiRenderer::releaseResources() m_rhi = nullptr; } -void QRhiImguiRenderer::prepare(QRhi *rhi, QRhiRenderTarget *rt, QRhiCommandBuffer *cb, const QMatrix4x4 &mvp, float opacity) +void QRhiImguiRenderer::prepare(QRhi *rhi, + QRhiRenderTarget *rt, + QRhiCommandBuffer *cb, + const QMatrix4x4 &mvp, + float opacity, + float hdrWhiteLevelMultiplierOrZeroForSDRsRGB) { if (!m_rhi) { m_rhi = rhi; @@ -89,7 +94,7 @@ void QRhiImguiRenderer::prepare(QRhi *rhi, QRhiRenderTarget *rt, QRhiCommandBuff } if (!m_ubuf) { - m_ubuf.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64 + 4)); + m_ubuf.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64 + 4 + 4)); m_ubuf->setName(QByteArrayLiteral("imgui uniform buffer")); if (!m_ubuf->create()) return; @@ -201,6 +206,7 @@ void QRhiImguiRenderer::prepare(QRhi *rhi, QRhiRenderTarget *rt, QRhiCommandBuff u->updateDynamicBuffer(m_ubuf.get(), 0, 64, mvp.constData()); u->updateDynamicBuffer(m_ubuf.get(), 64, 4, &opacity); + u->updateDynamicBuffer(m_ubuf.get(), 68, 4, &hdrWhiteLevelMultiplierOrZeroForSDRsRGB); for (int i = 0; i < texturesNeedUpdate.count(); ++i) { Texture &t(m_textures[texturesNeedUpdate[i]]); diff --git a/tests/manual/rhi/shared/imgui/qrhiimgui_p.h b/tests/manual/rhi/shared/imgui/qrhiimgui_p.h index 31782144bf..ec86c2af7f 100644 --- a/tests/manual/rhi/shared/imgui/qrhiimgui_p.h +++ b/tests/manual/rhi/shared/imgui/qrhiimgui_p.h @@ -1,5 +1,5 @@ // Copyright (C) 2022 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef QRHIIMGUI_P_H #define QRHIIMGUI_P_H @@ -45,7 +45,12 @@ public: StaticRenderData sf; FrameRenderData f; - void prepare(QRhi *rhi, QRhiRenderTarget *rt, QRhiCommandBuffer *cb, const QMatrix4x4 &mvp, float opacity); + void prepare(QRhi *rhi, + QRhiRenderTarget *rt, + QRhiCommandBuffer *cb, + const QMatrix4x4 &mvp, + float opacity = 1.0f, + float hdrWhiteLevelMultiplierOrZeroForSDRsRGB = 0.0f); void render(); void releaseResources(); diff --git a/tests/manual/rhi/stenciloutline/buildshaders.bat b/tests/manual/rhi/stenciloutline/buildshaders.bat index fc274eeec2..c1e0fb4722 100644 --- a/tests/manual/rhi/stenciloutline/buildshaders.bat +++ b/tests/manual/rhi/stenciloutline/buildshaders.bat @@ -1,2 +1,4 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 material.vert -o material.vert.qsb qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 material.frag -o material.frag.qsb diff --git a/tests/manual/rhi/stenciloutline/stenciloutline.cpp b/tests/manual/rhi/stenciloutline/stenciloutline.cpp index bdf7f217b1..dfa4cdbbff 100644 --- a/tests/manual/rhi/stenciloutline/stenciloutline.cpp +++ b/tests/manual/rhi/stenciloutline/stenciloutline.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" #include "../shared/cube.h" diff --git a/tests/manual/rhi/stereo/main.cpp b/tests/manual/rhi/stereo/main.cpp index 7ab1448217..cae25c8d24 100644 --- a/tests/manual/rhi/stereo/main.cpp +++ b/tests/manual/rhi/stereo/main.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2022 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only // This is a demo showing stereoscopic rendering. // For now, the backend is hardcoded to be OpenGL, because that's the only @@ -22,7 +22,7 @@ int main(int argc, char **argv) QSurfaceFormat::setDefaultFormat(fmt); - Window w; + Window w{QRhi::Vulkan}; w.resize(1280, 720); w.setTitle(QCoreApplication::applicationName()); w.show(); diff --git a/tests/manual/rhi/stereo/window.cpp b/tests/manual/rhi/stereo/window.cpp index 391e8b75fc..18e1ecc409 100644 --- a/tests/manual/rhi/stereo/window.cpp +++ b/tests/manual/rhi/stereo/window.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2022 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "window.h" #include <QPlatformSurfaceEvent> @@ -8,9 +8,25 @@ #include <rhi/qshader.h> #include "../shared/cube.h" -Window::Window() +Window::Window(QRhi::Implementation graphicsApi) + :m_graphicsApi(graphicsApi) { - setSurfaceType(OpenGLSurface); + switch (graphicsApi) { + default: + case QRhi::OpenGLES2: + setSurfaceType(OpenGLSurface); + break; + case QRhi::Vulkan: + instance.setLayers({ "VK_LAYER_KHRONOS_validation" }); + instance.create(); + setVulkanInstance(&instance); + setSurfaceType(VulkanSurface); + break; + case QRhi::D3D11: + case QRhi::D3D12: + setSurfaceType(Direct3DSurface); + break; + } } void Window::exposeEvent(QExposeEvent *) @@ -57,11 +73,44 @@ void Window::init() { QRhi::Flags rhiFlags = QRhi::EnableDebugMarkers; - m_fallbackSurface.reset(QRhiGles2InitParams::newFallbackSurface()); - QRhiGles2InitParams params; - params.fallbackSurface = m_fallbackSurface.get(); - params.window = this; - m_rhi.reset(QRhi::create(QRhi::OpenGLES2, ¶ms, rhiFlags)); + switch (m_graphicsApi) { + case QRhi::Vulkan: + { + QRhiVulkanInitParams params; + params.window = this; + params.inst = vulkanInstance(); + m_rhi.reset(QRhi::create(QRhi::Vulkan, ¶ms, rhiFlags)); + break; + } + case QRhi::Null: + case QRhi::Metal: + case QRhi::OpenGLES2: + { + m_fallbackSurface.reset(QRhiGles2InitParams::newFallbackSurface()); + QRhiGles2InitParams params; + params.fallbackSurface = m_fallbackSurface.get(); + params.window = this; + m_rhi.reset(QRhi::create(QRhi::OpenGLES2, ¶ms, rhiFlags)); + break; + } +#ifdef Q_OS_WIN + case QRhi::D3D11: + { + QRhiD3D11InitParams params; + m_rhi.reset(QRhi::create(QRhi::D3D11, ¶ms, rhiFlags)); + break; + } + case QRhi::D3D12: + { + QRhiD3D12InitParams params; + params.enableDebugLayer = true; + m_rhi.reset(QRhi::create(QRhi::D3D12, ¶ms, rhiFlags)); + break; + } +#endif + default: + break; + } m_sc.reset(m_rhi->newSwapChain()); m_ds.reset(m_rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, diff --git a/tests/manual/rhi/stereo/window.h b/tests/manual/rhi/stereo/window.h index ea35040a7a..0a175e31a0 100644 --- a/tests/manual/rhi/stereo/window.h +++ b/tests/manual/rhi/stereo/window.h @@ -1,5 +1,5 @@ // Copyright (C) 2022 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef WINDOW_H #define WINDOW_H @@ -11,17 +11,19 @@ class Window : public QWindow { public: - Window(); + Window(QRhi::Implementation graphicsApi); void releaseSwapChain(); protected: + QVulkanInstance instance; std::unique_ptr<QOffscreenSurface> m_fallbackSurface; std::unique_ptr<QRhi> m_rhi; std::unique_ptr<QRhiSwapChain> m_sc; std::unique_ptr<QRhiRenderBuffer> m_ds; std::unique_ptr<QRhiRenderPassDescriptor> m_rp; + QRhi::Implementation m_graphicsApi; bool m_hasSwapChain = false; QMatrix4x4 m_proj; diff --git a/tests/manual/rhi/tessellation/buildshaders.bat b/tests/manual/rhi/tessellation/buildshaders.bat index bc992dc28c..61345d1906 100644 --- a/tests/manual/rhi/tessellation/buildshaders.bat +++ b/tests/manual/rhi/tessellation/buildshaders.bat @@ -1,3 +1,5 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 qsb --glsl 320es,410 --hlsl 50 --msl 12 --msltess test.vert -o test.vert.qsb qsb --glsl 320es,410 --msl 12 --tess-mode triangles test.tesc -o test.tesc.qsb qsb -r hlsl,50,test_hull.hlsl test.tesc.qsb diff --git a/tests/manual/rhi/tessellation/tessellation.cpp b/tests/manual/rhi/tessellation/tessellation.cpp index c746e6f83b..a50ddeeeb2 100644 --- a/tests/manual/rhi/tessellation/tessellation.cpp +++ b/tests/manual/rhi/tessellation/tessellation.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" diff --git a/tests/manual/rhi/tex1d/buildshaders.bat b/tests/manual/rhi/tex1d/buildshaders.bat index 37934cf362..27bb8fc0e6 100644 --- a/tests/manual/rhi/tex1d/buildshaders.bat +++ b/tests/manual/rhi/tex1d/buildshaders.bat @@ -1,2 +1,4 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 qsb --glsl "120,150,300 es" --hlsl 50 --msl 12 -c texture1d.vert -o texture1d.vert.qsb qsb --glsl "120,150,300 es" --hlsl 50 --msl 12 -c texture1d.frag -o texture1d.frag.qsb diff --git a/tests/manual/rhi/tex1d/tex1d.cpp b/tests/manual/rhi/tex1d/tex1d.cpp index 66e0186b0f..7791c840ca 100644 --- a/tests/manual/rhi/tex1d/tex1d.cpp +++ b/tests/manual/rhi/tex1d/tex1d.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" #include <QImage> diff --git a/tests/manual/rhi/tex3d/buildshaders.bat b/tests/manual/rhi/tex3d/buildshaders.bat index 041c554688..699d2b112b 100644 --- a/tests/manual/rhi/tex3d/buildshaders.bat +++ b/tests/manual/rhi/tex3d/buildshaders.bat @@ -1,2 +1,4 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 qsb --glsl "300 es,150" --hlsl 50 --msl 12 -c texture3d.vert -o texture3d.vert.qsb qsb --glsl "300 es,150" --hlsl 50 --msl 12 -c texture3d.frag -o texture3d.frag.qsb diff --git a/tests/manual/rhi/tex3d/tex3d.cpp b/tests/manual/rhi/tex3d/tex3d.cpp index d98ae2fe45..33c4cab8d1 100644 --- a/tests/manual/rhi/tex3d/tex3d.cpp +++ b/tests/manual/rhi/tex3d/tex3d.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" #include <QImage> diff --git a/tests/manual/rhi/texturearray/texturearray.cpp b/tests/manual/rhi/texturearray/texturearray.cpp index 0a354dd53a..241f440e01 100644 --- a/tests/manual/rhi/texturearray/texturearray.cpp +++ b/tests/manual/rhi/texturearray/texturearray.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" #include <QElapsedTimer> diff --git a/tests/manual/rhi/texuploads/texuploads.cpp b/tests/manual/rhi/texuploads/texuploads.cpp index 566bc48474..5723d19be9 100644 --- a/tests/manual/rhi/texuploads/texuploads.cpp +++ b/tests/manual/rhi/texuploads/texuploads.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../shared/examplefw.h" #include "../shared/cube.h" @@ -192,7 +192,7 @@ void Window::customRender() if (d.testStage == 6) { const QRhiTexture::NativeTexture nativeTexture = d.tex->nativeTexture(); if (nativeTexture.object) { -#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) +#if QT_CONFIG(metal) if (graphicsApi == Metal) { qDebug() << "Metal texture: " << nativeTexture.object; // Now could cast to id<MTLTexture> and do something with diff --git a/tests/manual/rhi/triquadcube/quadrenderer.cpp b/tests/manual/rhi/triquadcube/quadrenderer.cpp index 09c2047c35..67392dc583 100644 --- a/tests/manual/rhi/triquadcube/quadrenderer.cpp +++ b/tests/manual/rhi/triquadcube/quadrenderer.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "quadrenderer.h" #include <QFile> diff --git a/tests/manual/rhi/triquadcube/quadrenderer.h b/tests/manual/rhi/triquadcube/quadrenderer.h index f8757992ff..8e5b556e06 100644 --- a/tests/manual/rhi/triquadcube/quadrenderer.h +++ b/tests/manual/rhi/triquadcube/quadrenderer.h @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef QUADRENDERER_H #define QUADRENDERER_H diff --git a/tests/manual/rhi/triquadcube/texturedcuberenderer.cpp b/tests/manual/rhi/triquadcube/texturedcuberenderer.cpp index 8e73194fc8..452c593e16 100644 --- a/tests/manual/rhi/triquadcube/texturedcuberenderer.cpp +++ b/tests/manual/rhi/triquadcube/texturedcuberenderer.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "texturedcuberenderer.h" #include <QFile> diff --git a/tests/manual/rhi/triquadcube/texturedcuberenderer.h b/tests/manual/rhi/triquadcube/texturedcuberenderer.h index 0972ad6d46..53fc9a30d1 100644 --- a/tests/manual/rhi/triquadcube/texturedcuberenderer.h +++ b/tests/manual/rhi/triquadcube/texturedcuberenderer.h @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef TEXTUREDCUBERENDERER_H #define TEXTUREDCUBERENDERER_H diff --git a/tests/manual/rhi/triquadcube/triangleoncuberenderer.cpp b/tests/manual/rhi/triquadcube/triangleoncuberenderer.cpp index 683134589e..33dc0776d7 100644 --- a/tests/manual/rhi/triquadcube/triangleoncuberenderer.cpp +++ b/tests/manual/rhi/triquadcube/triangleoncuberenderer.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "triangleoncuberenderer.h" #include <QFile> diff --git a/tests/manual/rhi/triquadcube/triangleoncuberenderer.h b/tests/manual/rhi/triquadcube/triangleoncuberenderer.h index ae8134601e..9d77feb253 100644 --- a/tests/manual/rhi/triquadcube/triangleoncuberenderer.h +++ b/tests/manual/rhi/triquadcube/triangleoncuberenderer.h @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef TRIANGLEONCUBERENDERER_H #define TRIANGLEONCUBERENDERER_H diff --git a/tests/manual/rhi/triquadcube/trianglerenderer.cpp b/tests/manual/rhi/triquadcube/trianglerenderer.cpp index 46f6e0dec4..21e3e791b4 100644 --- a/tests/manual/rhi/triquadcube/trianglerenderer.cpp +++ b/tests/manual/rhi/triquadcube/trianglerenderer.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "trianglerenderer.h" #include <QFile> diff --git a/tests/manual/rhi/triquadcube/trianglerenderer.h b/tests/manual/rhi/triquadcube/trianglerenderer.h index e6e3d0c0a9..bad2198be5 100644 --- a/tests/manual/rhi/triquadcube/trianglerenderer.h +++ b/tests/manual/rhi/triquadcube/trianglerenderer.h @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef TRIANGLERENDERER_H #define TRIANGLERENDERER_H diff --git a/tests/manual/rhi/triquadcube/triquadcube.cpp b/tests/manual/rhi/triquadcube/triquadcube.cpp index 3be0291779..2ef0d567db 100644 --- a/tests/manual/rhi/triquadcube/triquadcube.cpp +++ b/tests/manual/rhi/triquadcube/triquadcube.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only // An example exercising more than a single feature. Enables profiling // (resource logging to a file) and inserts debug markers and sets some |