Having a simple Dear ImGui bridge is not just useful for the manual
tests, which do not have any other means to displays GUIs, but is
in itself an important exercise for the QRhi machinery.
Have a new manual test that exercises the built-in ImGui demo window.
Then use it in the displacement test for real, to replace the myriads
of key presses with on-screen sliders and checkboxes (with less code).
Change-Id: I296bafae2a5cce6fc7a447d97e68e5bcec15f451
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This does not really belong here as a built-in feature, esp.
considering that such testing is relevant for other backends
as well.
Change-Id: Ifbe3b8c6a430aacb9fcbdabf0e3761b14c48decc
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
There is something odd when running on Metal: note how the uv
is vec3 instead of vec2, in order to make the vertex-tesc-tese
data to look like this:
struct main0_out
{
float3 out_uv;
float3 out_normal;
float4 gl_Position;
};
if out_uv was float2 we'd get some strange rendering results,
perhaps due to something related to alignment. But have no means
to investigate this further.
Change-Id: I79d4edb2ddde3971c599c4326d98e99a49aa7122
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
- The optional nice-to-haves DebugMarkers, Timestamps, PipelineCache
are not yet implemented (features reported as false, to be
implemented later, although buffer/texture resource name setting
already works as-is, regardless of DebugMarkers).
- Mipmap generation for 3D textures is missing. Won't matter much
given that 3D textures are not used in Qt for anything atm. For
generating mipmaps for 2D (or 2D array) textures, the MiniEngine
compute shader and approach is used. 3D support for the mipmap
generator may be added later. 1D textures / arrays are supported
except for mipmap generation, and so the
OneDimensionalTextureMipmaps feature is reported as false.
- Qt Quick and Qt Quick 3D are expected to be fully functional.
(unforeseen issues are not impossible, of course)
- Uses minimum feature level 11.0 when requesting the device. It is
expected to be functional on resource binding tier 1 hardware even,
although this has not been verified in practice.
- 2 frames in flight with the usual resource buffering
(QRhiBuffer::Dynamic is host visible (UPLOAD) and always mapped and
slotted, other buffers and textures are device local (DEFAULT).
Requests 3 swapchain buffers. Swapchains are mostly like with D3D11
(e.g. FLIP_DISCARD and SCALING_NONE).
- The root signature generation is somewhat limited by the SPIR-V
binding model and that we need to map every binding point using the
nativeResourceBindingMap from the QShader. Thus the root signature
is laid out so each stage has its own set of resources, with shader
register clashes being prevented by setting the visibility to a
given stage.
Sampler handling is somewhat suboptimal but we are tied by the
binding model and existing API design. It is in a fairly special
situation due to the 2048 limit on a shader visible sampler heap, as
opposed to 1000000 for SRVs and UAVS, so the approach we use for
textures (just stage the CPU SRVs on the (per-frame slot) shader
visible heap as they are encountered, effectively treating the heap
as a ring buffer) would quickly lead to having to switch heaps many
times with scenes with many draw calls and sampledTexture/sampler
bindings in the srb.
Whereas static samplers, which would be beautiful, are impossible to
utilize safely since we do not have that concept (i.e. samplers
specified upfront, tied to the graphics/compute pipeline) in the
QRhi API, and an srb used at pipeline creation may change its
associated resources, such as the QRhiSampler reference, by the time
the shader resources are set for the draw call (or another,
compatible srb may get used altogether), so specifying the samplers
at root signature creation time is impossible.
Rather, the current approach is to treat each sampler as a separate
root parameter (per stage) having a descriptor table with a single
entry. The shader visible sampler heap has exactly one instance of
each unique sampler encountered during the lifetime of the QRhi.
- Shader-wise no different from D3D11, works with HLSL/DXBC 5.0
(i.e. existing .qsb files with DXBC in them work as-is). But unlike
D3D11, this one will try to pick 6.7, 6.6, ..., down to 5.0 from the
QShader, in that order.
- Uses D3D12MA for suballocating. As a result it can report vmem
allocation statistics like the Vulkan backend, and it does more
since the DXGI memory usage (incl. implicit resources) is also
reported. This is optional technically, so we also have the option
of going straight with the heavyweight CreateCommittedResource()
instead. That is what we do if the adapter chosen reports it's
software-based or when QT_D3D_NO_SUBALLOC=1 is set.
- PreferSoftwareRenderer (picking the WARP device) and the env.var.
QT_D3D_ADAPTER_INDEX work as with the D3D11 backend.
- It is not unexpected that with large scenes that generate lots of
draw calls with multiple textures/samplers per call the performance
may be slightly below D3D11 (probably mostly due to descriptor
management). Similarly, the reported memory usage will be higher,
which is partly natural due to creating heaps, descriptor pools,
staging areas, etc. upfront. Will need to be evaluated later how
these can be tuned.
Change-Id: I5a42580bb65f391ebceaf81adc6ae673cceacb74
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Interesting on its own just because it exercises stencil testing,
unlike any of the other existing manual tests.
In addition it serves as a base example for how outlines could be
done, it is one possible approach at least. (render with stencil
write, then render again slightly scaled up with a solid color with
testing against the stencil buffer content)
Change-Id: I0c845a9004136f229cab037f6f0aab2f772bdd76
Reviewed-by: Christian Strømme <christian.stromme@qt.io>
...by removing the entire adjustedFormat() helper.
Qt Quick has never used this, which indicates it is not that
useful. Same goes for Qt Multimedia or Qt 3D. Ensuring depth and
stencil is requested is already solved by using
QSurfaceFormat::setDefaultFormat() or by adjusting the formats
everywhere as appropriate.
The helper function's usages are in the manual tests that use it as a
shortcut, and in the GL backend itself. Remove it and leave it up the
client to set the depth or stencil buffer size, typically in the
global default surface format. (which in fact many of the mentioned
manual tests already did, so some of calls to
window->setFormat(adjustedFormat()) were completely unnecessary)
By not having the built-in magic that tries to always force depth and
stencil, we avoid problems that arise then the helper cannot be easily
invoked (thinking of widgets and backingstores), and so one ends up
with unexpected stencil (or depth) in the context (where the GL
backend auto-adjusts), but not in the window (which is not under
QRhi's control).
It was in practice possible to trigger EGL_BAD_MATCH failures with the
new rhi-based widget composition on EGL-based systems. For example, if
an application with a QOpenGLWidget did not set both depth and stencil
(but only one, or none), it ended up failing due to the context -
surface EGLConfig mismatches. On other platforms this matters less due
to less strict config/pixelformat management.
Pick-to: 6.4
Change-Id: I28ae2de163de63ee91bee3ceae08b58e106e1380
Fixes: QTBUG-104951
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Replace the current license disclaimer in files by
a SPDX-License-Identifier.
Files that have to be modified by hand are modified.
License files are organized under LICENSES directory.
Task-number: QTBUG-67283
Change-Id: Id880c92784c40f3bbde861c0d93f58151c18b9f1
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
The system we inherited from the original Qt 5.14 introduction of QRhi
is a text stream based solution where resource creation and frame
timings are sent in a comma-separated format to a QIODevice.
This, while useful to get insights about the number of resources at a
given time, is not actively helpful. The frameworks built on top (Qt
Quick, Qt Quick 3D) are expected to provide solutions for logging
timings in a different way (e.g. via the QML Profiler). Similarly,
tracking active resources and generating statistics from that is
better handled on a higher level.
The unique bits, such as the Vulkan memory allocator statistics and
the GPU frame timestamps, are converted into APIs in QRhi. This way a
user of QRhi can query it at any time and do whatever it sees fit with
the data.
When it comes to the GPU timestamps, that has a somewhat limited value
due to the heavy asynchronousness, hence the callback based
API. Nonetheless, this is still useful since it is the only means of
reporting some frame timing data (an approx. elapsed milliseconds for
a frame) from the GPU side.
Change-Id: I67cd58b81aaa7e343c11731f9aa5b4804c2a1823
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Arrays of textures have always been supported, but we will encounter
cases when we need to work with texture array objects as well.
Note that currently it is not possible to expose only a slice of the
array to the shader, because there is no dedicated API in the SRB,
and thus the same SRV/UAV (or equivalent) is used always, capturing
all elements in the array. Therefore in the shader the last component
of P in texture() is in range 0..array_size-1.
Change-Id: I5a032ed016aeefbbcd743d5bfb9fbc49ba00a1fa
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
QT_VERSION is now at least QT_VERSION_CHECK(6, 3, 0), so remove all
checks against Qt 6.0.0 or earlier. They are superfluous. Tidied up in
some places in the process, particularly #include order.
Change-Id: I2636b2fd13be5b976f5b043ef2f8cddc038a72a4
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Supported on OpenGL (and ES) 3.0+ and everywhere else.
Can also be a render target, targeting a single slice at a time.
Can be mipmapped, cannot be multisample.
Reading back a given slice from a 3D texture is left as a future
exercise, for now it is documented to be not supported.
Upload is going to be limited to one slice in one upload entry,
just like we specify one face or one miplevel for cubemap and
mipmapped textures.
This also involves some welcome hardening of how texture subresources
are described internally: as we no longer can count on a layer index
between 0..5 (as is the case with cubemaps), simply arrays with
MAX_LAYER==6 are no longer sufficient. Switch to sufficiently dynamic
data structures where applicable.
On Vulkan rendering to a slice needs Vulkan 1.1 (and 1.1 enabled on the
VkInstance).
Task-number: QTBUG-89703
Change-Id: Ide6c20124ec9201d94ffc339dd479cd1ece777b0
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Instead, have a static function in QRhiVulkanInitParams then Qt Quick
and anyone else who creates a QVulkanInstance that is then used in
combination with QRhi can query.
Change-Id: I046e0d84541fc00f5487a7527c97be262221527f
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Even though there is no D3D-specific logic in the windows platform
plugin, meaning a QWindow with either OpenGLSurface or VulkanSurface
(or anything really) is DXGI/D3D-compatible, it now looks like it is
beneficial, and more future proof, if there is a dedicated surface
type.
As the linked report shows, there are OpenGL-specific workarounds
accumulated in the platform plugin, while not being clear if these
are relevant to non-OpenGL content, or if they are relevant at all
still. (and some of these can be difficult/impossible to retest and
verify in practice)
When D3D-based windows use the same surface type, all these are
active for those windows as well, while Vulkan-based windows have
their own type and so some of these old workarounds are not active
for those. To reduce confusion, having a dedicated surface type for
D3D as well allows the logic to skip the old OpenGL workarounds,
giving us (and users) a more clear overall behavior when it comes
to OpenGL vs. Vulkan vs. D3D.
The change is compatible with any existing code in other modules
because any code that uses OpenGLSurface for D3D will continue to
work, using the new type can be introduced incrementally.
Task-number: QTBUG-89715
Change-Id: Ieba86a580bf5a3636730952184dc3a3ab7669b26
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Draw 25000 cubes while doing a uniform buffer update for each.
Change-Id: I2216641c8bf7c6ea147fe3edd679317b472e1f04
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
This attribute is now on by default.
Change-Id: I7c9d2e3445d204d3450758673048d514bc9c850c
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
...now that a recent path enables MultisampleTextures for ES >= 3.1 and
GL 3.x and up.
Just need to make sure the .qsb contains something for OpenGL as well.
While we are at it, make updated .qsb files for all the commonly used
shaders since what we had before was version 4. Bump them to version 5.
Change-Id: If2040f4894e6360d1ebd5daf7e698508e5e6e42e
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
For historical reasons we use build and release instead of create and
destroy. This becomes confusing now that more modules in Qt start taking
QRhi into use. Migrate to the more familiar naming, so those who have
used QWindow or QOpenGLContext before will find it natural.
Change-Id: I05eb2243ce274c59b03a5f8bcbb2792a4f37120f
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
They are now version 4, which is hopefully the final format,
relying on nothing but QDataStream.
Except for the qshader autotest which tests all the 1..4 versions
and so needs appropriate test data.
Also unifies the batch file naming.
Change-Id: Iec478be86d14dbec7ffb9d5f9b62c14fca5d7c9e
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
What's more, demonstrate two types of rendering to a cubemap:
one by one to each face, and by attaching all faces as color
attachments in one go.
Both are used by Qt Quick 3D in connection with shadows, so this
proves that the same is possible to implement with QRhi.
Task-number: QTBUG-81261
Change-Id: I5c7077224d7cae0dd6ea02ac30a9e6f9f1f0c229
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
While we are at it, remove the Border and MirrorOnce wrap modes that have
not been supported on OpenGL, because they are unsupported with Metal+iOS
as well.
Task-number: QTBUG-78580
Change-Id: I0db94b9d3a6125b3bb5d7b1db5d02a42cd94d2c2
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This was used to support QFlags f = 0 initialization, but with 0 used
as a pointer literal now considered bad form, it had been changed many
places to QFlags f = nullptr, which is meaningless and confusing.
Change-Id: I4bc592151c255dc5cab1a232615caecc520f02e8
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Revert surfacePixelSize() to be a getter only. With Metal this will
mean returning the "live" layer size (and so not the
layer.drawableSize), which is in line with what we expect with other
backends.
Instead, we leave it to the swapchain's buildOrResize() to "commit"
the size by setting drawableSize on the layer. With typical
application or Qt Quick logic this ensures that layer.drawableSize is
set once and stays static until we get to process the next resize - on
the rendering thread.
This of course would still mean that there was a race when a client
queries surfacePixelSize() to set the depth-stencil buffer size that
is associated with a swapchain. (because that must happen before
calling buildOrResize() according to the current semantics)
That can however be solved in a quite elegant way, it turns out,
because we already have a flag that indicates if a QRhiRenderBuffer is
used in combination with (and only in combination with) a
swapchain. If we simply say that setting the UsedWithSwapChainOnly
flag provides automatic sizing as well (so no setPixelSize() call is
needed), clients can simply get rid of the problematic
surfacePixelSize() query and everything works.
Task-number: QTBUG-78641
Change-Id: Ib1bfc9ef8531bcce033d1f1e5d4d5b4984d6d69f
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
It can be important to see for example the adapter enumeration that is
printed when qt.rhi.general is enabled. Make it enabled by default in
the tests.
Change-Id: I7bd073781e176d9b17b5386c548e9f8a2e16c10f
Reviewed-by: Christian Strømme <christian.stromme@qt.io>
This will also cause clearing to 0,0,0,0.
Essential in order to allow fast testing of window transparency
issues in combination with QRhi and the various backends.
Change-Id: Iee2763c1d06f1d3e5d59a9142abaf30fab1dc543
Reviewed-by: Christian Strømme <christian.stromme@qt.io>
...if there is one and the concept is applicable in the first place.
Change-Id: Iab202c1c1cdd229f4910159de4cae7ce30805ea9
Reviewed-by: Christian Strømme <christian.stromme@qt.io>
The device can be lost when physically removing the graphics adapter,
disabling the driver (Device Manager), upgrading/uninstalling the
graphics driver, and when it is reset due to an error.
Some of these can (and should) be tested manually, but the last
one has a convenient, programmatic way of triggering: by triggering
the timeout detection and recovery (TDR) of WDDM. A compute shader
with an infinite loop should trigger this after 2 seconds by default.
All tests in tests/manual/rhi can now be started with a --curse <count>
argument where <count> specifies the number of frames to render before
breaking the device. Qt Quick will get an environment variable with
similar semantics in a separate patch.
Change-Id: I4b6f8d977a15b5b89d686b3973965df6435810ae
Reviewed-by: Christian Strømme <christian.stromme@qt.io>
As an option. Must opt in via setting ExternalContentsInPass in
the flags for beginFrame(). It is somewhat unfortunate to require
declaring this up front, but forcing using secondary command buffers
always, even though beginExternal() may not be used in many applications,
would be an overkill.
Change-Id: I8d52bcab40c96f89f140c4c7877b6c459925e3c7
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Comes with backends for Vulkan, Metal, Direct3D 11.1, and OpenGL (ES).
All APIs are private for now.
Shader conditioning (i.e. generating a QRhiShader in memory or on disk
from some shader source code) is done via the tools and APIs provided
by qt-labs/qtshadertools.
The OpenGL support follows the cross-platform tradition of requiring
ES 2.0 only, while optionally using some (ES) 3.x features. It can
operate in core profile contexts as well.
Task-number: QTBUG-70287
Change-Id: I246f2e36d562e404012c05db2aa72487108aa7cc
Reviewed-by: Lars Knoll <lars.knoll@qt.io>