Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qrhid3d12_p.h
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QRHID3D12_P_H
5#define QRHID3D12_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qrhi_p.h"
19#include <QWindow>
20#include <QBitArray>
21
22#include <optional>
23#include <array>
24
25#include <d3d12.h>
26#include <d3d12sdklayers.h>
27#include <dxgi1_6.h>
28#include <dcomp.h>
29
30#include "D3D12MemAlloc.h"
31
32// ID3D12Device2 and ID3D12GraphicsCommandList1 and types and enums introduced
33// with those are hard requirements now. These should be declared in any
34// moderately recent d3d12.h, but if it is an SDK from before Windows 10
35// version 1703 then these types could be missing. In the absence of other
36// options, handle this by skipping all the code and making QRhi::create() fail
37// in such builds.
38#ifdef __ID3D12Device2_INTERFACE_DEFINED__
39#define QRHI_D3D12_AVAILABLE
40
42
43static const int QD3D12_FRAMES_IN_FLIGHT = 2;
44
45class QRhiD3D12;
46
47struct QD3D12Descriptor
48{
49 D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle = {};
50 D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle = {};
51
52 bool isValid() const { return cpuHandle.ptr != 0; }
53};
54
55struct QD3D12ReleaseQueue;
56
57struct QD3D12DescriptorHeap
58{
59 bool isValid() const { return heap && capacity; }
60 bool create(ID3D12Device *device,
61 quint32 descriptorCount,
62 D3D12_DESCRIPTOR_HEAP_TYPE heapType,
63 D3D12_DESCRIPTOR_HEAP_FLAGS heapFlags);
64 void createWithExisting(const QD3D12DescriptorHeap &other,
65 quint32 offsetInDescriptors,
66 quint32 descriptorCount);
67 void destroy();
68 void destroyWithDeferredRelease(QD3D12ReleaseQueue *releaseQueue);
69
70 QD3D12Descriptor get(quint32 count);
71 QD3D12Descriptor at(quint32 index) const;
72 quint32 remainingCapacity() const { return capacity - head; }
73
74 QD3D12Descriptor incremented(const QD3D12Descriptor &descriptor, quint32 offsetInDescriptors) const
75 {
76 D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle = descriptor.cpuHandle;
77 cpuHandle.ptr += offsetInDescriptors * descriptorByteSize;
78 D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle = descriptor.gpuHandle;
79 if (gpuHandle.ptr)
80 gpuHandle.ptr += offsetInDescriptors * descriptorByteSize;
81 return { cpuHandle, gpuHandle };
82 }
83
84 ID3D12DescriptorHeap *heap = nullptr;
85 quint32 capacity = 0;
86 QD3D12Descriptor heapStart;
87 quint32 head = 0;
88 quint32 descriptorByteSize = 0;
89 D3D12_DESCRIPTOR_HEAP_TYPE heapType;
90 D3D12_DESCRIPTOR_HEAP_FLAGS heapFlags;
91};
92
93struct QD3D12CpuDescriptorPool
94{
95 bool isValid() const { return !heaps.isEmpty(); }
96 bool create(ID3D12Device *device, D3D12_DESCRIPTOR_HEAP_TYPE heapType, const char *debugName = "");
97 void destroy();
98
99 QD3D12Descriptor allocate(quint32 count);
100 void release(const QD3D12Descriptor &descriptor, quint32 count);
101
102 static const int DESCRIPTORS_PER_HEAP = 256;
103
104 struct HeapWithMap {
105 QD3D12DescriptorHeap heap;
107 static HeapWithMap init(const QD3D12DescriptorHeap &heap, quint32 descriptorCount) {
108 HeapWithMap result;
109 result.heap = heap;
110 result.map.resize(descriptorCount);
111 return result;
112 }
113 };
114
115 ID3D12Device *device;
116 quint32 descriptorByteSize;
117 QVector<HeapWithMap> heaps;
118 const char *debugName;
119};
120
121struct QD3D12QueryHeap
122{
123 bool isValid() const { return heap && capacity; }
124 bool create(ID3D12Device *device,
125 quint32 queryCount,
126 D3D12_QUERY_HEAP_TYPE heapType);
127 void destroy();
128
129 ID3D12QueryHeap *heap = nullptr;
130 quint32 capacity = 0;
131};
132
133struct QD3D12StagingArea
134{
135 static const quint32 ALIGNMENT = D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT; // 512 so good enough both for cb and texdata
136
137 struct Allocation {
138 quint8 *p = nullptr;
139 D3D12_GPU_VIRTUAL_ADDRESS gpuAddr = 0;
140 ID3D12Resource *buffer = nullptr;
141 quint32 bufferOffset = 0;
142 bool isValid() const { return p != nullptr; }
143 };
144
145 bool isValid() const { return allocation && mem.isValid(); }
146 bool create(QRhiD3D12 *rhi, quint32 capacity, D3D12_HEAP_TYPE heapType);
147 void destroy();
148 void destroyWithDeferredRelease(QD3D12ReleaseQueue *releaseQueue);
149
150 Allocation get(quint32 byteSize);
151
152 quint32 remainingCapacity() const
153 {
154 return capacity - head;
155 }
156
157 static quint32 allocSizeForArray(quint32 size, int count = 1)
158 {
159 return count * ((size + ALIGNMENT - 1) & ~(ALIGNMENT - 1));
160 }
161
162 Allocation mem;
163 ID3D12Resource *resource = nullptr;
164 D3D12MA::Allocation *allocation = nullptr;
167};
168
169struct QD3D12ObjectHandle
170{
171 quint32 index = 0;
172 quint32 generation = 0;
173
174 // the default, null handle is guaranteed to give ObjectPool::isValid() == false
175 bool isNull() const { return index == 0 && generation == 0; }
176};
177
178inline bool operator==(const QD3D12ObjectHandle &a, const QD3D12ObjectHandle &b) noexcept
179{
180 return a.index == b.index && a.generation == b.generation;
181}
182
183inline bool operator!=(const QD3D12ObjectHandle &a, const QD3D12ObjectHandle &b) noexcept
184{
185 return !(a == b);
186}
187
188template<typename T>
189struct QD3D12ObjectPool
190{
191 void create(const char *debugName = "")
192 {
193 this->debugName = debugName;
194 Q_ASSERT(data.isEmpty());
195 data.append(Data()); // index 0 is always invalid
196 }
197
198 void destroy() {
199 int leakCount = 0; // will nicely destroy everything here, but warn about it if enabled
200 for (Data &d : data) {
201 if (d.object.has_value()) {
202 leakCount += 1;
203 d.object->releaseResources();
204 }
205 }
206 data.clear();
207#ifndef QT_NO_DEBUG
208 // debug builds: just do it always
209 static bool leakCheck = true;
210#else
211 // release builds: opt-in
212 static bool leakCheck = qEnvironmentVariableIntValue("QT_RHI_LEAK_CHECK");
213#endif
214 if (leakCheck) {
215 if (leakCount > 0) {
216 qWarning("QD3D12ObjectPool::destroy(): Pool %p '%s' had %d unreleased objects",
217 this, debugName, leakCount);
218 }
219 }
220 }
221
222 bool isValid(const QD3D12ObjectHandle &handle) const
223 {
224 return handle.index > 0
225 && handle.index < quint32(data.count())
226 && handle.generation > 0
227 && handle.generation == data[handle.index].generation
228 && data[handle.index].object.has_value();
229 }
230
231 T lookup(const QD3D12ObjectHandle &handle) const
232 {
233 return isValid(handle) ? *data[handle.index].object : T();
234 }
235
236 const T *lookupRef(const QD3D12ObjectHandle &handle) const
237 {
238 return isValid(handle) ? &*data[handle.index].object : nullptr;
239 }
240
241 T *lookupRef(const QD3D12ObjectHandle &handle)
242 {
243 return isValid(handle) ? &*data[handle.index].object : nullptr;
244 }
245
246 QD3D12ObjectHandle add(const T &object)
247 {
248 Q_ASSERT(!data.isEmpty());
249 const quint32 count = quint32(data.count());
250 quint32 index = 1; // index 0 is always invalid
251 for (; index < count; ++index) {
252 if (!data[index].object.has_value())
253 break;
254 }
255 if (index < count) {
256 data[index].object = object;
257 quint32 &generation = data[index].generation;
258 generation += 1u;
259 return { index, generation };
260 } else {
261 data.append({ object, 1 });
262 return { count, 1 };
263 }
264 }
265
266 void remove(const QD3D12ObjectHandle &handle)
267 {
268 if (T *object = lookupRef(handle)) {
269 object->releaseResources();
270 data[handle.index].object.reset();
271 }
272 }
273
274 const char *debugName;
275 struct Data {
276 std::optional<T> object;
277 quint32 generation = 0;
278 };
279 QVector<Data> data;
280};
281
282struct QD3D12Resource
283{
284 ID3D12Resource *resource;
285 D3D12_RESOURCE_STATES state;
286 D3D12_RESOURCE_DESC desc;
287 D3D12MA::Allocation *allocation;
288 void *cpuMapPtr;
289 enum { UavUsageRead = 0x01, UavUsageWrite = 0x02 };
290 int uavUsage;
291 bool owns;
292
293 // note that this assumes the allocation (if there is one) and the resource
294 // are separately releaseable, see D3D12MemAlloc docs
295 static QD3D12ObjectHandle addToPool(QD3D12ObjectPool<QD3D12Resource> *pool,
296 ID3D12Resource *resource,
297 D3D12_RESOURCE_STATES state,
298 D3D12MA::Allocation *allocation = nullptr,
299 void *cpuMapPtr = nullptr)
300 {
301 Q_ASSERT(resource);
302 return pool->add({ resource, state, resource->GetDesc(), allocation, cpuMapPtr, 0, true });
303 }
304
305 // for QRhiTexture::createFrom() where the ID3D12Resource is not owned by us
306 static QD3D12ObjectHandle addNonOwningToPool(QD3D12ObjectPool<QD3D12Resource> *pool,
307 ID3D12Resource *resource,
308 D3D12_RESOURCE_STATES state)
309 {
310 Q_ASSERT(resource);
311 return pool->add({ resource, state, resource->GetDesc(), nullptr, nullptr, 0, false });
312 }
313
314 void releaseResources()
315 {
316 if (owns) {
317 // order matters: resource first, then the allocation
318 resource->Release();
319 if (allocation)
320 allocation->Release();
321 }
322 }
323};
324
325struct QD3D12Pipeline
326{
327 enum Type {
328 Graphics,
329 Compute
330 };
331 Type type;
332 ID3D12PipelineState *pso;
333
334 static QD3D12ObjectHandle addToPool(QD3D12ObjectPool<QD3D12Pipeline> *pool,
335 Type type,
336 ID3D12PipelineState *pso)
337 {
338 return pool->add({ type, pso });
339 }
340
341 void releaseResources()
342 {
343 pso->Release();
344 }
345};
346
347struct QD3D12RootSignature
348{
349 ID3D12RootSignature *rootSig;
350
351 static QD3D12ObjectHandle addToPool(QD3D12ObjectPool<QD3D12RootSignature> *pool,
352 ID3D12RootSignature *rootSig)
353 {
354 return pool->add({ rootSig });
355 }
356
357 void releaseResources()
358 {
359 rootSig->Release();
360 }
361};
362
363struct QD3D12ReleaseQueue
364{
365 void create(QD3D12ObjectPool<QD3D12Resource> *resourcePool,
366 QD3D12ObjectPool<QD3D12Pipeline> *pipelinePool,
367 QD3D12ObjectPool<QD3D12RootSignature> *rootSignaturePool)
368 {
369 this->resourcePool = resourcePool;
370 this->pipelinePool = pipelinePool;
371 this->rootSignaturePool = rootSignaturePool;
372 }
373
374 void deferredReleaseResource(const QD3D12ObjectHandle &handle);
375 void deferredReleaseResourceWithViews(const QD3D12ObjectHandle &handle,
376 QD3D12CpuDescriptorPool *pool,
377 const QD3D12Descriptor &viewsStart,
378 int viewCount);
379 void deferredReleasePipeline(const QD3D12ObjectHandle &handle);
380 void deferredReleaseRootSignature(const QD3D12ObjectHandle &handle);
381 void deferredReleaseCallback(std::function<void(void*)> callback, void *userData);
382 void deferredReleaseResourceAndAllocation(ID3D12Resource *resource,
383 D3D12MA::Allocation *allocation);
384 void deferredReleaseDescriptorHeap(ID3D12DescriptorHeap *heap);
385 void deferredReleaseViews(QD3D12CpuDescriptorPool *pool,
386 const QD3D12Descriptor &viewsStart,
387 int viewCount);
388
389 void activatePendingDeferredReleaseRequests(int frameSlot);
390 void executeDeferredReleases(int frameSlot, bool forced = false);
391 void releaseAll();
392
393 struct DeferredReleaseEntry {
394 enum Type {
395 Resource,
396 Pipeline,
397 RootSignature,
398 Callback,
399 ResourceAndAllocation,
400 DescriptorHeap,
401 Views
402 };
403 Type type = Resource;
404 std::optional<int> frameSlotToBeReleasedIn;
405 QD3D12ObjectHandle handle;
406 QD3D12CpuDescriptorPool *poolForViews = nullptr;
407 QD3D12Descriptor viewsStart;
408 int viewCount = 0;
409 std::function<void(void*)> callback = nullptr;
410 void *callbackUserData = nullptr;
411 QPair<ID3D12Resource *, D3D12MA::Allocation *> resourceAndAllocation = {};
412 ID3D12DescriptorHeap *descriptorHeap = nullptr;
413 };
414 QVector<DeferredReleaseEntry> queue;
415 QD3D12ObjectPool<QD3D12Resource> *resourcePool = nullptr;
416 QD3D12ObjectPool<QD3D12Pipeline> *pipelinePool = nullptr;
417 QD3D12ObjectPool<QD3D12RootSignature> *rootSignaturePool = nullptr;
418};
419
420struct QD3D12CommandBuffer;
421
422struct QD3D12ResourceBarrierGenerator
423{
424 static const int PREALLOC = 16;
425
426 void create(QD3D12ObjectPool<QD3D12Resource> *resourcePool)
427 {
428 this->resourcePool = resourcePool;
429 }
430
431 void addTransitionBarrier(const QD3D12ObjectHandle &resourceHandle, D3D12_RESOURCE_STATES stateAfter);
432 void enqueueBufferedTransitionBarriers(QD3D12CommandBuffer *cbD);
433 void enqueueSubresourceTransitionBarrier(QD3D12CommandBuffer *cbD,
434 const QD3D12ObjectHandle &resourceHandle,
435 UINT subresource,
436 D3D12_RESOURCE_STATES stateBefore,
437 D3D12_RESOURCE_STATES stateAfter);
438 void enqueueUavBarrier(QD3D12CommandBuffer *cbD, const QD3D12ObjectHandle &resourceHandle);
439
440 struct TransitionResourceBarrier {
441 QD3D12ObjectHandle resourceHandle;
442 D3D12_RESOURCE_STATES stateBefore;
443 D3D12_RESOURCE_STATES stateAfter;
444 };
445 QVarLengthArray<TransitionResourceBarrier, PREALLOC> transitionResourceBarriers;
446 QD3D12ObjectPool<QD3D12Resource> *resourcePool = nullptr;
447};
448
449struct QD3D12ShaderBytecodeCache
450{
451 struct Shader {
452 Shader() = default;
453 Shader(const QByteArray &bytecode, const QShader::NativeResourceBindingMap &rbm)
454 : bytecode(bytecode), nativeResourceBindingMap(rbm)
455 { }
456 QByteArray bytecode;
457 QShader::NativeResourceBindingMap nativeResourceBindingMap;
458 };
459
460 QHash<QRhiShaderStage, Shader> data;
461
462 void insertWithCapacityLimit(const QRhiShaderStage &key, const Shader &s);
463};
464
465struct QD3D12ShaderVisibleDescriptorHeap
466{
467 bool create(ID3D12Device *device, D3D12_DESCRIPTOR_HEAP_TYPE type, quint32 perFrameDescriptorCount);
468 void destroy();
469 void destroyWithDeferredRelease(QD3D12ReleaseQueue *releaseQueue);
470
471 QD3D12DescriptorHeap heap;
472 QD3D12DescriptorHeap perFrameHeapSlice[QD3D12_FRAMES_IN_FLIGHT];
473};
474
475// wrap foreign struct so we can legally supply equality operators and qHash:
476struct Q_D3D12_SAMPLER_DESC
477{
478 D3D12_SAMPLER_DESC desc;
479
480 friend bool operator==(const Q_D3D12_SAMPLER_DESC &lhs, const Q_D3D12_SAMPLER_DESC &rhs) noexcept
481 {
482 return lhs.desc.Filter == rhs.desc.Filter
483 && lhs.desc.AddressU == rhs.desc.AddressU
484 && lhs.desc.AddressV == rhs.desc.AddressV
485 && lhs.desc.AddressW == rhs.desc.AddressW
486 && lhs.desc.MipLODBias == rhs.desc.MipLODBias
487 && lhs.desc.MaxAnisotropy == rhs.desc.MaxAnisotropy
488 && lhs.desc.ComparisonFunc == rhs.desc.ComparisonFunc
489 // BorderColor is never used, skip it
490 && lhs.desc.MinLOD == rhs.desc.MinLOD
491 && lhs.desc.MaxLOD == rhs.desc.MaxLOD;
492 }
493
494 friend bool operator!=(const Q_D3D12_SAMPLER_DESC &lhs, const Q_D3D12_SAMPLER_DESC &rhs) noexcept
495 {
496 return !(lhs == rhs);
497 }
498
499 friend size_t qHash(const Q_D3D12_SAMPLER_DESC &key, size_t seed = 0) noexcept
500 {
502 seed = hash(seed, key.desc.Filter);
503 seed = hash(seed, key.desc.AddressU);
504 seed = hash(seed, key.desc.AddressV);
505 seed = hash(seed, key.desc.AddressW);
506 seed = hash(seed, key.desc.MipLODBias);
507 seed = hash(seed, key.desc.MaxAnisotropy);
508 seed = hash(seed, key.desc.ComparisonFunc);
509 // BorderColor is never used, skip it
510 seed = hash(seed, key.desc.MinLOD);
511 seed = hash(seed, key.desc.MaxLOD);
512 return seed;
513 }
514};
515
516struct QD3D12SamplerManager
517{
518 const quint32 MAX_SAMPLERS = 512;
519
520 bool create(ID3D12Device *device);
521 void destroy();
522
523 QD3D12Descriptor getShaderVisibleDescriptor(const D3D12_SAMPLER_DESC &desc);
524
525 ID3D12Device *device = nullptr;
526 QD3D12ShaderVisibleDescriptorHeap shaderVisibleSamplerHeap;
527 QHash<Q_D3D12_SAMPLER_DESC, QD3D12Descriptor> gpuMap;
528};
529
530enum QD3D12Stage { VS = 0, HS, DS, GS, PS, CS };
531
532static inline QD3D12Stage qd3d12_stage(QRhiShaderStage::Type type)
533{
534 switch (type) {
536 return VS;
538 return HS;
540 return DS;
542 return GS;
544 return PS;
546 return CS;
547 }
548 Q_UNREACHABLE_RETURN(VS);
549}
550
551static inline D3D12_SHADER_VISIBILITY qd3d12_stageToVisibility(QD3D12Stage s)
552{
553 switch (s) {
554 case VS:
555 return D3D12_SHADER_VISIBILITY_VERTEX;
556 case HS:
557 return D3D12_SHADER_VISIBILITY_HULL;
558 case DS:
559 return D3D12_SHADER_VISIBILITY_DOMAIN;
560 case GS:
561 return D3D12_SHADER_VISIBILITY_GEOMETRY;
562 case PS:
563 return D3D12_SHADER_VISIBILITY_PIXEL;
564 case CS:
565 return D3D12_SHADER_VISIBILITY_ALL;
566 }
567 Q_UNREACHABLE_RETURN(D3D12_SHADER_VISIBILITY_ALL);
568}
569
570static inline QRhiShaderResourceBinding::StageFlag qd3d12_stageToSrb(QD3D12Stage s)
571{
572 switch (s) {
573 case VS:
575 case HS:
577 case DS:
579 case GS:
581 case PS:
583 case CS:
585 }
586 Q_UNREACHABLE_RETURN(QRhiShaderResourceBinding::VertexStage);
587}
588
589struct QD3D12ShaderStageData
590{
591 bool valid = false; // to allow simple arrays where unused stages are indicated by !valid
592 QD3D12Stage stage = VS;
593 QShader::NativeResourceBindingMap nativeResourceBindingMap;
594};
595
596struct QD3D12ShaderResourceBindings;
597
598struct QD3D12ShaderResourceVisitor
599{
600 enum StorageOp { Load = 0, Store, LoadStore };
601
602 QD3D12ShaderResourceVisitor(const QD3D12ShaderResourceBindings *srb,
603 const QD3D12ShaderStageData *stageData,
604 int stageCount)
605 : srb(srb),
606 stageData(stageData),
607 stageCount(stageCount)
608 {
609 }
610
611 std::function<void(QD3D12Stage, const QRhiShaderResourceBinding::Data::UniformBufferData &, int, int)> uniformBuffer = nullptr;
612 std::function<void(QD3D12Stage, const QRhiShaderResourceBinding::TextureAndSampler &, int)> texture = nullptr;
613 std::function<void(QD3D12Stage, const QRhiShaderResourceBinding::TextureAndSampler &, int)> sampler = nullptr;
614 std::function<void(QD3D12Stage, const QRhiShaderResourceBinding::Data::StorageImageData &, StorageOp, int)> storageImage = nullptr;
615 std::function<void(QD3D12Stage, const QRhiShaderResourceBinding::Data::StorageBufferData &, StorageOp, int)> storageBuffer = nullptr;
616
617 void visit();
618
619 const QD3D12ShaderResourceBindings *srb;
620 const QD3D12ShaderStageData *stageData;
621 int stageCount;
622};
623
624struct QD3D12Readback
625{
626 // common
627 int frameSlot = -1;
628 QRhiReadbackResult *result = nullptr;
629 QD3D12StagingArea staging;
630 quint32 byteSize = 0;
631 // textures
632 quint32 bytesPerLine = 0;
633 QSize pixelSize;
635 quint32 stagingRowPitch = 0;
636};
637
638struct QD3D12MipmapGenerator
639{
640 bool create(QRhiD3D12 *rhiD);
641 void destroy();
642 void generate(QD3D12CommandBuffer *cbD, const QD3D12ObjectHandle &textureHandle);
643
644 QRhiD3D12 *rhiD;
645 QD3D12ObjectHandle rootSigHandle;
646 QD3D12ObjectHandle pipelineHandle;
647};
648
649struct QD3D12MemoryAllocator
650{
651 bool create(ID3D12Device *device, IDXGIAdapter1 *adapter);
652 void destroy();
653
654 HRESULT createResource(D3D12_HEAP_TYPE heapType,
655 const D3D12_RESOURCE_DESC *resourceDesc,
656 D3D12_RESOURCE_STATES initialState,
657 const D3D12_CLEAR_VALUE *optimizedClearValue,
658 D3D12MA::Allocation **maybeAllocation,
659 REFIID riidResource,
660 void **ppvResource);
661
662 void getBudget(D3D12MA::Budget *localBudget, D3D12MA::Budget *nonLocalBudget);
663
664 bool isUsingD3D12MA() const { return allocator != nullptr; }
665
666 ID3D12Device *device = nullptr;
667 D3D12MA::Allocator *allocator = nullptr;
668};
669
670struct QD3D12Buffer : public QRhiBuffer
671{
672 QD3D12Buffer(QRhiImplementation *rhi, Type type, UsageFlags usage, quint32 size);
673 ~QD3D12Buffer();
674
675 void destroy() override;
676 bool create() override;
677 QRhiBuffer::NativeBuffer nativeBuffer() override;
678 char *beginFullDynamicBufferUpdateForCurrentFrame() override;
679 void endFullDynamicBufferUpdateForCurrentFrame() override;
680
681 void executeHostWritesForFrameSlot(int frameSlot);
682
683 QD3D12ObjectHandle handles[QD3D12_FRAMES_IN_FLIGHT] = {};
684 struct HostWrite {
687 };
688 QVarLengthArray<HostWrite, 16> pendingHostWrites[QD3D12_FRAMES_IN_FLIGHT];
689 friend class QRhiD3D12;
690 friend struct QD3D12CommandBuffer;
691};
692
693struct QD3D12RenderBuffer : public QRhiRenderBuffer
694{
695 QD3D12RenderBuffer(QRhiImplementation *rhi,
696 Type type,
697 const QSize &pixelSize,
698 int sampleCount,
699 Flags flags,
700 QRhiTexture::Format backingFormatHint);
701 ~QD3D12RenderBuffer();
702 void destroy() override;
703 bool create() override;
704 QRhiTexture::Format backingFormat() const override;
705
706 static const DXGI_FORMAT DS_FORMAT = DXGI_FORMAT_D24_UNORM_S8_UINT;
707
708 QD3D12ObjectHandle handle;
709 QD3D12Descriptor rtv;
710 QD3D12Descriptor dsv;
711 DXGI_FORMAT dxgiFormat;
712 DXGI_SAMPLE_DESC sampleDesc;
713 uint generation = 0;
714 friend class QRhiD3D12;
715};
716
717struct QD3D12Texture : public QRhiTexture
718{
719 QD3D12Texture(QRhiImplementation *rhi, Format format, const QSize &pixelSize, int depth,
720 int arraySize, int sampleCount, Flags flags);
721 ~QD3D12Texture();
722 void destroy() override;
723 bool create() override;
724 bool createFrom(NativeTexture src) override;
725 NativeTexture nativeTexture() override;
726 void setNativeLayout(int layout) override;
727
728 bool prepareCreate(QSize *adjustedSize = nullptr);
729 bool finishCreate();
730
731 QD3D12ObjectHandle handle;
732 QD3D12Descriptor srv;
733 DXGI_FORMAT dxgiFormat;
734 DXGI_FORMAT srvFormat;
735 DXGI_FORMAT rtFormat; // RTV/DSV/UAV
736 uint mipLevelCount;
737 DXGI_SAMPLE_DESC sampleDesc;
738 uint generation = 0;
739 friend class QRhiD3D12;
740 friend struct QD3D12CommandBuffer;
741};
742
743struct QD3D12Sampler : public QRhiSampler
744{
745 QD3D12Sampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode,
746 AddressMode u, AddressMode v, AddressMode w);
747 ~QD3D12Sampler();
748 void destroy() override;
749 bool create() override;
750
751 QD3D12Descriptor lookupOrCreateShaderVisibleDescriptor();
752
753 D3D12_SAMPLER_DESC desc = {};
754 QD3D12Descriptor shaderVisibleDescriptor;
755};
756
757struct QD3D12RenderPassDescriptor : public QRhiRenderPassDescriptor
758{
759 QD3D12RenderPassDescriptor(QRhiImplementation *rhi);
760 ~QD3D12RenderPassDescriptor();
761 void destroy() override;
762 bool isCompatible(const QRhiRenderPassDescriptor *other) const override;
763 QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() const override;
764 QVector<quint32> serializedFormat() const override;
765
766 void updateSerializedFormat();
767
768 static const int MAX_COLOR_ATTACHMENTS = 8;
769 int colorAttachmentCount = 0;
770 bool hasDepthStencil = false;
771 int colorFormat[MAX_COLOR_ATTACHMENTS];
772 int dsFormat;
773 QVector<quint32> serializedFormatData;
774};
775
776struct QD3D12RenderTargetData
777{
778 QD3D12RenderTargetData(QRhiImplementation *) { }
779
780 QD3D12RenderPassDescriptor *rp = nullptr;
781 QSize pixelSize;
782 float dpr = 1;
783 int sampleCount = 1;
784 int colorAttCount = 0;
785 int dsAttCount = 0;
787 static const int MAX_COLOR_ATTACHMENTS = QD3D12RenderPassDescriptor::MAX_COLOR_ATTACHMENTS;
788 D3D12_CPU_DESCRIPTOR_HANDLE rtv[MAX_COLOR_ATTACHMENTS];
789 D3D12_CPU_DESCRIPTOR_HANDLE dsv;
790};
791
792struct QD3D12SwapChainRenderTarget : public QRhiSwapChainRenderTarget
793{
794 QD3D12SwapChainRenderTarget(QRhiImplementation *rhi, QRhiSwapChain *swapchain);
795 ~QD3D12SwapChainRenderTarget();
796 void destroy() override;
797
798 QSize pixelSize() const override;
799 float devicePixelRatio() const override;
800 int sampleCount() const override;
801
802 QD3D12RenderTargetData d;
803};
804
805struct QD3D12TextureRenderTarget : public QRhiTextureRenderTarget
806{
807 QD3D12TextureRenderTarget(QRhiImplementation *rhi,
809 Flags flags);
810 ~QD3D12TextureRenderTarget();
811 void destroy() override;
812
813 QSize pixelSize() const override;
814 float devicePixelRatio() const override;
815 int sampleCount() const override;
816
817 QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
818 bool create() override;
819
820 QD3D12RenderTargetData d;
821 bool ownsRtv[QD3D12RenderTargetData::MAX_COLOR_ATTACHMENTS];
822 QD3D12Descriptor rtv[QD3D12RenderTargetData::MAX_COLOR_ATTACHMENTS];
823 bool ownsDsv = false;
824 QD3D12Descriptor dsv;
825 friend class QRhiD3D12;
826};
827
828struct QD3D12ShaderResourceBindings : public QRhiShaderResourceBindings
829{
830 QD3D12ShaderResourceBindings(QRhiImplementation *rhi);
831 ~QD3D12ShaderResourceBindings();
832 void destroy() override;
833 bool create() override;
834 void updateResources(UpdateFlags flags) override;
835
836 QD3D12ObjectHandle createRootSignature(const QD3D12ShaderStageData *stageData, int stageCount);
837
838 struct VisitorData {
839 QVarLengthArray<D3D12_ROOT_PARAMETER1, 2> cbParams[6];
840
841 D3D12_ROOT_PARAMETER1 srvTables[6] = {};
842 QVarLengthArray<D3D12_DESCRIPTOR_RANGE1, 4> srvRanges[6];
843 quint32 currentSrvRangeOffset[6] = {};
844
845 QVarLengthArray<D3D12_ROOT_PARAMETER1, 4> samplerTables[6];
846 std::array<D3D12_DESCRIPTOR_RANGE1, 16> samplerRanges[6] = {};
847 int samplerRangeHeads[6] = {};
848
849 D3D12_ROOT_PARAMETER1 uavTables[6] = {};
850 QVarLengthArray<D3D12_DESCRIPTOR_RANGE1, 4> uavRanges[6];
851 quint32 currentUavRangeOffset[6] = {};
852 } visitorData;
853
854
855 void visitUniformBuffer(QD3D12Stage s,
857 int shaderRegister,
858 int binding);
859 void visitTexture(QD3D12Stage s,
861 int shaderRegister);
862 void visitSampler(QD3D12Stage s,
864 int shaderRegister);
865 void visitStorageBuffer(QD3D12Stage s,
867 QD3D12ShaderResourceVisitor::StorageOp op,
868 int shaderRegister);
869 void visitStorageImage(QD3D12Stage s,
871 QD3D12ShaderResourceVisitor::StorageOp op,
872 int shaderRegister);
873
874 bool hasDynamicOffset = false;
875 uint generation = 0;
876
877 friend class QRhiD3D12;
878 friend struct QD3D12ShaderResourceVisitor;
879};
880
881struct QD3D12GraphicsPipeline : public QRhiGraphicsPipeline
882{
883 QD3D12GraphicsPipeline(QRhiImplementation *rhi);
884 ~QD3D12GraphicsPipeline();
885 void destroy() override;
886 bool create() override;
887
888 QD3D12ObjectHandle handle;
889 QD3D12ObjectHandle rootSigHandle;
890 std::array<QD3D12ShaderStageData, 5> stageData;
891 D3D12_PRIMITIVE_TOPOLOGY topology;
892 UINT viewInstanceMask = 0;
893 uint generation = 0;
894 friend class QRhiD3D12;
895};
896
897struct QD3D12ComputePipeline : public QRhiComputePipeline
898{
899 QD3D12ComputePipeline(QRhiImplementation *rhi);
900 ~QD3D12ComputePipeline();
901 void destroy() override;
902 bool create() override;
903
904 QD3D12ObjectHandle handle;
905 QD3D12ObjectHandle rootSigHandle;
906 QD3D12ShaderStageData stageData;
907 uint generation = 0;
908 friend class QRhiD3D12;
909};
910
911struct QD3D12CommandBuffer : public QRhiCommandBuffer
912{
913 QD3D12CommandBuffer(QRhiImplementation *rhi);
914 ~QD3D12CommandBuffer();
915 void destroy() override;
916
917 const QRhiNativeHandles *nativeHandles();
918
919 ID3D12GraphicsCommandList1 *cmdList = nullptr; // not owned
920 QRhiD3D12CommandBufferNativeHandles nativeHandlesStruct;
921
922 enum PassType {
923 NoPass,
924 RenderPass,
925 ComputePass
926 };
927
928 void resetState()
929 {
930 recordingPass = NoPass;
931 currentTarget = nullptr;
932
933 resetPerPassState();
934 }
935
936 void resetPerPassState()
937 {
938 currentGraphicsPipeline = nullptr;
939 currentComputePipeline = nullptr;
940 currentPipelineGeneration = 0;
941 currentGraphicsSrb = nullptr;
942 currentComputeSrb = nullptr;
943 currentSrbGeneration = 0;
944 currentIndexBuffer = {};
945 currentIndexOffset = 0;
946 currentIndexFormat = DXGI_FORMAT_R16_UINT;
947 currentVertexBuffers = {};
948 currentVertexOffsets = {};
949 }
950
951 // per-frame
952 PassType recordingPass;
953 QRhiRenderTarget *currentTarget;
954
955 // per-pass
956 QD3D12GraphicsPipeline *currentGraphicsPipeline;
957 QD3D12ComputePipeline *currentComputePipeline;
958 uint currentPipelineGeneration;
959 QRhiShaderResourceBindings *currentGraphicsSrb;
960 QRhiShaderResourceBindings *currentComputeSrb;
961 uint currentSrbGeneration;
962 QD3D12ObjectHandle currentIndexBuffer;
963 quint32 currentIndexOffset;
964 DXGI_FORMAT currentIndexFormat;
965 std::array<QD3D12ObjectHandle, D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT> currentVertexBuffers;
966 std::array<quint32, D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT> currentVertexOffsets;
967
968 // global
969 double lastGpuTime = 0;
970
971 // per-setShaderResources
972 struct VisitorData {
973 QVarLengthArray<QPair<QD3D12ObjectHandle, quint32>, 4> cbufs[6];
974 QVarLengthArray<QD3D12Descriptor, 8> srvs[6];
975 QVarLengthArray<QD3D12Descriptor, 8> samplers[6];
976 QVarLengthArray<QPair<QD3D12ObjectHandle, D3D12_UNORDERED_ACCESS_VIEW_DESC>, 4> uavs[6];
977 } visitorData;
978
979 void visitUniformBuffer(QD3D12Stage s,
981 int shaderRegister,
982 int binding,
983 int dynamicOffsetCount,
984 const QRhiCommandBuffer::DynamicOffset *dynamicOffsets);
985 void visitTexture(QD3D12Stage s,
987 int shaderRegister);
988 void visitSampler(QD3D12Stage s,
990 int shaderRegister);
991 void visitStorageBuffer(QD3D12Stage s,
993 QD3D12ShaderResourceVisitor::StorageOp op,
994 int shaderRegister);
995 void visitStorageImage(QD3D12Stage s,
997 QD3D12ShaderResourceVisitor::StorageOp op,
998 int shaderRegister);
999};
1000
1001struct QD3D12SwapChain : public QRhiSwapChain
1002{
1003 QD3D12SwapChain(QRhiImplementation *rhi);
1004 ~QD3D12SwapChain();
1005 void destroy() override;
1006
1007 QRhiCommandBuffer *currentFrameCommandBuffer() override;
1008 QRhiRenderTarget *currentFrameRenderTarget() override;
1009 QRhiRenderTarget *currentFrameRenderTarget(StereoTargetBuffer targetBuffer) override;
1010
1011 QSize surfacePixelSize() override;
1012 bool isFormatSupported(Format f) override;
1013 QRhiSwapChainHdrInfo hdrInfo() override;
1014
1015 QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
1016 bool createOrResize() override;
1017
1018 void releaseBuffers();
1019 void waitCommandCompletionForFrameSlot(int frameSlot);
1020 void addCommandCompletionSignalForCurrentFrameSlot();
1021 void chooseFormats();
1022
1023 QWindow *window = nullptr;
1024 IDXGISwapChain1 *sourceSwapChain1 = nullptr;
1025 IDXGISwapChain3 *swapChain = nullptr;
1026 QSize pixelSize;
1027 UINT swapInterval = 1;
1028 UINT swapChainFlags = 0;
1029 BOOL stereo = false;
1030 DXGI_FORMAT colorFormat;
1031 DXGI_FORMAT srgbAdjustedColorFormat;
1032 DXGI_COLOR_SPACE_TYPE hdrColorSpace;
1033 IDCompositionTarget *dcompTarget = nullptr;
1034 IDCompositionVisual *dcompVisual = nullptr;
1035 static const UINT BUFFER_COUNT = 3;
1036 QD3D12ObjectHandle colorBuffers[BUFFER_COUNT];
1037 QD3D12Descriptor rtvs[BUFFER_COUNT];
1038 QD3D12Descriptor rtvsRight[BUFFER_COUNT];
1039 DXGI_SAMPLE_DESC sampleDesc;
1040 QD3D12ObjectHandle msaaBuffers[BUFFER_COUNT];
1041 QD3D12Descriptor msaaRtvs[BUFFER_COUNT];
1042 QD3D12RenderBuffer *ds = nullptr;
1043 UINT currentBackBufferIndex = 0;
1044 QD3D12SwapChainRenderTarget rtWrapper;
1045 QD3D12SwapChainRenderTarget rtWrapperRight;
1046 QD3D12CommandBuffer cbWrapper;
1047
1048 struct FrameResources {
1049 ID3D12Fence *fence = nullptr;
1050 HANDLE fenceEvent = nullptr;
1051 UINT64 fenceCounter = 0;
1052 ID3D12GraphicsCommandList1 *cmdList = nullptr;
1053 } frameRes[QD3D12_FRAMES_IN_FLIGHT];
1054
1055 int currentFrameSlot = 0; // index in frameRes
1056};
1057
1058template<typename T, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE Type>
1059struct alignas(void*) QD3D12PipelineStateSubObject
1060{
1061 D3D12_PIPELINE_STATE_SUBOBJECT_TYPE type = Type;
1062 T object = {};
1063};
1064
1065class QRhiD3D12 : public QRhiImplementation
1066{
1067public:
1068 // 16MB * QD3D12_FRAMES_IN_FLIGHT; buffer and texture upload staging data that
1069 // gets no space from this will get their own temporary staging areas.
1070 static const quint32 SMALL_STAGING_AREA_BYTES_PER_FRAME = 16 * 1024 * 1024;
1071
1072 static const quint32 SHADER_VISIBLE_CBV_SRV_UAV_HEAP_PER_FRAME_START_SIZE = 16384;
1073
1074 QRhiD3D12(QRhiD3D12InitParams *params, QRhiD3D12NativeHandles *importDevice = nullptr);
1075
1076 bool create(QRhi::Flags flags) override;
1077 void destroy() override;
1078
1080 QRhiComputePipeline *createComputePipeline() override;
1081 QRhiShaderResourceBindings *createShaderResourceBindings() override;
1082 QRhiBuffer *createBuffer(QRhiBuffer::Type type,
1083 QRhiBuffer::UsageFlags usage,
1084 quint32 size) override;
1085 QRhiRenderBuffer *createRenderBuffer(QRhiRenderBuffer::Type type,
1086 const QSize &pixelSize,
1087 int sampleCount,
1088 QRhiRenderBuffer::Flags flags,
1089 QRhiTexture::Format backingFormatHint) override;
1090 QRhiTexture *createTexture(QRhiTexture::Format format,
1091 const QSize &pixelSize,
1092 int depth,
1093 int arraySize,
1094 int sampleCount,
1095 QRhiTexture::Flags flags) override;
1096 QRhiSampler *createSampler(QRhiSampler::Filter magFilter,
1097 QRhiSampler::Filter minFilter,
1098 QRhiSampler::Filter mipmapMode,
1101 QRhiSampler::AddressMode w) override;
1102
1103 QRhiTextureRenderTarget *createTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc,
1104 QRhiTextureRenderTarget::Flags flags) override;
1105
1106 QRhiSwapChain *createSwapChain() override;
1107 QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags) override;
1108 QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags) override;
1109 QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags) override;
1110 QRhi::FrameOpResult endOffscreenFrame(QRhi::EndFrameFlags flags) override;
1111 QRhi::FrameOpResult finish() override;
1112
1113 void resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
1114
1115 void beginPass(QRhiCommandBuffer *cb,
1116 QRhiRenderTarget *rt,
1117 const QColor &colorClearValue,
1118 const QRhiDepthStencilClearValue &depthStencilClearValue,
1119 QRhiResourceUpdateBatch *resourceUpdates,
1120 QRhiCommandBuffer::BeginPassFlags flags) override;
1121 void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
1122
1123 void setGraphicsPipeline(QRhiCommandBuffer *cb,
1124 QRhiGraphicsPipeline *ps) override;
1125
1126 void setShaderResources(QRhiCommandBuffer *cb,
1128 int dynamicOffsetCount,
1129 const QRhiCommandBuffer::DynamicOffset *dynamicOffsets) override;
1130
1131 void setVertexInput(QRhiCommandBuffer *cb,
1132 int startBinding, int bindingCount, const QRhiCommandBuffer::VertexInput *bindings,
1133 QRhiBuffer *indexBuf, quint32 indexOffset,
1134 QRhiCommandBuffer::IndexFormat indexFormat) override;
1135
1136 void setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) override;
1137 void setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) override;
1138 void setBlendConstants(QRhiCommandBuffer *cb, const QColor &c) override;
1139 void setStencilRef(QRhiCommandBuffer *cb, quint32 refValue) override;
1140
1141 void draw(QRhiCommandBuffer *cb, quint32 vertexCount,
1142 quint32 instanceCount, quint32 firstVertex, quint32 firstInstance) override;
1143
1144 void drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
1145 quint32 instanceCount, quint32 firstIndex,
1146 qint32 vertexOffset, quint32 firstInstance) override;
1147
1148 void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) override;
1149 void debugMarkEnd(QRhiCommandBuffer *cb) override;
1150 void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override;
1151
1152 void beginComputePass(QRhiCommandBuffer *cb,
1153 QRhiResourceUpdateBatch *resourceUpdates,
1154 QRhiCommandBuffer::BeginPassFlags flags) override;
1155 void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
1156 void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) override;
1157 void dispatch(QRhiCommandBuffer *cb, int x, int y, int z) override;
1158
1159 const QRhiNativeHandles *nativeHandles(QRhiCommandBuffer *cb) override;
1160 void beginExternal(QRhiCommandBuffer *cb) override;
1161 void endExternal(QRhiCommandBuffer *cb) override;
1162 double lastCompletedGpuTime(QRhiCommandBuffer *cb) override;
1163
1164 QList<int> supportedSampleCounts() const override;
1165 int ubufAlignment() const override;
1166 bool isYUpInFramebuffer() const override;
1167 bool isYUpInNDC() const override;
1168 bool isClipDepthZeroToOne() const override;
1169 QMatrix4x4 clipSpaceCorrMatrix() const override;
1170 bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const override;
1171 bool isFeatureSupported(QRhi::Feature feature) const override;
1172 int resourceLimit(QRhi::ResourceLimit limit) const override;
1173 const QRhiNativeHandles *nativeHandles() override;
1174 QRhiDriverInfo driverInfo() const override;
1175 QRhiStats statistics() override;
1176 bool makeThreadLocalNativeContextCurrent() override;
1177 void releaseCachedResources() override;
1178 bool isDeviceLost() const override;
1179
1180 QByteArray pipelineCacheData() override;
1181 void setPipelineCacheData(const QByteArray &data) override;
1182
1183 void waitGpu();
1184 DXGI_SAMPLE_DESC effectiveSampleDesc(int sampleCount, DXGI_FORMAT format) const;
1185 bool ensureDirectCompositionDevice();
1186 bool startCommandListForCurrentFrameSlot(ID3D12GraphicsCommandList1 **cmdList);
1187 void enqueueResourceUpdates(QD3D12CommandBuffer *cbD, QRhiResourceUpdateBatch *resourceUpdates);
1188 void finishActiveReadbacks(bool forced = false);
1189 bool ensureShaderVisibleDescriptorHeapCapacity(QD3D12ShaderVisibleDescriptorHeap *h,
1190 D3D12_DESCRIPTOR_HEAP_TYPE type,
1191 int frameSlot,
1192 quint32 neededDescriptorCount,
1193 bool *gotNew);
1194 void bindShaderVisibleHeaps(QD3D12CommandBuffer *cbD);
1195
1196 bool debugLayer = false;
1197 ID3D12Device2 *dev = nullptr;
1198 D3D_FEATURE_LEVEL minimumFeatureLevel = D3D_FEATURE_LEVEL(0);
1199 LUID adapterLuid = {};
1200 bool importedDevice = false;
1201 bool importedCommandQueue = false;
1202 QRhi::Flags rhiFlags;
1203 IDXGIFactory2 *dxgiFactory = nullptr;
1204 bool supportsAllowTearing = false;
1205 IDXGIAdapter1 *activeAdapter = nullptr;
1206 QRhiDriverInfo driverInfoStruct;
1207 QRhiD3D12NativeHandles nativeHandlesStruct;
1208 bool deviceLost = false;
1209 ID3D12CommandQueue *cmdQueue = nullptr;
1210 ID3D12Fence *fullFence = nullptr;
1211 HANDLE fullFenceEvent = nullptr;
1212 UINT64 fullFenceCounter = 0;
1213 ID3D12CommandAllocator *cmdAllocators[QD3D12_FRAMES_IN_FLIGHT] = {};
1214 QD3D12MemoryAllocator vma;
1215 QD3D12CpuDescriptorPool rtvPool;
1216 QD3D12CpuDescriptorPool dsvPool;
1217 QD3D12CpuDescriptorPool cbvSrvUavPool;
1218 QD3D12ObjectPool<QD3D12Resource> resourcePool;
1219 QD3D12ObjectPool<QD3D12Pipeline> pipelinePool;
1220 QD3D12ObjectPool<QD3D12RootSignature> rootSignaturePool;
1221 QD3D12ReleaseQueue releaseQueue;
1222 QD3D12ResourceBarrierGenerator barrierGen;
1223 QD3D12SamplerManager samplerMgr;
1224 QD3D12MipmapGenerator mipmapGen;
1225 QD3D12StagingArea smallStagingAreas[QD3D12_FRAMES_IN_FLIGHT];
1226 QD3D12ShaderVisibleDescriptorHeap shaderVisibleCbvSrvUavHeap;
1227 UINT64 timestampTicksPerSecond = 0;
1228 QD3D12QueryHeap timestampQueryHeap;
1229 QD3D12StagingArea timestampReadbackArea;
1230 IDCompositionDevice *dcompDevice = nullptr;
1231 QD3D12SwapChain *currentSwapChain = nullptr;
1232 QSet<QD3D12SwapChain *> swapchains;
1233 QD3D12ShaderBytecodeCache shaderBytecodeCache;
1234 QVarLengthArray<QD3D12Readback, 4> activeReadbacks;
1235 bool offscreenActive = false;
1236 QD3D12CommandBuffer *offscreenCb[QD3D12_FRAMES_IN_FLIGHT] = {};
1237
1238 struct {
1239 bool multiView = false;
1240 bool textureViewFormat = false;
1241 } caps;
1242};
1243
1245
1246#endif // __ID3D12Device2_INTERFACE_DEFINED__
1247
1248#endif
IOBluetoothDevice * device
\inmodule QtCore
Definition qbitarray.h:13
\inmodule QtCore
Definition qbytearray.h:57
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:25
\inmodule QtGui
Definition qrhi.h:846
Type
Specifies storage type of buffer resource.
Definition qrhi.h:848
\inmodule QtGui
Definition qrhi.h:1651
QPair< int, quint32 > DynamicOffset
Synonym for QPair<int, quint32>.
Definition qrhi.h:1676
QPair< QRhiBuffer *, quint32 > VertexInput
Synonym for QPair<QRhiBuffer *, quint32>.
Definition qrhi.h:1680
IndexFormat
Specifies the index data type.
Definition qrhi.h:1653
\inmodule QtGui
Definition qrhi.h:1622
\inmodule QtGui
Definition qrhi.h:44
\inmodule QtGui
Definition qrhi.h:1270
\inmodule QtGui
Definition qrhi.h:1094
Type
Specifies the type of the renderbuffer.
Definition qrhi.h:1096
\inmodule QtGui
Definition qrhi.h:1142
\inmodule QtGui
Definition qrhi.h:1158
\inmodule QtGui
Definition qrhi.h:1731
\inmodule QtGui
Definition qrhi.h:1030
Filter
Specifies the minification, magnification, or mipmap filtering.
Definition qrhi.h:1032
AddressMode
Specifies the addressing mode.
Definition qrhi.h:1038
\inmodule QtGui
Definition qrhi.h:138
StageFlag
Flag values to indicate which stages the shader resource is visible in.
Definition qrhi.h:454
\inmodule QtGui
Definition qrhi.h:1214
\inmodule QtGui
Definition qrhi.h:379
Type
Specifies the type of the shader stage.
Definition qrhi.h:381
@ TessellationControl
Definition qrhi.h:383
@ TessellationEvaluation
Definition qrhi.h:384
\inmodule QtGui
Definition qrhi.h:1173
\inmodule QtGui
Definition qrhi.h:1549
\inmodule QtGui
Definition qrhi.h:1184
\inmodule QtGui
Definition qrhi.h:895
Format
Specifies the texture format.
Definition qrhi.h:914
@ UnknownFormat
Definition qrhi.h:915
\inmodule QtGui
Definition qrhi.h:85
ResourceLimit
Describes the resource limit to query.
Definition qrhi.h:1886
Feature
Flag values to indicate what features are supported by the backend currently in use.
Definition qrhi.h:1831
FrameOpResult
Describes the result of operations that can have a soft failure.
Definition qrhi.h:1824
\inmodule QtCore
Definition qsize.h:25
\inmodule QtGui
Definition qwindow.h:63
Format
Definition ddsheader.h:14
QHash< int, QWidget * > hash
[35multi]
QMap< QString, QString > map
[6]
else opt state
[0]
auto visit(Fn &&fn, QIODevice *socket, Args &&...args)
@ Views
Definition qtsqlglobal.h:38
Combined button and popup list for selecting options.
Q_ALWAYS_INLINE void fence()
bool isNull(const T &t)
void * HANDLE
static QRhiGraphicsPipeline * createGraphicsPipeline(QRhi *rhi, QRhiShaderResourceBindings *srb, QRhiRenderPassDescriptor *rpDesc, PipelineBlend blend)
constexpr bool operator!=(const timespec &t1, const timespec &t2)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
static QDBusError::ErrorType get(const char *name)
static int instanceCount
size_t qHash(const QFileSystemWatcherPathKey &key, size_t seed=0)
Flags
NSUInteger capacity
static QT_BEGIN_NAMESPACE const int BUFFER_COUNT
#define qWarning
Definition qlogging.h:166
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLuint64 GLenum void * handle
GLint GLint GLint GLint GLint x
[0]
GLint GLenum GLsizei GLsizei GLsizei depth
GLuint64 key
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLuint sampler
GLenum GLenum GLsizei count
GLuint object
[3]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat f
GLenum src
GLenum GLuint buffer
GLenum type
GLbitfield flags
GLenum GLuint texture
GLenum GLuint GLintptr offset
GLuint name
GLint GLsizei GLsizei GLenum format
GLint y
GLfloat GLfloat GLfloat GLfloat h
void ** params
GLdouble s
[6]
Definition qopenglext.h:235
const GLubyte * c
GLint limit
GLuint * samplers
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
GLenum GLenum colorFormat
GLsizeiptr const void GLenum usage
Definition qopenglext.h:543
static void add(QPainterPath &path, const QWingedEdge &list, int edge, QPathEdge::Traversal traversal)
QT_BEGIN_NAMESPACE typedef void(* Callback)(QQmlNotifierEndpoint *, void **)
static QT_BEGIN_NAMESPACE qreal dpr(const QWindow *w)
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
Definition qrandom.cpp:196
bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
Definition qrandom.cpp:1220
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static bool isCompatible(const QImage &img1, const QImage &img2)
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
std::unique_ptr< ThunkPool::ThunkAllocation > allocation
Definition qstdweb.cpp:276
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
unsigned int quint32
Definition qtypes.h:50
int qint32
Definition qtypes.h:49
unsigned int uint
Definition qtypes.h:34
unsigned char quint8
Definition qtypes.h:46
long HRESULT
settings remove("monkey")
QVBoxLayout * layout
sem release()
QQueue< int > queue
[0]
QSharedPointer< T > other(t)
[5]
view viewport() -> scroll(dx, dy, deviceRect)
myFilter draw(painter, QPoint(0, 0), originalPixmap)
aWidget window() -> setWindowTitle("New Window Title")
[2]
QAction * at
manager head(request, this, [this](QRestReply &reply) { if(reply.isSuccess()) })
[6]
view create()
\inmodule QtGui
Definition qrhi.h:862
\inmodule QtGui
Definition qrhi.h:1759
\variable QRhiReadbackResult::completed
Definition qrhi.h:800
\inmodule QtGui
Definition qrhi.h:1723
\inmodule QtGui
Definition qrhi.h:1782
\inmodule QtGui
Definition qrhi.h:1511
Definition moc.h:23