rhi: Add D3D12 support

- 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>
This commit is contained in:
Laszlo Agocs 2022-08-12 12:01:41 +02:00
parent 19c32e7ee7
commit 84fb0de413
25 changed files with 21933 additions and 34 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,19 @@
Copyright (c) 2019-2022 Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,91 @@
From d83bc556c26b13e1a243c71628f75ef624de05bf Mon Sep 17 00:00:00 2001
From: Laszlo Agocs <laszlo.agocs@qt.io>
Date: Sat, 21 Jan 2023 20:07:00 +0100
Subject: [PATCH] Eliminate warnings in D3D12MA
Change-Id: If703c50cc1239248b94967edb4047868aaf07f1a
---
.../D3D12MemoryAllocator/D3D12MemAlloc.cpp | 23 ++++++++++++++++++-
.../D3D12MemoryAllocator/D3D12MemAlloc.h | 6 ++---
2 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/src/3rdparty/D3D12MemoryAllocator/D3D12MemAlloc.cpp b/src/3rdparty/D3D12MemoryAllocator/D3D12MemAlloc.cpp
index fe1856927f..f041ec13d8 100644
--- a/src/3rdparty/D3D12MemoryAllocator/D3D12MemAlloc.cpp
+++ b/src/3rdparty/D3D12MemoryAllocator/D3D12MemAlloc.cpp
@@ -132,6 +132,18 @@ especially to test compatibility with D3D12_RESOURCE_HEAP_TIER_1 on modern GPUs.
#define D3D12MA_CREATE_NOT_ZEROED_AVAILABLE 1
#endif
+#if defined(__clang__) || defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#pragma GCC diagnostic ignored "-Wsign-compare"
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#pragma GCC diagnostic ignored "-Wswitch"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Wunused-function"
+#pragma GCC diagnostic ignored "-Wnonnull-compare"
+#endif
+
namespace D3D12MA
{
static constexpr UINT HEAP_TYPE_COUNT = 4;
@@ -7581,12 +7593,14 @@ void AllocatorPimpl::BuildStatsString(WCHAR** ppStatsString, BOOL detailedMap)
json.WriteString(L"HEAP_FLAG_ALLOW_DISPLAY");
if (flags & D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER)
json.WriteString(L"HEAP_FLAG_CROSS_ADAPTER");
+#ifdef __ID3D12Device8_INTERFACE_DEFINED__
if (flags & D3D12_HEAP_FLAG_HARDWARE_PROTECTED)
json.WriteString(L"HEAP_FLAG_HARDWARE_PROTECTED");
if (flags & D3D12_HEAP_FLAG_ALLOW_WRITE_WATCH)
json.WriteString(L"HEAP_FLAG_ALLOW_WRITE_WATCH");
if (flags & D3D12_HEAP_FLAG_ALLOW_SHADER_ATOMICS)
json.WriteString(L"HEAP_FLAG_ALLOW_SHADER_ATOMICS");
+#endif
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
if (flags & D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT)
json.WriteString(L"HEAP_FLAG_CREATE_NOT_RESIDENT");
@@ -7607,9 +7621,12 @@ void AllocatorPimpl::BuildStatsString(WCHAR** ppStatsString, BOOL detailedMap)
| D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER
| D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES
| D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES
+#ifdef __ID3D12Device8_INTERFACE_DEFINED__
| D3D12_HEAP_FLAG_HARDWARE_PROTECTED
| D3D12_HEAP_FLAG_ALLOW_WRITE_WATCH
- | D3D12_HEAP_FLAG_ALLOW_SHADER_ATOMICS);
+ | D3D12_HEAP_FLAG_ALLOW_SHADER_ATOMICS
+#endif
+ );
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
flags &= ~(D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT
| D3D12_HEAP_FLAG_CREATE_NOT_ZEROED);
@@ -10539,3 +10556,7 @@ VirtualBlock::~VirtualBlock()
#endif // _D3D12MA_VIRTUAL_BLOCK_FUNCTIONS
#endif // _D3D12MA_PUBLIC_INTERFACE
} // namespace D3D12MA
+
+#if defined(__clang__) || defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
diff --git a/src/3rdparty/D3D12MemoryAllocator/D3D12MemAlloc.h b/src/3rdparty/D3D12MemoryAllocator/D3D12MemAlloc.h
index 4ab7be318e..d80dcb1e89 100644
--- a/src/3rdparty/D3D12MemoryAllocator/D3D12MemAlloc.h
+++ b/src/3rdparty/D3D12MemoryAllocator/D3D12MemAlloc.h
@@ -151,9 +151,9 @@ class D3D12MA_API IUnknownImpl : public IUnknown
{
public:
virtual ~IUnknownImpl() = default;
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
- virtual ULONG STDMETHODCALLTYPE AddRef();
- virtual ULONG STDMETHODCALLTYPE Release();
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override;
+ ULONG STDMETHODCALLTYPE AddRef() override;
+ ULONG STDMETHODCALLTYPE Release() override;
protected:
virtual void ReleaseThis() { delete this; }
private:
--
2.33.0.windows.2

View File

@ -0,0 +1,16 @@
[
{
"Id": "D3D12MemoryAllocator",
"Name": "D3D12 Memory Allocator",
"QDocModule": "qtgui",
"Description": "D3D12 Memory Allocator",
"QtUsage": "Memory management for the D3D12 backend of QRhi.",
"Homepage": "https://github.com/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator",
"Version": "f128d39b7a95b4235bd228d231646278dc6c24b2",
"License": "MIT License",
"LicenseId": "MIT",
"LicenseFile": "LICENSE.txt",
"Copyright": "Copyright (c) 2019-2022 Advanced Micro Devices, Inc. All rights reserved."
}
]

View File

@ -269,6 +269,7 @@ qt_internal_add_module(Gui
QT_QPA_DEFAULT_PLATFORM_NAME="${QT_QPA_DEFAULT_PLATFORM}"
INCLUDE_DIRECTORIES
../3rdparty/VulkanMemoryAllocator
../3rdparty/D3D12MemoryAllocator
LIBRARIES
Qt::CorePrivate
PUBLIC_LIBRARIES
@ -402,6 +403,11 @@ qt_internal_extend_target(Gui CONDITION WIN32
rhi/qrhid3d11.cpp rhi/qrhid3d11_p.h
rhi/qrhid3d11_p_p.h
rhi/vs_test_p.h
rhi/qrhid3d12.cpp rhi/qrhid3d12_p.h
rhi/qrhid3d12_p_p.h
rhi/cs_mipmap_p.h
../3rdparty/D3D12MemoryAllocator/D3D12MemAlloc.h
../3rdparty/D3D12MemoryAllocator/D3D12MemAlloc.cpp
text/windows/qwindowsfontdatabase.cpp text/windows/qwindowsfontdatabase_p.h
text/windows/qwindowsfontdatabasebase.cpp text/windows/qwindowsfontdatabasebase_p.h
text/windows/qwindowsfontengine.cpp text/windows/qwindowsfontengine_p.h
@ -417,6 +423,7 @@ qt_internal_extend_target(Gui CONDITION WIN32
dxgi
dxguid
dcomp
d3d12
)
if(QT_FEATURE_egl)

View File

@ -13,6 +13,7 @@
#ifdef Q_OS_WIN
#include <QtGui/private/qrhid3d11_p.h>
#include <QtGui/private/qrhid3d12_p.h>
#endif
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
@ -79,10 +80,16 @@ bool QBackingStoreRhiSupport::create()
#endif
#ifdef Q_OS_WIN
if (!rhi && m_config.api() == QPlatformBackingStoreRhiConfig::D3D11) {
QRhiD3D11InitParams params;
params.enableDebugLayer = m_config.isDebugLayerEnabled();
rhi = QRhi::create(QRhi::D3D11, &params, flags);
if (!rhi) {
if (m_config.api() == QPlatformBackingStoreRhiConfig::D3D11) {
QRhiD3D11InitParams params;
params.enableDebugLayer = m_config.isDebugLayerEnabled();
rhi = QRhi::create(QRhi::D3D11, &params, flags);
} else if (m_config.api() == QPlatformBackingStoreRhiConfig::D3D12) {
QRhiD3D12InitParams params;
params.enableDebugLayer = m_config.isDebugLayerEnabled();
rhi = QRhi::create(QRhi::D3D12, &params, flags);
}
}
#endif
@ -195,6 +202,7 @@ QSurface::SurfaceType QBackingStoreRhiSupport::surfaceTypeForConfig(const QPlatf
QSurface::SurfaceType type = QSurface::RasterSurface;
switch (config.api()) {
case QPlatformBackingStoreRhiConfig::D3D11:
case QPlatformBackingStoreRhiConfig::D3D12:
type = QSurface::Direct3DSurface;
break;
case QPlatformBackingStoreRhiConfig::Vulkan:
@ -223,6 +231,8 @@ QRhi::Implementation QBackingStoreRhiSupport::apiToRhiBackend(QPlatformBackingSt
return QRhi::Vulkan;
case QPlatformBackingStoreRhiConfig::D3D11:
return QRhi::D3D11;
case QPlatformBackingStoreRhiConfig::D3D12:
return QRhi::D3D12;
case QPlatformBackingStoreRhiConfig::Null:
return QRhi::Null;
default:
@ -264,6 +274,8 @@ bool QBackingStoreRhiSupport::checkForceRhi(QPlatformBackingStoreRhiConfig *outC
#ifdef Q_OS_WIN
if (backend == QStringLiteral("d3d11") || backend == QStringLiteral("d3d"))
config.setApi(QPlatformBackingStoreRhiConfig::D3D11);
if (backend == QStringLiteral("d3d12"))
config.setApi(QPlatformBackingStoreRhiConfig::D3D12);
#endif
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
if (backend == QStringLiteral("metal"))

View File

@ -45,6 +45,7 @@ struct Q_GUI_EXPORT QPlatformBackingStoreRhiConfig
Metal,
Vulkan,
D3D11,
D3D12,
Null
};

View File

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 Microsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

939
src/gui/rhi/cs_mipmap_p.h Normal file
View File

@ -0,0 +1,939 @@
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef CS_MIPMAP_P_H
#define CS_MIPMAP_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of other Qt classes. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/private/qglobal_p.h>
#ifdef Q_OS_WIN
#include <qt_windows.h>
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 10.1
//
//
// Buffer Definitions:
//
// cbuffer CB0
// {
//
// uint SrcMipLevel; // Offset: 0 Size: 4
// uint NumMipLevels; // Offset: 4 Size: 4
// float2 TexelSize; // Offset: 8 Size: 8
//
// }
//
//
// Resource Bindings:
//
// Name Type Format Dim HLSL Bind Count
// ------------------------------ ---------- ------- ----------- -------------- ------
// BilinearClamp sampler NA NA s0 1
// SrcMip texture float4 2d t0 1
// OutMip1 UAV float4 2d u0 1
// OutMip2 UAV float4 2d u1 1
// OutMip3 UAV float4 2d u2 1
// OutMip4 UAV float4 2d u3 1
// CB0 cbuffer NA NA cb0 1
//
//
//
// Input signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// no Input
//
// Output signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// no Output
cs_5_0
dcl_globalFlags refactoringAllowed
dcl_constantbuffer CB0[1], immediateIndexed
dcl_sampler s0, mode_default
dcl_resource_texture2d (float,float,float,float) t0
dcl_uav_typed_texture2d (float,float,float,float) u0
dcl_uav_typed_texture2d (float,float,float,float) u1
dcl_uav_typed_texture2d (float,float,float,float) u2
dcl_uav_typed_texture2d (float,float,float,float) u3
dcl_input vThreadIDInGroupFlattened
dcl_input vThreadID.xy
dcl_temps 6
dcl_tgsm_structured g0, 4, 64
dcl_tgsm_structured g1, 4, 64
dcl_tgsm_structured g2, 4, 64
dcl_tgsm_structured g3, 4, 64
dcl_thread_group 8, 8, 1
utof r0.xy, vThreadID.xyxx
add r0.xy, r0.xyxx, l(0.250000, 0.250000, 0.000000, 0.000000)
mul r0.zw, r0.xxxy, cb0[0].zzzw
utof r1.x, cb0[0].x
sample_l_indexable(texture2d)(float,float,float,float) r2.xyzw, r0.zwzz, t0.xyzw, s0, r1.x
mul r3.xyz, cb0[0].zwzz, l(0.500000, 0.500000, 0.500000, 0.000000)
mov r3.w, l(0)
mad r3.xyzw, cb0[0].zwzw, r0.xyxy, r3.zwxy
sample_l_indexable(texture2d)(float,float,float,float) r4.xyzw, r3.xyxx, t0.xyzw, s0, r1.x
add r2.xyzw, r2.xyzw, r4.xyzw
mov r3.x, l(0)
mul r3.y, cb0[0].w, l(0.500000)
mad r0.xy, cb0[0].zwzz, r0.xyxx, r3.xyxx
sample_l_indexable(texture2d)(float,float,float,float) r0.xyzw, r0.xyxx, t0.xyzw, s0, r1.x
add r0.xyzw, r0.xyzw, r2.xyzw
sample_l_indexable(texture2d)(float,float,float,float) r1.xyzw, r3.zwzz, t0.xyzw, s0, r1.x
add r0.xyzw, r0.xyzw, r1.xyzw
mul r1.xyzw, r0.xyzw, l(0.250000, 0.250000, 0.250000, 0.250000)
store_uav_typed u0.xyzw, vThreadID.xyyy, r1.xyzw
ieq r2.x, cb0[0].y, l(1)
if_nz r2.x
ret
endif
store_structured g0.x, vThreadIDInGroupFlattened.x, l(0), r1.x
store_structured g1.x, vThreadIDInGroupFlattened.x, l(0), r1.y
store_structured g2.x, vThreadIDInGroupFlattened.x, l(0), r1.z
store_structured g3.x, vThreadIDInGroupFlattened.x, l(0), r1.w
sync_g_t
and r2.x, vThreadIDInGroupFlattened.x, l(9)
if_z r2.x
iadd r2.xyz, vThreadIDInGroupFlattened.xxxx, l(1, 8, 9, 0)
ld_structured r3.x, r2.x, l(0), g0.xxxx
ld_structured r3.y, r2.x, l(0), g1.xxxx
ld_structured r3.z, r2.x, l(0), g2.xxxx
ld_structured r3.w, r2.x, l(0), g3.xxxx
ld_structured r4.x, r2.y, l(0), g0.xxxx
ld_structured r4.y, r2.y, l(0), g1.xxxx
ld_structured r4.z, r2.y, l(0), g2.xxxx
ld_structured r4.w, r2.y, l(0), g3.xxxx
ld_structured r5.x, r2.z, l(0), g0.xxxx
ld_structured r5.y, r2.z, l(0), g1.xxxx
ld_structured r5.z, r2.z, l(0), g2.xxxx
ld_structured r5.w, r2.z, l(0), g3.xxxx
mad r0.xyzw, r0.xyzw, l(0.250000, 0.250000, 0.250000, 0.250000), r3.xyzw
add r0.xyzw, r4.xyzw, r0.xyzw
add r0.xyzw, r5.xyzw, r0.xyzw
mul r1.xyzw, r0.xyzw, l(0.250000, 0.250000, 0.250000, 0.250000)
ushr r0.xyzw, vThreadID.xyyy, l(1, 1, 1, 1)
store_uav_typed u1.xyzw, r0.xyzw, r1.xyzw
store_structured g0.x, vThreadIDInGroupFlattened.x, l(0), r1.x
store_structured g1.x, vThreadIDInGroupFlattened.x, l(0), r1.y
store_structured g2.x, vThreadIDInGroupFlattened.x, l(0), r1.z
store_structured g3.x, vThreadIDInGroupFlattened.x, l(0), r1.w
endif
ieq r0.x, cb0[0].y, l(2)
if_nz r0.x
ret
endif
sync_g_t
and r0.x, vThreadIDInGroupFlattened.x, l(27)
if_z r0.x
iadd r0.xyz, vThreadIDInGroupFlattened.xxxx, l(2, 16, 18, 0)
ld_structured r2.x, r0.x, l(0), g0.xxxx
ld_structured r2.y, r0.x, l(0), g1.xxxx
ld_structured r2.z, r0.x, l(0), g2.xxxx
ld_structured r2.w, r0.x, l(0), g3.xxxx
ld_structured r3.x, r0.y, l(0), g0.xxxx
ld_structured r3.y, r0.y, l(0), g1.xxxx
ld_structured r3.z, r0.y, l(0), g2.xxxx
ld_structured r3.w, r0.y, l(0), g3.xxxx
ld_structured r4.x, r0.z, l(0), g0.xxxx
ld_structured r4.y, r0.z, l(0), g1.xxxx
ld_structured r4.z, r0.z, l(0), g2.xxxx
ld_structured r4.w, r0.z, l(0), g3.xxxx
add r0.xyzw, r1.xyzw, r2.xyzw
add r0.xyzw, r3.xyzw, r0.xyzw
add r0.xyzw, r4.xyzw, r0.xyzw
mul r1.xyzw, r0.xyzw, l(0.250000, 0.250000, 0.250000, 0.250000)
ushr r0.xyzw, vThreadID.xyyy, l(2, 2, 2, 2)
store_uav_typed u2.xyzw, r0.xyzw, r1.xyzw
store_structured g0.x, vThreadIDInGroupFlattened.x, l(0), r1.x
store_structured g1.x, vThreadIDInGroupFlattened.x, l(0), r1.y
store_structured g2.x, vThreadIDInGroupFlattened.x, l(0), r1.z
store_structured g3.x, vThreadIDInGroupFlattened.x, l(0), r1.w
endif
ieq r0.x, cb0[0].y, l(3)
if_nz r0.x
ret
endif
sync_g_t
if_z vThreadIDInGroupFlattened.x
ld_structured r0.x, l(4), l(0), g0.xxxx
ld_structured r0.y, l(4), l(0), g1.xxxx
ld_structured r0.z, l(4), l(0), g2.xxxx
ld_structured r0.w, l(4), l(0), g3.xxxx
ld_structured r2.x, l(32), l(0), g0.xxxx
ld_structured r2.y, l(32), l(0), g1.xxxx
ld_structured r2.z, l(32), l(0), g2.xxxx
ld_structured r2.w, l(32), l(0), g3.xxxx
ld_structured r3.x, l(36), l(0), g0.xxxx
ld_structured r3.y, l(36), l(0), g1.xxxx
ld_structured r3.z, l(36), l(0), g2.xxxx
ld_structured r3.w, l(36), l(0), g3.xxxx
add r0.xyzw, r0.xyzw, r1.xyzw
add r0.xyzw, r2.xyzw, r0.xyzw
add r0.xyzw, r3.xyzw, r0.xyzw
mul r0.xyzw, r0.xyzw, l(0.250000, 0.250000, 0.250000, 0.250000)
ushr r1.xyzw, vThreadID.xyyy, l(3, 3, 3, 3)
store_uav_typed u3.xyzw, r1.xyzw, r0.xyzw
endif
ret
// Approximately 111 instruction slots used
#endif
inline constexpr BYTE g_csMipmap[] =
{
68, 88, 66, 67, 133, 122,
5, 181, 163, 163, 140, 185,
158, 179, 4, 65, 180, 238,
158, 10, 1, 0, 0, 0,
60, 17, 0, 0, 5, 0,
0, 0, 52, 0, 0, 0,
200, 2, 0, 0, 216, 2,
0, 0, 232, 2, 0, 0,
160, 16, 0, 0, 82, 68,
69, 70, 140, 2, 0, 0,
1, 0, 0, 0, 88, 1,
0, 0, 7, 0, 0, 0,
60, 0, 0, 0, 0, 5,
83, 67, 0, 1, 0, 0,
100, 2, 0, 0, 82, 68,
49, 49, 60, 0, 0, 0,
24, 0, 0, 0, 32, 0,
0, 0, 40, 0, 0, 0,
36, 0, 0, 0, 12, 0,
0, 0, 0, 0, 0, 0,
28, 1, 0, 0, 3, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 1, 0,
0, 0, 42, 1, 0, 0,
2, 0, 0, 0, 5, 0,
0, 0, 4, 0, 0, 0,
255, 255, 255, 255, 0, 0,
0, 0, 1, 0, 0, 0,
13, 0, 0, 0, 49, 1,
0, 0, 4, 0, 0, 0,
5, 0, 0, 0, 4, 0,
0, 0, 255, 255, 255, 255,
0, 0, 0, 0, 1, 0,
0, 0, 13, 0, 0, 0,
57, 1, 0, 0, 4, 0,
0, 0, 5, 0, 0, 0,
4, 0, 0, 0, 255, 255,
255, 255, 1, 0, 0, 0,
1, 0, 0, 0, 13, 0,
0, 0, 65, 1, 0, 0,
4, 0, 0, 0, 5, 0,
0, 0, 4, 0, 0, 0,
255, 255, 255, 255, 2, 0,
0, 0, 1, 0, 0, 0,
13, 0, 0, 0, 73, 1,
0, 0, 4, 0, 0, 0,
5, 0, 0, 0, 4, 0,
0, 0, 255, 255, 255, 255,
3, 0, 0, 0, 1, 0,
0, 0, 13, 0, 0, 0,
81, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 1, 0,
0, 0, 66, 105, 108, 105,
110, 101, 97, 114, 67, 108,
97, 109, 112, 0, 83, 114,
99, 77, 105, 112, 0, 79,
117, 116, 77, 105, 112, 49,
0, 79, 117, 116, 77, 105,
112, 50, 0, 79, 117, 116,
77, 105, 112, 51, 0, 79,
117, 116, 77, 105, 112, 52,
0, 67, 66, 48, 0, 171,
171, 171, 81, 1, 0, 0,
3, 0, 0, 0, 112, 1,
0, 0, 16, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 232, 1, 0, 0,
0, 0, 0, 0, 4, 0,
0, 0, 2, 0, 0, 0,
252, 1, 0, 0, 0, 0,
0, 0, 255, 255, 255, 255,
0, 0, 0, 0, 255, 255,
255, 255, 0, 0, 0, 0,
32, 2, 0, 0, 4, 0,
0, 0, 4, 0, 0, 0,
2, 0, 0, 0, 252, 1,
0, 0, 0, 0, 0, 0,
255, 255, 255, 255, 0, 0,
0, 0, 255, 255, 255, 255,
0, 0, 0, 0, 45, 2,
0, 0, 8, 0, 0, 0,
8, 0, 0, 0, 2, 0,
0, 0, 64, 2, 0, 0,
0, 0, 0, 0, 255, 255,
255, 255, 0, 0, 0, 0,
255, 255, 255, 255, 0, 0,
0, 0, 83, 114, 99, 77,
105, 112, 76, 101, 118, 101,
108, 0, 100, 119, 111, 114,
100, 0, 171, 171, 0, 0,
19, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
244, 1, 0, 0, 78, 117,
109, 77, 105, 112, 76, 101,
118, 101, 108, 115, 0, 84,
101, 120, 101, 108, 83, 105,
122, 101, 0, 102, 108, 111,
97, 116, 50, 0, 171, 171,
1, 0, 3, 0, 1, 0,
2, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 55, 2, 0, 0,
77, 105, 99, 114, 111, 115,
111, 102, 116, 32, 40, 82,
41, 32, 72, 76, 83, 76,
32, 83, 104, 97, 100, 101,
114, 32, 67, 111, 109, 112,
105, 108, 101, 114, 32, 49,
48, 46, 49, 0, 73, 83,
71, 78, 8, 0, 0, 0,
0, 0, 0, 0, 8, 0,
0, 0, 79, 83, 71, 78,
8, 0, 0, 0, 0, 0,
0, 0, 8, 0, 0, 0,
83, 72, 69, 88, 176, 13,
0, 0, 80, 0, 5, 0,
108, 3, 0, 0, 106, 8,
0, 1, 89, 0, 0, 4,
70, 142, 32, 0, 0, 0,
0, 0, 1, 0, 0, 0,
90, 0, 0, 3, 0, 96,
16, 0, 0, 0, 0, 0,
88, 24, 0, 4, 0, 112,
16, 0, 0, 0, 0, 0,
85, 85, 0, 0, 156, 24,
0, 4, 0, 224, 17, 0,
0, 0, 0, 0, 85, 85,
0, 0, 156, 24, 0, 4,
0, 224, 17, 0, 1, 0,
0, 0, 85, 85, 0, 0,
156, 24, 0, 4, 0, 224,
17, 0, 2, 0, 0, 0,
85, 85, 0, 0, 156, 24,
0, 4, 0, 224, 17, 0,
3, 0, 0, 0, 85, 85,
0, 0, 95, 0, 0, 2,
0, 64, 2, 0, 95, 0,
0, 2, 50, 0, 2, 0,
104, 0, 0, 2, 6, 0,
0, 0, 160, 0, 0, 5,
0, 240, 17, 0, 0, 0,
0, 0, 4, 0, 0, 0,
64, 0, 0, 0, 160, 0,
0, 5, 0, 240, 17, 0,
1, 0, 0, 0, 4, 0,
0, 0, 64, 0, 0, 0,
160, 0, 0, 5, 0, 240,
17, 0, 2, 0, 0, 0,
4, 0, 0, 0, 64, 0,
0, 0, 160, 0, 0, 5,
0, 240, 17, 0, 3, 0,
0, 0, 4, 0, 0, 0,
64, 0, 0, 0, 155, 0,
0, 4, 8, 0, 0, 0,
8, 0, 0, 0, 1, 0,
0, 0, 86, 0, 0, 4,
50, 0, 16, 0, 0, 0,
0, 0, 70, 0, 2, 0,
0, 0, 0, 10, 50, 0,
16, 0, 0, 0, 0, 0,
70, 0, 16, 0, 0, 0,
0, 0, 2, 64, 0, 0,
0, 0, 128, 62, 0, 0,
128, 62, 0, 0, 0, 0,
0, 0, 0, 0, 56, 0,
0, 8, 194, 0, 16, 0,
0, 0, 0, 0, 6, 4,
16, 0, 0, 0, 0, 0,
166, 142, 32, 0, 0, 0,
0, 0, 0, 0, 0, 0,
86, 0, 0, 6, 18, 0,
16, 0, 1, 0, 0, 0,
10, 128, 32, 0, 0, 0,
0, 0, 0, 0, 0, 0,
72, 0, 0, 141, 194, 0,
0, 128, 67, 85, 21, 0,
242, 0, 16, 0, 2, 0,
0, 0, 230, 10, 16, 0,
0, 0, 0, 0, 70, 126,
16, 0, 0, 0, 0, 0,
0, 96, 16, 0, 0, 0,
0, 0, 10, 0, 16, 0,
1, 0, 0, 0, 56, 0,
0, 11, 114, 0, 16, 0,
3, 0, 0, 0, 230, 138,
32, 0, 0, 0, 0, 0,
0, 0, 0, 0, 2, 64,
0, 0, 0, 0, 0, 63,
0, 0, 0, 63, 0, 0,
0, 63, 0, 0, 0, 0,
54, 0, 0, 5, 130, 0,
16, 0, 3, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 50, 0, 0, 10,
242, 0, 16, 0, 3, 0,
0, 0, 230, 142, 32, 0,
0, 0, 0, 0, 0, 0,
0, 0, 70, 4, 16, 0,
0, 0, 0, 0, 230, 4,
16, 0, 3, 0, 0, 0,
72, 0, 0, 141, 194, 0,
0, 128, 67, 85, 21, 0,
242, 0, 16, 0, 4, 0,
0, 0, 70, 0, 16, 0,
3, 0, 0, 0, 70, 126,
16, 0, 0, 0, 0, 0,
0, 96, 16, 0, 0, 0,
0, 0, 10, 0, 16, 0,
1, 0, 0, 0, 0, 0,
0, 7, 242, 0, 16, 0,
2, 0, 0, 0, 70, 14,
16, 0, 2, 0, 0, 0,
70, 14, 16, 0, 4, 0,
0, 0, 54, 0, 0, 5,
18, 0, 16, 0, 3, 0,
0, 0, 1, 64, 0, 0,
0, 0, 0, 0, 56, 0,
0, 8, 34, 0, 16, 0,
3, 0, 0, 0, 58, 128,
32, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 64,
0, 0, 0, 0, 0, 63,
50, 0, 0, 10, 50, 0,
16, 0, 0, 0, 0, 0,
230, 138, 32, 0, 0, 0,
0, 0, 0, 0, 0, 0,
70, 0, 16, 0, 0, 0,
0, 0, 70, 0, 16, 0,
3, 0, 0, 0, 72, 0,
0, 141, 194, 0, 0, 128,
67, 85, 21, 0, 242, 0,
16, 0, 0, 0, 0, 0,
70, 0, 16, 0, 0, 0,
0, 0, 70, 126, 16, 0,
0, 0, 0, 0, 0, 96,
16, 0, 0, 0, 0, 0,
10, 0, 16, 0, 1, 0,
0, 0, 0, 0, 0, 7,
242, 0, 16, 0, 0, 0,
0, 0, 70, 14, 16, 0,
0, 0, 0, 0, 70, 14,
16, 0, 2, 0, 0, 0,
72, 0, 0, 141, 194, 0,
0, 128, 67, 85, 21, 0,
242, 0, 16, 0, 1, 0,
0, 0, 230, 10, 16, 0,
3, 0, 0, 0, 70, 126,
16, 0, 0, 0, 0, 0,
0, 96, 16, 0, 0, 0,
0, 0, 10, 0, 16, 0,
1, 0, 0, 0, 0, 0,
0, 7, 242, 0, 16, 0,
0, 0, 0, 0, 70, 14,
16, 0, 0, 0, 0, 0,
70, 14, 16, 0, 1, 0,
0, 0, 56, 0, 0, 10,
242, 0, 16, 0, 1, 0,
0, 0, 70, 14, 16, 0,
0, 0, 0, 0, 2, 64,
0, 0, 0, 0, 128, 62,
0, 0, 128, 62, 0, 0,
128, 62, 0, 0, 128, 62,
164, 0, 0, 6, 242, 224,
17, 0, 0, 0, 0, 0,
70, 5, 2, 0, 70, 14,
16, 0, 1, 0, 0, 0,
32, 0, 0, 8, 18, 0,
16, 0, 2, 0, 0, 0,
26, 128, 32, 0, 0, 0,
0, 0, 0, 0, 0, 0,
1, 64, 0, 0, 1, 0,
0, 0, 31, 0, 4, 3,
10, 0, 16, 0, 2, 0,
0, 0, 62, 0, 0, 1,
21, 0, 0, 1, 168, 0,
0, 8, 18, 240, 17, 0,
0, 0, 0, 0, 10, 64,
2, 0, 1, 64, 0, 0,
0, 0, 0, 0, 10, 0,
16, 0, 1, 0, 0, 0,
168, 0, 0, 8, 18, 240,
17, 0, 1, 0, 0, 0,
10, 64, 2, 0, 1, 64,
0, 0, 0, 0, 0, 0,
26, 0, 16, 0, 1, 0,
0, 0, 168, 0, 0, 8,
18, 240, 17, 0, 2, 0,
0, 0, 10, 64, 2, 0,
1, 64, 0, 0, 0, 0,
0, 0, 42, 0, 16, 0,
1, 0, 0, 0, 168, 0,
0, 8, 18, 240, 17, 0,
3, 0, 0, 0, 10, 64,
2, 0, 1, 64, 0, 0,
0, 0, 0, 0, 58, 0,
16, 0, 1, 0, 0, 0,
190, 24, 0, 1, 1, 0,
0, 6, 18, 0, 16, 0,
2, 0, 0, 0, 10, 64,
2, 0, 1, 64, 0, 0,
9, 0, 0, 0, 31, 0,
0, 3, 10, 0, 16, 0,
2, 0, 0, 0, 30, 0,
0, 9, 114, 0, 16, 0,
2, 0, 0, 0, 6, 64,
2, 0, 2, 64, 0, 0,
1, 0, 0, 0, 8, 0,
0, 0, 9, 0, 0, 0,
0, 0, 0, 0, 167, 0,
0, 9, 18, 0, 16, 0,
3, 0, 0, 0, 10, 0,
16, 0, 2, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
0, 0, 0, 0, 167, 0,
0, 9, 34, 0, 16, 0,
3, 0, 0, 0, 10, 0,
16, 0, 2, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
1, 0, 0, 0, 167, 0,
0, 9, 66, 0, 16, 0,
3, 0, 0, 0, 10, 0,
16, 0, 2, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
2, 0, 0, 0, 167, 0,
0, 9, 130, 0, 16, 0,
3, 0, 0, 0, 10, 0,
16, 0, 2, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
3, 0, 0, 0, 167, 0,
0, 9, 18, 0, 16, 0,
4, 0, 0, 0, 26, 0,
16, 0, 2, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
0, 0, 0, 0, 167, 0,
0, 9, 34, 0, 16, 0,
4, 0, 0, 0, 26, 0,
16, 0, 2, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
1, 0, 0, 0, 167, 0,
0, 9, 66, 0, 16, 0,
4, 0, 0, 0, 26, 0,
16, 0, 2, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
2, 0, 0, 0, 167, 0,
0, 9, 130, 0, 16, 0,
4, 0, 0, 0, 26, 0,
16, 0, 2, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
3, 0, 0, 0, 167, 0,
0, 9, 18, 0, 16, 0,
5, 0, 0, 0, 42, 0,
16, 0, 2, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
0, 0, 0, 0, 167, 0,
0, 9, 34, 0, 16, 0,
5, 0, 0, 0, 42, 0,
16, 0, 2, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
1, 0, 0, 0, 167, 0,
0, 9, 66, 0, 16, 0,
5, 0, 0, 0, 42, 0,
16, 0, 2, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
2, 0, 0, 0, 167, 0,
0, 9, 130, 0, 16, 0,
5, 0, 0, 0, 42, 0,
16, 0, 2, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
3, 0, 0, 0, 50, 0,
0, 12, 242, 0, 16, 0,
0, 0, 0, 0, 70, 14,
16, 0, 0, 0, 0, 0,
2, 64, 0, 0, 0, 0,
128, 62, 0, 0, 128, 62,
0, 0, 128, 62, 0, 0,
128, 62, 70, 14, 16, 0,
3, 0, 0, 0, 0, 0,
0, 7, 242, 0, 16, 0,
0, 0, 0, 0, 70, 14,
16, 0, 4, 0, 0, 0,
70, 14, 16, 0, 0, 0,
0, 0, 0, 0, 0, 7,
242, 0, 16, 0, 0, 0,
0, 0, 70, 14, 16, 0,
5, 0, 0, 0, 70, 14,
16, 0, 0, 0, 0, 0,
56, 0, 0, 10, 242, 0,
16, 0, 1, 0, 0, 0,
70, 14, 16, 0, 0, 0,
0, 0, 2, 64, 0, 0,
0, 0, 128, 62, 0, 0,
128, 62, 0, 0, 128, 62,
0, 0, 128, 62, 85, 0,
0, 9, 242, 0, 16, 0,
0, 0, 0, 0, 70, 5,
2, 0, 2, 64, 0, 0,
1, 0, 0, 0, 1, 0,
0, 0, 1, 0, 0, 0,
1, 0, 0, 0, 164, 0,
0, 7, 242, 224, 17, 0,
1, 0, 0, 0, 70, 14,
16, 0, 0, 0, 0, 0,
70, 14, 16, 0, 1, 0,
0, 0, 168, 0, 0, 8,
18, 240, 17, 0, 0, 0,
0, 0, 10, 64, 2, 0,
1, 64, 0, 0, 0, 0,
0, 0, 10, 0, 16, 0,
1, 0, 0, 0, 168, 0,
0, 8, 18, 240, 17, 0,
1, 0, 0, 0, 10, 64,
2, 0, 1, 64, 0, 0,
0, 0, 0, 0, 26, 0,
16, 0, 1, 0, 0, 0,
168, 0, 0, 8, 18, 240,
17, 0, 2, 0, 0, 0,
10, 64, 2, 0, 1, 64,
0, 0, 0, 0, 0, 0,
42, 0, 16, 0, 1, 0,
0, 0, 168, 0, 0, 8,
18, 240, 17, 0, 3, 0,
0, 0, 10, 64, 2, 0,
1, 64, 0, 0, 0, 0,
0, 0, 58, 0, 16, 0,
1, 0, 0, 0, 21, 0,
0, 1, 32, 0, 0, 8,
18, 0, 16, 0, 0, 0,
0, 0, 26, 128, 32, 0,
0, 0, 0, 0, 0, 0,
0, 0, 1, 64, 0, 0,
2, 0, 0, 0, 31, 0,
4, 3, 10, 0, 16, 0,
0, 0, 0, 0, 62, 0,
0, 1, 21, 0, 0, 1,
190, 24, 0, 1, 1, 0,
0, 6, 18, 0, 16, 0,
0, 0, 0, 0, 10, 64,
2, 0, 1, 64, 0, 0,
27, 0, 0, 0, 31, 0,
0, 3, 10, 0, 16, 0,
0, 0, 0, 0, 30, 0,
0, 9, 114, 0, 16, 0,
0, 0, 0, 0, 6, 64,
2, 0, 2, 64, 0, 0,
2, 0, 0, 0, 16, 0,
0, 0, 18, 0, 0, 0,
0, 0, 0, 0, 167, 0,
0, 9, 18, 0, 16, 0,
2, 0, 0, 0, 10, 0,
16, 0, 0, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
0, 0, 0, 0, 167, 0,
0, 9, 34, 0, 16, 0,
2, 0, 0, 0, 10, 0,
16, 0, 0, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
1, 0, 0, 0, 167, 0,
0, 9, 66, 0, 16, 0,
2, 0, 0, 0, 10, 0,
16, 0, 0, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
2, 0, 0, 0, 167, 0,
0, 9, 130, 0, 16, 0,
2, 0, 0, 0, 10, 0,
16, 0, 0, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
3, 0, 0, 0, 167, 0,
0, 9, 18, 0, 16, 0,
3, 0, 0, 0, 26, 0,
16, 0, 0, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
0, 0, 0, 0, 167, 0,
0, 9, 34, 0, 16, 0,
3, 0, 0, 0, 26, 0,
16, 0, 0, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
1, 0, 0, 0, 167, 0,
0, 9, 66, 0, 16, 0,
3, 0, 0, 0, 26, 0,
16, 0, 0, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
2, 0, 0, 0, 167, 0,
0, 9, 130, 0, 16, 0,
3, 0, 0, 0, 26, 0,
16, 0, 0, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
3, 0, 0, 0, 167, 0,
0, 9, 18, 0, 16, 0,
4, 0, 0, 0, 42, 0,
16, 0, 0, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
0, 0, 0, 0, 167, 0,
0, 9, 34, 0, 16, 0,
4, 0, 0, 0, 42, 0,
16, 0, 0, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
1, 0, 0, 0, 167, 0,
0, 9, 66, 0, 16, 0,
4, 0, 0, 0, 42, 0,
16, 0, 0, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
2, 0, 0, 0, 167, 0,
0, 9, 130, 0, 16, 0,
4, 0, 0, 0, 42, 0,
16, 0, 0, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
3, 0, 0, 0, 0, 0,
0, 7, 242, 0, 16, 0,
0, 0, 0, 0, 70, 14,
16, 0, 1, 0, 0, 0,
70, 14, 16, 0, 2, 0,
0, 0, 0, 0, 0, 7,
242, 0, 16, 0, 0, 0,
0, 0, 70, 14, 16, 0,
3, 0, 0, 0, 70, 14,
16, 0, 0, 0, 0, 0,
0, 0, 0, 7, 242, 0,
16, 0, 0, 0, 0, 0,
70, 14, 16, 0, 4, 0,
0, 0, 70, 14, 16, 0,
0, 0, 0, 0, 56, 0,
0, 10, 242, 0, 16, 0,
1, 0, 0, 0, 70, 14,
16, 0, 0, 0, 0, 0,
2, 64, 0, 0, 0, 0,
128, 62, 0, 0, 128, 62,
0, 0, 128, 62, 0, 0,
128, 62, 85, 0, 0, 9,
242, 0, 16, 0, 0, 0,
0, 0, 70, 5, 2, 0,
2, 64, 0, 0, 2, 0,
0, 0, 2, 0, 0, 0,
2, 0, 0, 0, 2, 0,
0, 0, 164, 0, 0, 7,
242, 224, 17, 0, 2, 0,
0, 0, 70, 14, 16, 0,
0, 0, 0, 0, 70, 14,
16, 0, 1, 0, 0, 0,
168, 0, 0, 8, 18, 240,
17, 0, 0, 0, 0, 0,
10, 64, 2, 0, 1, 64,
0, 0, 0, 0, 0, 0,
10, 0, 16, 0, 1, 0,
0, 0, 168, 0, 0, 8,
18, 240, 17, 0, 1, 0,
0, 0, 10, 64, 2, 0,
1, 64, 0, 0, 0, 0,
0, 0, 26, 0, 16, 0,
1, 0, 0, 0, 168, 0,
0, 8, 18, 240, 17, 0,
2, 0, 0, 0, 10, 64,
2, 0, 1, 64, 0, 0,
0, 0, 0, 0, 42, 0,
16, 0, 1, 0, 0, 0,
168, 0, 0, 8, 18, 240,
17, 0, 3, 0, 0, 0,
10, 64, 2, 0, 1, 64,
0, 0, 0, 0, 0, 0,
58, 0, 16, 0, 1, 0,
0, 0, 21, 0, 0, 1,
32, 0, 0, 8, 18, 0,
16, 0, 0, 0, 0, 0,
26, 128, 32, 0, 0, 0,
0, 0, 0, 0, 0, 0,
1, 64, 0, 0, 3, 0,
0, 0, 31, 0, 4, 3,
10, 0, 16, 0, 0, 0,
0, 0, 62, 0, 0, 1,
21, 0, 0, 1, 190, 24,
0, 1, 31, 0, 0, 2,
10, 64, 2, 0, 167, 0,
0, 9, 18, 0, 16, 0,
0, 0, 0, 0, 1, 64,
0, 0, 4, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
0, 0, 0, 0, 167, 0,
0, 9, 34, 0, 16, 0,
0, 0, 0, 0, 1, 64,
0, 0, 4, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
1, 0, 0, 0, 167, 0,
0, 9, 66, 0, 16, 0,
0, 0, 0, 0, 1, 64,
0, 0, 4, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
2, 0, 0, 0, 167, 0,
0, 9, 130, 0, 16, 0,
0, 0, 0, 0, 1, 64,
0, 0, 4, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
3, 0, 0, 0, 167, 0,
0, 9, 18, 0, 16, 0,
2, 0, 0, 0, 1, 64,
0, 0, 32, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
0, 0, 0, 0, 167, 0,
0, 9, 34, 0, 16, 0,
2, 0, 0, 0, 1, 64,
0, 0, 32, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
1, 0, 0, 0, 167, 0,
0, 9, 66, 0, 16, 0,
2, 0, 0, 0, 1, 64,
0, 0, 32, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
2, 0, 0, 0, 167, 0,
0, 9, 130, 0, 16, 0,
2, 0, 0, 0, 1, 64,
0, 0, 32, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
3, 0, 0, 0, 167, 0,
0, 9, 18, 0, 16, 0,
3, 0, 0, 0, 1, 64,
0, 0, 36, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
0, 0, 0, 0, 167, 0,
0, 9, 34, 0, 16, 0,
3, 0, 0, 0, 1, 64,
0, 0, 36, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
1, 0, 0, 0, 167, 0,
0, 9, 66, 0, 16, 0,
3, 0, 0, 0, 1, 64,
0, 0, 36, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
2, 0, 0, 0, 167, 0,
0, 9, 130, 0, 16, 0,
3, 0, 0, 0, 1, 64,
0, 0, 36, 0, 0, 0,
1, 64, 0, 0, 0, 0,
0, 0, 6, 240, 17, 0,
3, 0, 0, 0, 0, 0,
0, 7, 242, 0, 16, 0,
0, 0, 0, 0, 70, 14,
16, 0, 0, 0, 0, 0,
70, 14, 16, 0, 1, 0,
0, 0, 0, 0, 0, 7,
242, 0, 16, 0, 0, 0,
0, 0, 70, 14, 16, 0,
2, 0, 0, 0, 70, 14,
16, 0, 0, 0, 0, 0,
0, 0, 0, 7, 242, 0,
16, 0, 0, 0, 0, 0,
70, 14, 16, 0, 3, 0,
0, 0, 70, 14, 16, 0,
0, 0, 0, 0, 56, 0,
0, 10, 242, 0, 16, 0,
0, 0, 0, 0, 70, 14,
16, 0, 0, 0, 0, 0,
2, 64, 0, 0, 0, 0,
128, 62, 0, 0, 128, 62,
0, 0, 128, 62, 0, 0,
128, 62, 85, 0, 0, 9,
242, 0, 16, 0, 1, 0,
0, 0, 70, 5, 2, 0,
2, 64, 0, 0, 3, 0,
0, 0, 3, 0, 0, 0,
3, 0, 0, 0, 3, 0,
0, 0, 164, 0, 0, 7,
242, 224, 17, 0, 3, 0,
0, 0, 70, 14, 16, 0,
1, 0, 0, 0, 70, 14,
16, 0, 0, 0, 0, 0,
21, 0, 0, 1, 62, 0,
0, 1, 83, 84, 65, 84,
148, 0, 0, 0, 111, 0,
0, 0, 6, 0, 0, 0,
0, 0, 0, 0, 2, 0,
0, 0, 22, 0, 0, 0,
5, 0, 0, 0, 5, 0,
0, 0, 4, 0, 0, 0,
6, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 4, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 2, 0, 0, 0,
0, 0, 0, 0, 2, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 3, 0, 0, 0,
0, 0, 0, 0, 4, 0,
0, 0
};
#endif // Q_OS_WIN
#endif // CS_MIPMAP_P_H

117
src/gui/rhi/mipmap.hlsl Normal file
View File

@ -0,0 +1,117 @@
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
RWTexture2D<float4> OutMip1 : register(u0);
RWTexture2D<float4> OutMip2 : register(u1);
RWTexture2D<float4> OutMip3 : register(u2);
RWTexture2D<float4> OutMip4 : register(u3);
Texture2D<float4> SrcMip : register(t0);
SamplerState BilinearClamp : register(s0);
cbuffer CB0 : register(b0)
{
uint SrcMipLevel; // Texture level of source mip
uint NumMipLevels; // Number of OutMips to write: [1, 4]
float2 TexelSize; // 1.0 / OutMip1.Dimensions
}
// The reason for separating channels is to reduce bank conflicts in the
// local data memory controller. A large stride will cause more threads
// to collide on the same memory bank.
groupshared float gs_R[64];
groupshared float gs_G[64];
groupshared float gs_B[64];
groupshared float gs_A[64];
void StoreColor( uint Index, float4 Color )
{
gs_R[Index] = Color.r;
gs_G[Index] = Color.g;
gs_B[Index] = Color.b;
gs_A[Index] = Color.a;
}
float4 LoadColor( uint Index )
{
return float4( gs_R[Index], gs_G[Index], gs_B[Index], gs_A[Index]);
}
[numthreads( 8, 8, 1 )]
void csMain( uint GI : SV_GroupIndex, uint3 DTid : SV_DispatchThreadID )
{
// Use 4 bilinear samples to guarantee we don't undersample when downsizing by more than 2x
// in both directions.
float2 UV1 = TexelSize * (DTid.xy + float2(0.25, 0.25));
float2 O = TexelSize * 0.5;
float4 Src1 = SrcMip.SampleLevel(BilinearClamp, UV1, SrcMipLevel);
Src1 += SrcMip.SampleLevel(BilinearClamp, UV1 + float2(O.x, 0.0), SrcMipLevel);
Src1 += SrcMip.SampleLevel(BilinearClamp, UV1 + float2(0.0, O.y), SrcMipLevel);
Src1 += SrcMip.SampleLevel(BilinearClamp, UV1 + float2(O.x, O.y), SrcMipLevel);
Src1 *= 0.25;
OutMip1[DTid.xy] = Src1;
// A scalar (constant) branch can exit all threads coherently.
if (NumMipLevels == 1)
return;
// Without lane swizzle operations, the only way to share data with other
// threads is through LDS.
StoreColor(GI, Src1);
// This guarantees all LDS writes are complete and that all threads have
// executed all instructions so far (and therefore have issued their LDS
// write instructions.)
GroupMemoryBarrierWithGroupSync();
// With low three bits for X and high three bits for Y, this bit mask
// (binary: 001001) checks that X and Y are even.
if ((GI & 0x9) == 0)
{
float4 Src2 = LoadColor(GI + 0x01);
float4 Src3 = LoadColor(GI + 0x08);
float4 Src4 = LoadColor(GI + 0x09);
Src1 = 0.25 * (Src1 + Src2 + Src3 + Src4);
OutMip2[DTid.xy / 2] = Src1;
StoreColor(GI, Src1);
}
if (NumMipLevels == 2)
return;
GroupMemoryBarrierWithGroupSync();
// This bit mask (binary: 011011) checks that X and Y are multiples of four.
if ((GI & 0x1B) == 0)
{
float4 Src2 = LoadColor(GI + 0x02);
float4 Src3 = LoadColor(GI + 0x10);
float4 Src4 = LoadColor(GI + 0x12);
Src1 = 0.25 * (Src1 + Src2 + Src3 + Src4);
OutMip3[DTid.xy / 4] = Src1;
StoreColor(GI, Src1);
}
if (NumMipLevels == 3)
return;
GroupMemoryBarrierWithGroupSync();
// This bit mask would be 111111 (X & Y multiples of 8), but only one
// thread fits that criteria.
if (GI == 0)
{
float4 Src2 = LoadColor(GI + 0x04);
float4 Src3 = LoadColor(GI + 0x20);
float4 Src4 = LoadColor(GI + 0x24);
Src1 = 0.25 * (Src1 + Src2 + Src3 + Src4);
OutMip4[DTid.xy / 8] = Src1;
}
}

View File

@ -14,6 +14,7 @@
#endif
#ifdef Q_OS_WIN
#include "qrhid3d11_p_p.h"
#include "qrhid3d12_p_p.h"
#endif
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
#include "qrhimetal_p_p.h"
@ -404,6 +405,7 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
\value Vulkan
\value OpenGLES2
\value D3D11
\value D3D12
\value Metal
*/
@ -587,7 +589,7 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
\value TriangleFanTopology Indicates that QRhiGraphicsPipeline::setTopology()
supports QRhiGraphicsPipeline::TriangleFan. In practice this feature will be
unsupported with Metal and Direct 3D 11.
unsupported with Metal and Direct 3D 11/12.
\value ReadBackNonUniformBuffer Indicates that
\l{QRhiResourceUpdateBatch::readBackBuffer()}{reading buffer contents} is
@ -3564,6 +3566,14 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::uniformBufferWithDynamicOff
together with another, layout compatible QRhiShaderResourceBindings with
resources present passed to QRhiCommandBuffer::setShaderResources().
\note A shader may not be able to consume more than 16 textures/samplers,
depending on the underlying graphics API. This hard limit must be kept in
mind in renderer design. This does not apply to texture arrays which
consume a single binding point (shader register) and can contain 256-2048
textures, depending on the underlying graphics API. Arrays of textures (see
sampledTextures()) are however no different in this regard than using the
same number of individual textures.
\sa sampledTextures()
*/
QRhiShaderResourceBinding QRhiShaderResourceBinding::sampledTexture(
@ -3649,6 +3659,14 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::sampledTextures(
Vulkan-compatible GLSL code separate textures are declared as \c texture2D
as opposed to \c sampler2D: \c{layout(binding = 1) uniform texture2D tex;}
\note A shader may not be able to consume more than 16 textures, depending
on the underlying graphics API. This hard limit must be kept in mind in
renderer design. This does not apply to texture arrays which consume a
single binding point (shader register) and can contain 256-2048 textures,
depending on the underlying graphics API. Arrays of textures (see
sampledTextures()) are however no different in this regard than using the
same number of individual textures.
\sa textures(), sampler()
*/
QRhiShaderResourceBinding QRhiShaderResourceBinding::texture(int binding, StageFlags stage, QRhiTexture *tex)
@ -3721,6 +3739,10 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::textures(int binding, Stage
to sample the texture: \c{fragColor = texture(sampler2D(tex, samp),
texcoord);}.
\note A shader may not be able to consume more than 16 samplers, depending
on the underlying graphics API. This hard limit must be kept in mind in
renderer design.
\sa texture()
*/
QRhiShaderResourceBinding QRhiShaderResourceBinding::sampler(int binding, StageFlags stage, QRhiSampler *sampler)
@ -5578,6 +5600,15 @@ QRhi *QRhi::create(Implementation impl, QRhiInitParams *params, Flags flags, QRh
#else
qWarning("This platform has no Metal support");
break;
#endif
case D3D12:
#ifdef Q_OS_WIN
r->d = new QRhiD3D12(static_cast<QRhiD3D12InitParams *>(params),
static_cast<QRhiD3D12NativeHandles *>(importDevice));
break;
#else
qWarning("This platform has no Direct3D 12 support");
break;
#endif
}
@ -5704,6 +5735,8 @@ const char *QRhi::backendName(Implementation impl)
return "D3D11";
case QRhi::Metal:
return "Metal";
case QRhi::D3D12:
return "D3D12";
}
Q_UNREACHABLE_RETURN("Unknown");
@ -7219,6 +7252,7 @@ QDebug operator<<(QDebug dbg, const QRhiStats &info)
<< " allocCount=" << info.allocCount
<< " usedBytes=" << info.usedBytes
<< " unusedBytes=" << info.unusedBytes
<< " totalUsageBytes=" << info.totalUsageBytes
<< ')';
return dbg;
}
@ -7237,6 +7271,15 @@ QDebug operator<<(QDebug dbg, const QRhiStats &info)
from the underlying memory allocator library. This gives an insight into
the memory requirements of the active buffers and textures.
The same is true for Direct 3D 12. In addition to the memory allocator
library's statistics, here the result also includes a \c totalUsageBytes
field which reports the total size including additional resources that are
not under the memory allocator library's control (swapchain buffers,
descriptor heaps, etc.), as reported by DXGI.
The values correspond to all types of memory used, combined. (i.e. video +
system in case of a discreet GPU)
Additional data, such as the total time in milliseconds spent in graphics
and compute pipeline creation (which usually involves shader compilation or
cache lookups, and potentially expensive processing) is available with most

View File

@ -818,7 +818,7 @@ public:
struct NativeTexture {
quint64 object;
int layout;
int layout; // or state
};
QRhiResource::Type resourceType() const override;
@ -1545,11 +1545,7 @@ struct Q_GUI_EXPORT QRhiReadbackResult
QByteArray data;
};
struct Q_GUI_EXPORT QRhiBufferReadbackResult
{
std::function<void()> completed = nullptr;
QByteArray data;
};
using QRhiBufferReadbackResult = QRhiReadbackResult;
class Q_GUI_EXPORT QRhiResourceUpdateBatch
{
@ -1605,10 +1601,13 @@ Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiDriverInfo &);
struct Q_GUI_EXPORT QRhiStats
{
qint64 totalPipelineCreationTime = 0;
// Vulkan or D3D12 memory allocator statistics
quint32 blockCount = 0;
quint32 allocCount = 0;
quint64 usedBytes = 0;
quint64 unusedBytes = 0;
// D3D12 only, from IDXGIAdapter3::QueryVideoMemoryInfo(), incl. all resources
quint64 totalUsageBytes = 0;
};
Q_DECLARE_TYPEINFO(QRhiStats, Q_RELOCATABLE_TYPE);
@ -1629,7 +1628,8 @@ public:
Vulkan,
OpenGLES2,
D3D11,
Metal
Metal,
D3D12
};
enum Flag {

View File

@ -283,8 +283,10 @@ bool qrhi_toTopLeftRenderTargetRect(const QSize &outputSize, const std::array<T,
*w = *x < outputWidth ? qMax<T>(0, inputWidth - widthOffset) : 0;
*h = *y < outputHeight ? qMax<T>(0, inputHeight - heightOffset) : 0;
*x = qBound<T>(0, *x, outputWidth - 1);
*y = qBound<T>(0, *y, outputHeight - 1);
if (outputWidth > 0)
*x = qBound<T>(0, *x, outputWidth - 1);
if (outputHeight > 0)
*y = qBound<T>(0, *y, outputHeight - 1);
if (*x + *w > outputWidth)
*w = qMax<T>(0, outputWidth - *x);

5964
src/gui/rhi/qrhid3d12.cpp Normal file

File diff suppressed because it is too large Load Diff

48
src/gui/rhi/qrhid3d12_p.h Normal file
View File

@ -0,0 +1,48 @@
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QRHID3D12_H
#define QRHID3D12_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <private/qrhi_p.h>
// no d3d includes here, to prevent precompiled header mess due to COM
QT_BEGIN_NAMESPACE
struct Q_GUI_EXPORT QRhiD3D12InitParams : public QRhiInitParams
{
bool enableDebugLayer = false;
};
struct Q_GUI_EXPORT QRhiD3D12NativeHandles : public QRhiNativeHandles
{
// to import a device
void *dev = nullptr;
int minimumFeatureLevel = 0;
// to just specify the adapter to use, set these and leave dev set to null
quint32 adapterLuidLow = 0;
qint32 adapterLuidHigh = 0;
// in addition, can specify the command queue to use
void *commandQueue = nullptr;
};
struct Q_GUI_EXPORT QRhiD3D12CommandBufferNativeHandles : public QRhiNativeHandles
{
void *commandList = nullptr; // ID3D12GraphicsCommandList
};
QT_END_NAMESPACE
#endif

1166
src/gui/rhi/qrhid3d12_p_p.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,16 @@
[
{
"Id": "rhi-miniengine-d3d12-mipmap",
"Name": "Mipmap generator for D3D12",
"QDocModule": "qtgui",
"Description": "Compute shader for mipmap generation from MiniEngine in DirectX-Graphics-Samples",
"QtUsage": "Compute shader for mipmap generation with Direct 3D 12",
"Homepage": "https://github.com/microsoft/DirectX-Graphics-Samples",
"Version": "0aa79bad78992da0b6a8279ddb9002c1753cb849",
"License": "MIT License",
"LicenseId": "MIT",
"LicenseFile": "MiniEngine_LICENSE.txt",
"Copyright": "Copyright (c) 2015 Microsoft"
}
]

View File

@ -31,7 +31,9 @@
#ifdef Q_OS_WIN
#include <QtGui/private/qrhid3d11_p.h>
#include <QtGui/private/qrhid3d12_p.h>
# define TST_D3D11
# define TST_D3D12
#endif
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
@ -107,6 +109,8 @@ private slots:
void renderToTextureTexturedQuadAllDynamicBuffers();
void renderToTextureDeferredSrb_data();
void renderToTextureDeferredSrb();
void renderToTextureDeferredUpdateSamplerInSrb_data();
void renderToTextureDeferredUpdateSamplerInSrb();
void renderToTextureMultipleUniformBuffersAndDynamicOffset_data();
void renderToTextureMultipleUniformBuffersAndDynamicOffset();
void renderToTextureSrbReuse_data();
@ -156,7 +160,10 @@ private:
QRhiVulkanInitParams vk;
#endif
#ifdef TST_D3D11
QRhiD3D11InitParams d3d;
QRhiD3D11InitParams d3d11;
#endif
#ifdef TST_D3D12
QRhiD3D12InitParams d3d12;
#endif
#ifdef TST_MTL
QRhiMetalInitParams mtl;
@ -195,7 +202,10 @@ void tst_QRhi::initTestCase()
#endif
#ifdef TST_D3D11
initParams.d3d.enableDebugLayer = true;
initParams.d3d11.enableDebugLayer = true;
#endif
#ifdef TST_D3D12
initParams.d3d12.enableDebugLayer = true;
#endif
}
@ -226,7 +236,10 @@ void tst_QRhi::rhiTestData()
QTest::newRow("Vulkan") << QRhi::Vulkan << static_cast<QRhiInitParams *>(&initParams.vk);
#endif
#ifdef TST_D3D11
QTest::newRow("Direct3D 11") << QRhi::D3D11 << static_cast<QRhiInitParams *>(&initParams.d3d);
QTest::newRow("Direct3D 11") << QRhi::D3D11 << static_cast<QRhiInitParams *>(&initParams.d3d11);
#endif
#ifdef TST_D3D12
QTest::newRow("Direct3D 12") << QRhi::D3D12 << static_cast<QRhiInitParams *>(&initParams.d3d12);
#endif
#ifdef TST_MTL
QTest::newRow("Metal") << QRhi::Metal << static_cast<QRhiInitParams *>(&initParams.mtl);
@ -495,6 +508,17 @@ void tst_QRhi::nativeHandles()
}
break;
#endif
#ifdef TST_D3D12
case QRhi::D3D12:
{
const QRhiD3D12NativeHandles *d3dHandles = static_cast<const QRhiD3D12NativeHandles *>(rhiHandles);
QVERIFY(d3dHandles->dev);
QVERIFY(d3dHandles->minimumFeatureLevel > 0);
QVERIFY(d3dHandles->adapterLuidLow || d3dHandles->adapterLuidHigh);
QVERIFY(d3dHandles->commandQueue);
}
break;
#endif
#ifdef TST_MTL
case QRhi::Metal:
{
@ -539,6 +563,10 @@ void tst_QRhi::nativeHandles()
case QRhi::D3D11:
break;
#endif
#ifdef TST_D3D12
case QRhi::D3D12:
break;
#endif
#ifdef TST_MTL
case QRhi::Metal:
{
@ -598,6 +626,10 @@ void tst_QRhi::nativeHandles()
case QRhi::D3D11:
break;
#endif
#ifdef TST_D3D12
case QRhi::D3D12:
break;
#endif
#ifdef TST_MTL
case QRhi::Metal:
break;
@ -665,7 +697,7 @@ void tst_QRhi::nativeHandlesImportVulkan()
void tst_QRhi::nativeHandlesImportD3D11()
{
#ifdef TST_D3D11
QScopedPointer<QRhi> rhi(QRhi::create(QRhi::D3D11, &initParams.d3d, QRhi::Flags(), nullptr));
QScopedPointer<QRhi> rhi(QRhi::create(QRhi::D3D11, &initParams.d3d11, QRhi::Flags(), nullptr));
if (!rhi)
QSKIP("QRhi could not be created, skipping testing D3D11 native handle import");
@ -677,7 +709,7 @@ void tst_QRhi::nativeHandlesImportD3D11()
h.featureLevel = 0; // see if these are queried as expected, even when not provided
h.adapterLuidLow = 0;
h.adapterLuidHigh = 0;
QScopedPointer<QRhi> adoptingRhi(QRhi::create(QRhi::D3D11, &initParams.d3d, QRhi::Flags(), &h));
QScopedPointer<QRhi> adoptingRhi(QRhi::create(QRhi::D3D11, &initParams.d3d11, QRhi::Flags(), &h));
QVERIFY(adoptingRhi);
const QRhiD3D11NativeHandles *newNativeHandles = static_cast<const QRhiD3D11NativeHandles *>(adoptingRhi->nativeHandles());
QCOMPARE(newNativeHandles->dev, nativeHandles->dev);
@ -692,7 +724,7 @@ void tst_QRhi::nativeHandlesImportD3D11()
QRhiD3D11NativeHandles h = *nativeHandles;
h.dev = nullptr;
h.context = nullptr;
QScopedPointer<QRhi> adoptingRhi(QRhi::create(QRhi::D3D11, &initParams.d3d, QRhi::Flags(), &h));
QScopedPointer<QRhi> adoptingRhi(QRhi::create(QRhi::D3D11, &initParams.d3d11, QRhi::Flags(), &h));
QVERIFY(adoptingRhi);
const QRhiD3D11NativeHandles *newNativeHandles = static_cast<const QRhiD3D11NativeHandles *>(adoptingRhi->nativeHandles());
QVERIFY(newNativeHandles->dev != nativeHandles->dev);
@ -777,6 +809,14 @@ void tst_QRhi::nativeTexture()
}
break;
#endif
#ifdef TST_D3D12
case QRhi::D3D12:
{
auto *texture = reinterpret_cast<void *>(nativeTex.object);
QVERIFY(texture);
}
break;
#endif
#ifdef TST_MTL
case QRhi::Metal:
{
@ -852,6 +892,18 @@ void tst_QRhi::nativeBuffer()
}
break;
#endif
#ifdef TST_D3D12
case QRhi::D3D12:
{
QVERIFY(nativeBuf.slotCount >= 1); // always backed by native buffers
for (int i = 0; i < nativeBuf.slotCount; ++i) {
auto *buffer = static_cast<void * const *>(nativeBuf.objects[i]);
QVERIFY(buffer);
QVERIFY(*buffer);
}
}
break;
#endif
#ifdef TST_MTL
case QRhi::Metal:
{
@ -2953,6 +3005,147 @@ void tst_QRhi::renderToTextureDeferredSrb()
QCOMPARE(result.pixel(4, 227), empty);
}
void tst_QRhi::renderToTextureDeferredUpdateSamplerInSrb_data()
{
rhiTestData();
}
void tst_QRhi::renderToTextureDeferredUpdateSamplerInSrb()
{
QFETCH(QRhi::Implementation, impl);
QFETCH(QRhiInitParams *, initParams);
QScopedPointer<QRhi> rhi(QRhi::create(impl, initParams, QRhi::Flags(), nullptr));
if (!rhi)
QSKIP("QRhi could not be created, skipping testing rendering");
QImage inputImage;
inputImage.load(QLatin1String(":/data/qt256.png"));
QVERIFY(!inputImage.isNull());
QScopedPointer<QRhiTexture> texture(rhi->newTexture(QRhiTexture::RGBA8, inputImage.size(), 1,
QRhiTexture::RenderTarget | QRhiTexture::UsedAsTransferSource));
QVERIFY(texture->create());
QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ texture.data() }));
QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor());
rt->setRenderPassDescriptor(rpDesc.data());
QVERIFY(rt->create());
QRhiCommandBuffer *cb = nullptr;
QVERIFY(rhi->beginOffscreenFrame(&cb) == QRhi::FrameOpSuccess);
QVERIFY(cb);
QRhiResourceUpdateBatch *updates = rhi->nextResourceUpdateBatch();
QScopedPointer<QRhiBuffer> vbuf(rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(quadVerticesUvs)));
QVERIFY(vbuf->create());
updates->uploadStaticBuffer(vbuf.data(), quadVerticesUvs);
QScopedPointer<QRhiTexture> inputTexture(rhi->newTexture(QRhiTexture::RGBA8, inputImage.size()));
QVERIFY(inputTexture->create());
updates->uploadTexture(inputTexture.data(), inputImage);
QScopedPointer<QRhiSampler> sampler1(rhi->newSampler(QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::Linear,
QRhiSampler::Repeat, QRhiSampler::Repeat));
QVERIFY(sampler1->create());
QScopedPointer<QRhiSampler> sampler2(rhi->newSampler(QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None,
QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge));
QVERIFY(sampler2->create());
QScopedPointer<QRhiBuffer> ubuf(rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64 + 4));
QVERIFY(ubuf->create());
QMatrix4x4 matrix;
updates->updateDynamicBuffer(ubuf.data(), 0, 64, matrix.constData());
float opacity = 0.5f;
updates->updateDynamicBuffer(ubuf.data(), 64, 4, &opacity);
const QRhiShaderResourceBinding::StageFlags commonVisibility = QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage;
QScopedPointer<QRhiShaderResourceBindings> srb(rhi->newShaderResourceBindings());
srb->setBindings({
QRhiShaderResourceBinding::uniformBuffer(0, commonVisibility, ubuf.data()),
QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, inputTexture.data(), sampler1.data())
});
QVERIFY(srb->create());
QScopedPointer<QRhiGraphicsPipeline> pipeline(rhi->newGraphicsPipeline());
pipeline->setTopology(QRhiGraphicsPipeline::TriangleStrip);
QShader vs = loadShader(":/data/textured.vert.qsb");
QVERIFY(vs.isValid());
QShader fs = loadShader(":/data/textured.frag.qsb");
QVERIFY(fs.isValid());
pipeline->setShaderStages({ { QRhiShaderStage::Vertex, vs }, { QRhiShaderStage::Fragment, fs } });
QRhiVertexInputLayout inputLayout;
inputLayout.setBindings({ { 4 * sizeof(float) } });
inputLayout.setAttributes({
{ 0, 0, QRhiVertexInputAttribute::Float2, 0 },
{ 0, 1, QRhiVertexInputAttribute::Float2, 2 * sizeof(float) }
});
pipeline->setVertexInputLayout(inputLayout);
pipeline->setShaderResourceBindings(srb.data());
pipeline->setRenderPassDescriptor(rpDesc.data());
QVERIFY(pipeline->create());
// Now update the sampler to a different one, so if the pipeline->create()
// baked in static samplers somewhere (with 3D APIs where that's a thing),
// based on sampler1, that's now all invalid.
srb->setBindings({
QRhiShaderResourceBinding::uniformBuffer(0, commonVisibility, ubuf.data()),
QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, inputTexture.data(), sampler2.data())
});
srb->updateResources(); // now it references sampler2, not sampler1
cb->beginPass(rt.data(), Qt::black, { 1.0f, 0 }, updates);
cb->setGraphicsPipeline(pipeline.data());
cb->setShaderResources();
cb->setViewport({ 0, 0, float(texture->pixelSize().width()), float(texture->pixelSize().height()) });
QRhiCommandBuffer::VertexInput vbindings(vbuf.data(), 0);
cb->setVertexInput(0, 1, &vbindings);
cb->draw(4);
QRhiReadbackResult readResult;
QImage result;
readResult.completed = [&readResult, &result] {
result = QImage(reinterpret_cast<const uchar *>(readResult.data.constData()),
readResult.pixelSize.width(), readResult.pixelSize.height(),
QImage::Format_RGBA8888_Premultiplied);
};
QRhiResourceUpdateBatch *readbackBatch = rhi->nextResourceUpdateBatch();
readbackBatch->readBackTexture({ texture.data() }, &readResult);
cb->endPass(readbackBatch);
rhi->endOffscreenFrame();
QVERIFY(!result.isNull());
if (impl == QRhi::Null)
return;
if (rhi->isYUpInFramebuffer() != rhi->isYUpInNDC())
result = std::move(result).mirrored();
// opacity 0.5 (premultiplied)
static const auto checkSemiWhite = [](const QRgb &c) {
QRgb semiWhite127 = qPremultiply(qRgba(255, 255, 255, 127));
QRgb semiWhite128 = qPremultiply(qRgba(255, 255, 255, 128));
return c == semiWhite127 || c == semiWhite128;
};
QVERIFY(checkSemiWhite(result.pixel(79, 77)));
QVERIFY(checkSemiWhite(result.pixel(124, 81)));
QVERIFY(checkSemiWhite(result.pixel(128, 149)));
QVERIFY(checkSemiWhite(result.pixel(120, 189)));
QVERIFY(checkSemiWhite(result.pixel(116, 185)));
QVERIFY(checkSemiWhite(result.pixel(191, 172)));
QRgb empty = qRgba(0, 0, 0, 0);
QCOMPARE(result.pixel(11, 45), empty);
QCOMPARE(result.pixel(246, 202), empty);
QCOMPARE(result.pixel(130, 18), empty);
QCOMPARE(result.pixel(4, 227), empty);
}
void tst_QRhi::renderToTextureMultipleUniformBuffersAndDynamicOffset_data()
{
rhiTestData();
@ -4601,8 +4794,11 @@ void tst_QRhi::threeDimTexture()
// Some software-based OpenGL implementations, such as Mesa llvmpipe builds that are
// used both in Qt CI and are shipped with the official Qt binaries also seem to have
// problems with this.
if (impl != QRhi::Null && impl != QRhi::OpenGLES2)
QVERIFY(imageRGBAEquals(result, referenceImage, 2));
if (impl != QRhi::Null && impl != QRhi::OpenGLES2) {
// temporarily skip for D3D12 as well since 3D texture mipmap generation is not implemented there
if (impl != QRhi::D3D12)
QVERIFY(imageRGBAEquals(result, referenceImage, 2));
}
}
// render target (one slice)
@ -5435,7 +5631,7 @@ void tst_QRhi::tessellation()
QSKIP("Tessellation is not supported with this graphics API, skipping test");
}
if (rhi->backend() == QRhi::D3D11)
if (rhi->backend() == QRhi::D3D11 || rhi->backend() == QRhi::D3D12)
QSKIP("Skipping tessellation test on D3D for now, test assets not prepared for HLSL yet");
QScopedPointer<QRhiTexture> texture(rhi->newTexture(QRhiTexture::RGBA8, QSize(1280, 720), 1,

View File

@ -20,6 +20,8 @@ QString graphicsApiName(QRhi::Implementation graphicsApi)
return QLatin1String("Vulkan");
case QRhi::D3D11:
return QLatin1String("Direct3D 11");
case QRhi::D3D12:
return QLatin1String("Direct3D 12");
case QRhi::Metal:
return QLatin1String("Metal");
default:
@ -51,8 +53,10 @@ int main(int argc, char **argv)
cmdLineParser.addOption(glOption);
QCommandLineOption vkOption({ "v", "vulkan" }, QLatin1String("Vulkan"));
cmdLineParser.addOption(vkOption);
QCommandLineOption d3dOption({ "d", "d3d11" }, QLatin1String("Direct3D 11"));
cmdLineParser.addOption(d3dOption);
QCommandLineOption d3d11Option({ "d", "d3d11" }, QLatin1String("Direct3D 11"));
cmdLineParser.addOption(d3d11Option);
QCommandLineOption d3d12Option({ "D", "d3d12" }, QLatin1String("Direct3D 12"));
cmdLineParser.addOption(d3d12Option);
QCommandLineOption mtlOption({ "m", "metal" }, QLatin1String("Metal"));
cmdLineParser.addOption(mtlOption);
@ -63,8 +67,10 @@ int main(int argc, char **argv)
graphicsApi = QRhi::OpenGLES2;
if (cmdLineParser.isSet(vkOption))
graphicsApi = QRhi::Vulkan;
if (cmdLineParser.isSet(d3dOption))
if (cmdLineParser.isSet(d3d11Option))
graphicsApi = QRhi::D3D11;
if (cmdLineParser.isSet(d3d12Option))
graphicsApi = QRhi::D3D12;
if (cmdLineParser.isSet(mtlOption))
graphicsApi = QRhi::Metal;

View File

@ -16,6 +16,7 @@ Window::Window(QRhi::Implementation graphicsApi)
setSurfaceType(VulkanSurface);
break;
case QRhi::D3D11:
case QRhi::D3D12:
setSurfaceType(Direct3DSurface);
break;
case QRhi::Metal:
@ -112,6 +113,10 @@ void Window::init()
QRhiD3D11InitParams params;
params.enableDebugLayer = true;
m_rhi.reset(QRhi::create(QRhi::D3D11, &params, rhiFlags));
} else if (m_graphicsApi == QRhi::D3D12) {
QRhiD3D12InitParams params;
params.enableDebugLayer = true;
m_rhi.reset(QRhi::create(QRhi::D3D12, &params, rhiFlags));
}
#endif

View File

@ -16,6 +16,7 @@
#endif
#ifdef Q_OS_WIN
#include <QtGui/private/qrhid3d11_p.h>
#include <QtGui/private/qrhid3d12_p.h>
#endif
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
#include <QtGui/private/qrhimetal_p.h>

View File

@ -23,6 +23,7 @@
#ifdef Q_OS_WIN
#include <QtGui/private/qrhid3d11_p.h>
#include <QtGui/private/qrhid3d12_p.h>
#endif
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
@ -51,6 +52,7 @@ enum GraphicsApi
OpenGL,
Vulkan,
D3D11,
D3D12,
Metal,
Null
};
@ -66,6 +68,8 @@ QString graphicsApiName()
return QLatin1String("Vulkan");
case D3D11:
return QLatin1String("Direct3D 11");
case D3D12:
return QLatin1String("Direct3D 12");
case Metal:
return QLatin1String("Metal");
case Null:
@ -96,8 +100,10 @@ int main(int argc, char **argv)
cmdLineParser.addOption(glOption);
QCommandLineOption vkOption({ "v", "vulkan" }, QLatin1String("Vulkan"));
cmdLineParser.addOption(vkOption);
QCommandLineOption d3dOption({ "d", "d3d11" }, QLatin1String("Direct3D 11"));
cmdLineParser.addOption(d3dOption);
QCommandLineOption d3d11Option({ "d", "d3d11" }, QLatin1String("Direct3D 11"));
cmdLineParser.addOption(d3d11Option);
QCommandLineOption d3d12Option({ "D", "d3d12" }, QLatin1String("Direct3D 12"));
cmdLineParser.addOption(d3d12Option);
QCommandLineOption mtlOption({ "m", "metal" }, QLatin1String("Metal"));
cmdLineParser.addOption(mtlOption);
QCommandLineOption nullOption({ "n", "null" }, QLatin1String("Null"));
@ -107,8 +113,10 @@ int main(int argc, char **argv)
graphicsApi = OpenGL;
if (cmdLineParser.isSet(vkOption))
graphicsApi = Vulkan;
if (cmdLineParser.isSet(d3dOption))
if (cmdLineParser.isSet(d3d11Option))
graphicsApi = D3D11;
if (cmdLineParser.isSet(d3d12Option))
graphicsApi = D3D12;
if (cmdLineParser.isSet(mtlOption))
graphicsApi = Metal;
if (cmdLineParser.isSet(nullOption))
@ -155,6 +163,10 @@ int main(int argc, char **argv)
QRhiD3D11InitParams params;
params.enableDebugLayer = true;
r = QRhi::create(QRhi::D3D11, &params);
} else if (graphicsApi == D3D12) {
QRhiD3D12InitParams params;
params.enableDebugLayer = true;
r = QRhi::create(QRhi::D3D12, &params);
}
#endif

View File

@ -29,6 +29,7 @@
#ifdef Q_OS_WIN
#include <QtGui/private/qrhid3d11_p.h>
#include <QtGui/private/qrhid3d12_p.h>
#endif
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
@ -50,6 +51,7 @@ enum GraphicsApi
OpenGL,
Vulkan,
D3D11,
D3D12,
Metal
};
@ -66,6 +68,8 @@ QString graphicsApiName()
return QLatin1String("Vulkan");
case D3D11:
return QLatin1String("Direct3D 11");
case D3D12:
return QLatin1String("Direct3D 12");
case Metal:
return QLatin1String("Metal");
default:
@ -141,6 +145,7 @@ Window::Window()
setSurfaceType(VulkanSurface);
break;
case D3D11:
case D3D12:
setSurfaceType(Direct3DSurface);
break;
case Metal:
@ -243,6 +248,12 @@ void Window::init()
params.repeatDeviceKill = true;
}
m_r = QRhi::create(QRhi::D3D11, &params, rhiFlags);
} else if (graphicsApi == D3D12) {
QRhiD3D12InitParams params;
if (debugLayer)
qDebug("Enabling D3D12 debug layer");
params.enableDebugLayer = debugLayer;
m_r = QRhi::create(QRhi::D3D12, &params, rhiFlags);
}
#endif
@ -390,8 +401,10 @@ int main(int argc, char **argv)
cmdLineParser.addOption(glOption);
QCommandLineOption vkOption({ "v", "vulkan" }, QLatin1String("Vulkan"));
cmdLineParser.addOption(vkOption);
QCommandLineOption d3dOption({ "d", "d3d11" }, QLatin1String("Direct3D 11"));
cmdLineParser.addOption(d3dOption);
QCommandLineOption d3d11Option({ "d", "d3d11" }, QLatin1String("Direct3D 11"));
cmdLineParser.addOption(d3d11Option);
QCommandLineOption d3d12Option({ "D", "d3d12" }, QLatin1String("Direct3D 12"));
cmdLineParser.addOption(d3d12Option);
QCommandLineOption mtlOption({ "m", "metal" }, QLatin1String("Metal"));
cmdLineParser.addOption(mtlOption);
// Testing cleanup both with QWindow::close() (hitting X or Alt-F4) and
@ -421,8 +434,10 @@ int main(int argc, char **argv)
graphicsApi = OpenGL;
if (cmdLineParser.isSet(vkOption))
graphicsApi = Vulkan;
if (cmdLineParser.isSet(d3dOption))
if (cmdLineParser.isSet(d3d11Option))
graphicsApi = D3D11;
if (cmdLineParser.isSet(d3d12Option))
graphicsApi = D3D12;
if (cmdLineParser.isSet(mtlOption))
graphicsApi = Metal;

View File

@ -43,7 +43,9 @@ void Window::customInit()
if (!m_r->isFeatureSupported(QRhi::TextureArrays))
qFatal("Texture array objects are not supported by this backend");
d.texArr = m_r->newTextureArray(QRhiTexture::RGBA8, ARRAY_SIZE, QSize(512, 512));
d.texArr = m_r->newTextureArray(QRhiTexture::RGBA8, ARRAY_SIZE, QSize(512, 512), 1,
// mipmaps will be generated, to exercise that too
QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips);
d.releasePool << d.texArr;
d.texArr->create();
@ -59,7 +61,9 @@ void Window::customInit()
img.fill(Qt::yellow);
d.initialUpdates->uploadTexture(d.texArr, QRhiTextureUploadDescription(QRhiTextureUploadEntry(3, 0, QRhiTextureSubresourceUploadDescription(img))));
d.sampler = m_r->newSampler(QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
d.initialUpdates->generateMips(d.texArr);
d.sampler = m_r->newSampler(QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::Linear,
QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
d.releasePool << d.sampler;
d.sampler->create();