27#include <d3d12sdklayers.h>
31#include "D3D12MemAlloc.h"
39#ifdef __ID3D12Device2_INTERFACE_DEFINED__
40#define QRHI_D3D12_AVAILABLE
44#ifdef __ID3D12GraphicsCommandList5_INTERFACE_DEFINED__
45#define QRHI_D3D12_CL5_AVAILABLE
46using D3D12GraphicsCommandList = ID3D12GraphicsCommandList5;
48using D3D12GraphicsCommandList = ID3D12GraphicsCommandList1;
51#ifdef __ID3D12InfoQueue1_INTERFACE_DEFINED__
52#define QRHI_D3D12_INFOQUEUE1_AVAILABLE
55#ifdef __ID3D12PipelineLibrary1_INTERFACE_DEFINED__
56#define QRHI_D3D12_PIPELINE_LIBRARY_AVAILABLE
61static const int QD3D12_FRAMES_IN_FLIGHT = 2;
65struct QD3D12Descriptor
67 D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle = {};
68 D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle = {};
70 bool isValid()
const {
return cpuHandle.ptr != 0; }
73struct QD3D12ReleaseQueue;
75struct QD3D12DescriptorHeap
77 bool isValid()
const {
return heap && capacity; }
78 bool create(ID3D12Device *device,
79 quint32 descriptorCount,
80 D3D12_DESCRIPTOR_HEAP_TYPE heapType,
81 D3D12_DESCRIPTOR_HEAP_FLAGS heapFlags);
82 void createWithExisting(
const QD3D12DescriptorHeap &other,
83 quint32 offsetInDescriptors,
84 quint32 descriptorCount);
86 void destroyWithDeferredRelease(QD3D12ReleaseQueue *releaseQueue);
88 QD3D12Descriptor get(quint32 count);
89 QD3D12Descriptor at(quint32 index)
const;
90 quint32 remainingCapacity()
const {
return capacity - head; }
92 QD3D12Descriptor incremented(
const QD3D12Descriptor &descriptor, quint32 offsetInDescriptors)
const
94 D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle = descriptor.cpuHandle;
95 cpuHandle.ptr += offsetInDescriptors * descriptorByteSize;
96 D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle = descriptor.gpuHandle;
98 gpuHandle.ptr += offsetInDescriptors * descriptorByteSize;
99 return { cpuHandle, gpuHandle };
102 ID3D12DescriptorHeap *heap =
nullptr;
103 quint32 capacity = 0;
104 QD3D12Descriptor heapStart;
106 quint32 descriptorByteSize = 0;
107 D3D12_DESCRIPTOR_HEAP_TYPE heapType;
108 D3D12_DESCRIPTOR_HEAP_FLAGS heapFlags;
111struct QD3D12CpuDescriptorPool
113 bool isValid()
const {
return !heaps.isEmpty(); }
114 bool create(ID3D12Device *device, D3D12_DESCRIPTOR_HEAP_TYPE heapType,
const char *debugName =
"");
117 QD3D12Descriptor allocate(quint32 count);
118 void release(
const QD3D12Descriptor &descriptor, quint32 count);
120 static const int DESCRIPTORS_PER_HEAP = 256;
123 QD3D12DescriptorHeap heap;
125 static HeapWithMap init(
const QD3D12DescriptorHeap &heap, quint32 descriptorCount) {
128 result.map.resize(descriptorCount);
133 ID3D12Device *device;
134 quint32 descriptorByteSize;
135 QVector<HeapWithMap> heaps;
136 const char *debugName;
139struct QD3D12QueryHeap
141 bool isValid()
const {
return heap && capacity; }
142 bool create(ID3D12Device *device,
144 D3D12_QUERY_HEAP_TYPE heapType);
147 ID3D12QueryHeap *heap =
nullptr;
148 quint32 capacity = 0;
151struct QD3D12StagingArea
153 static const quint32 ALIGNMENT = D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT;
157 D3D12_GPU_VIRTUAL_ADDRESS gpuAddr = 0;
158 ID3D12Resource *buffer =
nullptr;
159 quint32 bufferOffset = 0;
160 bool isValid()
const {
return p !=
nullptr; }
163 bool isValid()
const {
return allocation && mem.isValid(); }
164 bool create(QRhiD3D12 *rhi, quint32 capacity, D3D12_HEAP_TYPE heapType);
166 void destroyWithDeferredRelease(QD3D12ReleaseQueue *releaseQueue);
168 Allocation get(quint32 byteSize);
170 quint32 remainingCapacity()
const
172 return capacity - head;
175 static quint32 allocSizeForArray(quint32 size,
int count = 1)
177 return count * ((size + ALIGNMENT - 1) & ~(ALIGNMENT - 1));
181 ID3D12Resource *resource =
nullptr;
182 D3D12MA::Allocation *allocation =
nullptr;
187struct QD3D12ObjectHandle
190 quint32 generation = 0;
193 bool isNull()
const {
return index == 0 && generation == 0; }
196inline bool operator==(
const QD3D12ObjectHandle &a,
const QD3D12ObjectHandle &b)
noexcept
198 return a.index == b.index && a.generation == b.generation;
201inline bool operator!=(
const QD3D12ObjectHandle &a,
const QD3D12ObjectHandle &b)
noexcept
207struct QD3D12ObjectPool
209 void create(
const char *debugName =
"")
211 this->debugName = debugName;
212 Q_ASSERT(data.isEmpty());
218 for (Data &d : data) {
219 if (d.object.has_value()) {
221 d.object->releaseResources();
227 static bool leakCheck =
true;
230 static bool leakCheck = qEnvironmentVariableIntValue(
"QT_RHI_LEAK_CHECK");
234 qWarning(
"QD3D12ObjectPool::destroy(): Pool %p '%s' had %d unreleased objects",
235 this, debugName, leakCount);
240 bool isValid(
const QD3D12ObjectHandle &handle)
const
242 return handle.index > 0
243 && handle.index < quint32(data.count())
244 && handle.generation > 0
245 && handle.generation == data[handle.index].generation
246 && data[handle.index].object.has_value();
249 T lookup(
const QD3D12ObjectHandle &handle)
const
251 return isValid(handle) ? *data[handle.index].object : T();
254 const T *lookupRef(
const QD3D12ObjectHandle &handle)
const
256 return isValid(handle) ? &*data[handle.index].object :
nullptr;
259 T *lookupRef(
const QD3D12ObjectHandle &handle)
261 return isValid(handle) ? &*data[handle.index].object :
nullptr;
264 QD3D12ObjectHandle add(
const T &object)
266 Q_ASSERT(!data.isEmpty());
267 const quint32 count = quint32(data.count());
269 for (; index < count; ++index) {
270 if (!data[index].object.has_value())
274 data[index].object = object;
275 quint32 &generation = data[index].generation;
277 return { index, generation };
279 data.append({ object, 1 });
284 void remove(
const QD3D12ObjectHandle &handle)
286 if (T *object = lookupRef(handle)) {
287 object->releaseResources();
288 data[handle.index].object.reset();
292 const char *debugName;
294 std::optional<T> object;
295 quint32 generation = 0;
302 ID3D12Resource *resource;
303 D3D12_RESOURCE_STATES state;
304 D3D12_RESOURCE_DESC desc;
305 D3D12MA::Allocation *allocation;
307 enum { UavUsageRead = 0x01, UavUsageWrite = 0x02 };
313 static QD3D12ObjectHandle addToPool(QD3D12ObjectPool<QD3D12Resource> *pool,
314 ID3D12Resource *resource,
315 D3D12_RESOURCE_STATES state,
316 D3D12MA::Allocation *allocation =
nullptr,
317 void *cpuMapPtr =
nullptr)
320 return pool->add({ resource, state, resource->GetDesc(), allocation, cpuMapPtr, 0,
true });
324 static QD3D12ObjectHandle addNonOwningToPool(QD3D12ObjectPool<QD3D12Resource> *pool,
325 ID3D12Resource *resource,
326 D3D12_RESOURCE_STATES state)
329 return pool->add({ resource, state, resource->GetDesc(),
nullptr,
nullptr, 0,
false });
332 void releaseResources()
338 allocation->Release();
350 ID3D12PipelineState *pso;
352 static QD3D12ObjectHandle addToPool(QD3D12ObjectPool<QD3D12Pipeline> *pool,
354 ID3D12PipelineState *pso)
356 return pool->add({ type, pso });
359 void releaseResources()
365struct QD3D12RootSignature
367 ID3D12RootSignature *rootSig;
369 static QD3D12ObjectHandle addToPool(QD3D12ObjectPool<QD3D12RootSignature> *pool,
370 ID3D12RootSignature *rootSig)
372 return pool->add({ rootSig });
375 void releaseResources()
381struct QD3D12ReleaseQueue
383 void create(QD3D12ObjectPool<QD3D12Resource> *resourcePool,
384 QD3D12ObjectPool<QD3D12Pipeline> *pipelinePool,
385 QD3D12ObjectPool<QD3D12RootSignature> *rootSignaturePool)
387 this->resourcePool = resourcePool;
388 this->pipelinePool = pipelinePool;
389 this->rootSignaturePool = rootSignaturePool;
392 void deferredReleaseResource(
const QD3D12ObjectHandle &handle);
393 void deferredReleaseResourceWithViews(
const QD3D12ObjectHandle &handle,
394 QD3D12CpuDescriptorPool *pool,
395 const QD3D12Descriptor &viewsStart,
397 void deferredReleasePipeline(
const QD3D12ObjectHandle &handle);
398 void deferredReleaseRootSignature(
const QD3D12ObjectHandle &handle);
399 void deferredReleaseCallback(std::function<
void(
void*)> callback,
void *userData);
400 void deferredReleaseResourceAndAllocation(ID3D12Resource *resource,
401 D3D12MA::Allocation *allocation);
402 void deferredReleaseDescriptorHeap(ID3D12DescriptorHeap *heap);
403 void deferredReleaseViews(QD3D12CpuDescriptorPool *pool,
404 const QD3D12Descriptor &viewsStart,
407 void activatePendingDeferredReleaseRequests(
int frameSlot);
408 void executeDeferredReleases(
int frameSlot,
bool forced =
false);
411 struct DeferredReleaseEntry {
417 ResourceAndAllocation,
421 Type type = Resource;
422 std::optional<
int> frameSlotToBeReleasedIn;
423 QD3D12ObjectHandle handle;
424 QD3D12CpuDescriptorPool *poolForViews =
nullptr;
425 QD3D12Descriptor viewsStart;
427 std::function<
void(
void*)> callback =
nullptr;
428 void *callbackUserData =
nullptr;
429 std::pair<ID3D12Resource *, D3D12MA::Allocation *> resourceAndAllocation = {};
430 ID3D12DescriptorHeap *descriptorHeap =
nullptr;
432 QVector<DeferredReleaseEntry> queue;
433 QD3D12ObjectPool<QD3D12Resource> *resourcePool =
nullptr;
434 QD3D12ObjectPool<QD3D12Pipeline> *pipelinePool =
nullptr;
435 QD3D12ObjectPool<QD3D12RootSignature> *rootSignaturePool =
nullptr;
438struct QD3D12CommandBuffer;
440struct QD3D12ResourceBarrierGenerator
442 static const int PREALLOC = 16;
444 void create(QD3D12ObjectPool<QD3D12Resource> *resourcePool)
446 this->resourcePool = resourcePool;
449 void addTransitionBarrier(
const QD3D12ObjectHandle &resourceHandle, D3D12_RESOURCE_STATES stateAfter);
450 void enqueueBufferedTransitionBarriers(QD3D12CommandBuffer *cbD);
451 void enqueueSubresourceTransitionBarrier(QD3D12CommandBuffer *cbD,
452 const QD3D12ObjectHandle &resourceHandle,
454 D3D12_RESOURCE_STATES stateBefore,
455 D3D12_RESOURCE_STATES stateAfter);
456 void enqueueUavBarrier(QD3D12CommandBuffer *cbD,
const QD3D12ObjectHandle &resourceHandle);
458 struct TransitionResourceBarrier {
459 QD3D12ObjectHandle resourceHandle;
460 D3D12_RESOURCE_STATES stateBefore;
461 D3D12_RESOURCE_STATES stateAfter;
463 QVarLengthArray<TransitionResourceBarrier, PREALLOC> transitionResourceBarriers;
464 QD3D12ObjectPool<QD3D12Resource> *resourcePool =
nullptr;
467struct QD3D12ShaderBytecode
469 QD3D12ShaderBytecode() =
default;
470 QD3D12ShaderBytecode(
const QByteArray &bytecode,
const QShader::NativeResourceBindingMap &rbm,
471 int pushConstantRegister = -1, quint32 pushConstantSize = 0)
472 : bytecode(bytecode), nativeResourceBindingMap(rbm),
473 pushConstantRegister(pushConstantRegister), pushConstantSize(pushConstantSize)
476 QShader::NativeResourceBindingMap nativeResourceBindingMap;
477 int pushConstantRegister = -1;
478 quint32 pushConstantSize = 0;
481inline quint32 qrhiBinaryCacheEntryByteSize(
const QD3D12ShaderBytecode &s)
483 return quint32(s.bytecode.size());
486using QD3D12ShaderBytecodeCache = QRhiBinaryCache<QRhiShaderStage, QD3D12ShaderBytecode>;
488struct QD3D12ShaderVisibleDescriptorHeap
490 bool create(ID3D12Device *device, D3D12_DESCRIPTOR_HEAP_TYPE type, quint32 perFrameDescriptorCount);
492 void destroyWithDeferredRelease(QD3D12ReleaseQueue *releaseQueue);
494 QD3D12DescriptorHeap heap;
495 QD3D12DescriptorHeap perFrameHeapSlice[QD3D12_FRAMES_IN_FLIGHT];
499struct Q_D3D12_SAMPLER_DESC
501 D3D12_SAMPLER_DESC desc;
503 friend bool operator==(
const Q_D3D12_SAMPLER_DESC &lhs,
const Q_D3D12_SAMPLER_DESC &rhs)
noexcept
505 return lhs.desc.Filter == rhs.desc.Filter
506 && lhs.desc.AddressU == rhs.desc.AddressU
507 && lhs.desc.AddressV == rhs.desc.AddressV
508 && lhs.desc.AddressW == rhs.desc.AddressW
509 && lhs.desc.MipLODBias == rhs.desc.MipLODBias
510 && lhs.desc.MaxAnisotropy == rhs.desc.MaxAnisotropy
511 && lhs.desc.ComparisonFunc == rhs.desc.ComparisonFunc
513 && lhs.desc.MinLOD == rhs.desc.MinLOD
514 && lhs.desc.MaxLOD == rhs.desc.MaxLOD;
517 friend bool operator!=(
const Q_D3D12_SAMPLER_DESC &lhs,
const Q_D3D12_SAMPLER_DESC &rhs)
noexcept
519 return !(lhs == rhs);
522 friend size_t qHash(
const Q_D3D12_SAMPLER_DESC &key, size_t seed = 0)
noexcept
524 QtPrivate::QHashCombine hash(seed);
525 seed = hash(seed, key.desc.Filter);
526 seed = hash(seed, key.desc.AddressU);
527 seed = hash(seed, key.desc.AddressV);
528 seed = hash(seed, key.desc.AddressW);
529 seed = hash(seed, key.desc.MipLODBias);
530 seed = hash(seed, key.desc.MaxAnisotropy);
531 seed = hash(seed, key.desc.ComparisonFunc);
533 seed = hash(seed, key.desc.MinLOD);
534 seed = hash(seed, key.desc.MaxLOD);
541struct Q_D3D12_SAMPLER_DESC_LIST
543 QVarLengthArray<Q_D3D12_SAMPLER_DESC, 8> descs;
545 friend bool operator==(
const Q_D3D12_SAMPLER_DESC_LIST &lhs,
const Q_D3D12_SAMPLER_DESC_LIST &rhs)
noexcept
547 return lhs.descs == rhs.descs;
550 friend bool operator!=(
const Q_D3D12_SAMPLER_DESC_LIST &lhs,
const Q_D3D12_SAMPLER_DESC_LIST &rhs)
noexcept
552 return !(lhs == rhs);
555 friend size_t qHash(
const Q_D3D12_SAMPLER_DESC_LIST &key, size_t seed = 0)
noexcept
557 return qHashRange(key.descs.cbegin(), key.descs.cend(), seed);
561struct QD3D12SamplerManager
563 const quint32 MAX_SAMPLERS = 512;
565 bool create(ID3D12Device *device);
568 QD3D12Descriptor getShaderVisibleDescriptor(
const D3D12_SAMPLER_DESC &desc);
572 QD3D12Descriptor getShaderVisibleDescriptors(
const QVarLengthArray<Q_D3D12_SAMPLER_DESC, 8> &descs);
574 ID3D12Device *device =
nullptr;
575 QD3D12ShaderVisibleDescriptorHeap shaderVisibleSamplerHeap;
586 QHash<Q_D3D12_SAMPLER_DESC, QD3D12Descriptor> gpuMap;
587 QHash<Q_D3D12_SAMPLER_DESC_LIST, QD3D12Descriptor> gpuArrayMap;
590enum QD3D12Stage { VS = 0, HS, DS, GS, PS, CS };
592static inline QD3D12Stage qd3d12_stage(QRhiShaderStage::Type type)
595 case QRhiShaderStage::Vertex:
597 case QRhiShaderStage::TessellationControl:
599 case QRhiShaderStage::TessellationEvaluation:
601 case QRhiShaderStage::Geometry:
603 case QRhiShaderStage::Fragment:
605 case QRhiShaderStage::Compute:
608 Q_UNREACHABLE_RETURN(VS);
611static inline D3D12_SHADER_VISIBILITY qd3d12_stageToVisibility(QD3D12Stage s)
615 return D3D12_SHADER_VISIBILITY_VERTEX;
617 return D3D12_SHADER_VISIBILITY_HULL;
619 return D3D12_SHADER_VISIBILITY_DOMAIN;
621 return D3D12_SHADER_VISIBILITY_GEOMETRY;
623 return D3D12_SHADER_VISIBILITY_PIXEL;
625 return D3D12_SHADER_VISIBILITY_ALL;
627 Q_UNREACHABLE_RETURN(D3D12_SHADER_VISIBILITY_ALL);
630static inline QRhiShaderResourceBinding::StageFlag qd3d12_stageToSrb(QD3D12Stage s)
634 return QRhiShaderResourceBinding::VertexStage;
636 return QRhiShaderResourceBinding::TessellationControlStage;
638 return QRhiShaderResourceBinding::TessellationEvaluationStage;
640 return QRhiShaderResourceBinding::GeometryStage;
642 return QRhiShaderResourceBinding::FragmentStage;
644 return QRhiShaderResourceBinding::ComputeStage;
646 Q_UNREACHABLE_RETURN(QRhiShaderResourceBinding::VertexStage);
649struct QD3D12ShaderStageData
652 QD3D12Stage stage = VS;
653 QShader::NativeResourceBindingMap nativeResourceBindingMap;
654 int pushConstantRegister = -1;
655 quint32 pushConstantSize = 0;
658struct QD3D12ShaderResourceBindings;
660struct QD3D12ShaderResourceVisitor
662 enum StorageOp { Load = 0, Store, LoadStore };
664 QD3D12ShaderResourceVisitor(
const QD3D12ShaderResourceBindings *srb,
665 const QD3D12ShaderStageData *stageData,
668 stageData(stageData),
669 stageCount(stageCount)
673 std::function<
void(QD3D12Stage,
const QRhiShaderResourceBinding::Data::UniformBufferData &,
int,
int)> uniformBuffer =
nullptr;
680 std::function<
void(QD3D12Stage,
const QRhiShaderResourceBinding::TextureAndSampler *,
int,
int)> textures =
nullptr;
681 std::function<
void(QD3D12Stage,
const QRhiShaderResourceBinding::TextureAndSampler *,
int,
int)> samplers =
nullptr;
682 std::function<
void(QD3D12Stage,
const QRhiShaderResourceBinding::Data::StorageImageData &, StorageOp,
int)> storageImage =
nullptr;
683 std::function<
void(QD3D12Stage,
const QRhiShaderResourceBinding::Data::StorageBufferData &, StorageOp,
int)> storageBuffer =
nullptr;
687 const QD3D12ShaderResourceBindings *srb;
688 const QD3D12ShaderStageData *stageData;
696 QRhiReadbackResult *result =
nullptr;
697 QD3D12StagingArea staging;
698 quint32 byteSize = 0;
700 quint32 bytesPerLine = 0;
702 QRhiTexture::Format format = QRhiTexture::UnknownFormat;
703 quint32 stagingRowPitch = 0;
706struct QD3D12MipmapGenerator
708 void create(QRhiD3D12 *rhiD);
710 void generate(QD3D12CommandBuffer *cbD,
const QD3D12ObjectHandle &textureHandle);
712 bool ensureCreated();
713 bool buildPipeline();
715 QRhiD3D12 *rhiD =
nullptr;
716 QD3D12ObjectHandle rootSigHandle;
717 QD3D12ObjectHandle pipelineHandle;
718 bool createFailed =
false;
721struct QD3D12MipmapGenerator3D
723 void create(QRhiD3D12 *rhiD);
725 void generate(QD3D12CommandBuffer *cbD,
const QD3D12ObjectHandle &textureHandle);
727 bool ensureCreated();
728 bool buildPipeline();
730 QRhiD3D12 *rhiD =
nullptr;
731 QD3D12ObjectHandle rootSigHandle;
732 QD3D12ObjectHandle pipelineHandle;
733 bool createFailed =
false;
736struct QD3D12MemoryAllocator
738 bool create(ID3D12Device *device, IDXGIAdapter1 *adapter);
741 HRESULT createResource(D3D12_HEAP_TYPE heapType,
742 const D3D12_RESOURCE_DESC *resourceDesc,
743 D3D12_RESOURCE_STATES initialState,
744 const D3D12_CLEAR_VALUE *optimizedClearValue,
745 D3D12MA::Allocation **maybeAllocation,
749 void getBudget(D3D12MA::Budget *localBudget, D3D12MA::Budget *nonLocalBudget);
751 bool isUsingD3D12MA()
const {
return allocator !=
nullptr; }
753 ID3D12Device *device =
nullptr;
754 D3D12MA::Allocator *allocator =
nullptr;
757struct QD3D12Buffer :
public QRhiBuffer
759 QD3D12Buffer(QRhiImplementation *rhi, Type type, UsageFlags usage, quint32 size);
762 void destroy() override;
763 bool create() override;
764 QRhiBuffer::NativeBuffer nativeBuffer() override;
765 char *beginFullDynamicBufferUpdateForCurrentFrame() override;
766 void endFullDynamicBufferUpdateForCurrentFrame() override;
768 void executeHostWritesForFrameSlot(
int frameSlot);
770 QD3D12ObjectHandle handles[QD3D12_FRAMES_IN_FLIGHT] = {};
775 QVarLengthArray<HostWrite, 16> pendingHostWrites[QD3D12_FRAMES_IN_FLIGHT];
777 friend class QRhiD3D12;
778 friend struct QD3D12ShaderResourceBindings;
781struct QD3D12RenderBuffer :
public QRhiRenderBuffer
783 QD3D12RenderBuffer(QRhiImplementation *rhi,
785 const QSize &pixelSize,
788 QRhiTexture::Format backingFormatHint);
789 ~QD3D12RenderBuffer();
790 void destroy() override;
791 bool create() override;
792 QRhiTexture::Format backingFormat()
const override;
794 static const DXGI_FORMAT DS_FORMAT = DXGI_FORMAT_D24_UNORM_S8_UINT;
796 QD3D12ObjectHandle handle;
797 QD3D12Descriptor rtv;
798 QD3D12Descriptor dsv;
799 DXGI_FORMAT dxgiFormat;
800 DXGI_SAMPLE_DESC sampleDesc;
802 friend class QRhiD3D12;
805struct QD3D12Texture :
public QRhiTexture
807 QD3D12Texture(QRhiImplementation *rhi, Format format,
const QSize &pixelSize,
int depth,
808 int arraySize,
int sampleCount, Flags flags);
810 void destroy() override;
811 bool create() override;
812 bool createFrom(NativeTexture src) override;
813 NativeTexture nativeTexture() override;
814 void setNativeLayout(
int layout) override;
816 bool prepareCreate(QSize *adjustedSize =
nullptr);
819 QD3D12ObjectHandle handle;
820 QD3D12Descriptor srv;
821 DXGI_FORMAT dxgiFormat;
822 DXGI_FORMAT srvFormat;
823 DXGI_FORMAT rtFormat;
825 DXGI_SAMPLE_DESC sampleDesc;
826 QBitArray subresourceInitialized;
828 friend class QRhiD3D12;
829 friend struct QD3D12ShaderResourceBindings;
832struct QD3D12Sampler :
public QRhiSampler
834 QD3D12Sampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode,
835 AddressMode u, AddressMode v, AddressMode w);
837 void destroy() override;
838 bool create() override;
840 QD3D12Descriptor lookupOrCreateShaderVisibleDescriptor();
842 D3D12_SAMPLER_DESC desc = {};
843 QD3D12Descriptor shaderVisibleDescriptor;
845 friend class QRhiD3D12;
848struct QD3D12ShadingRateMap :
public QRhiShadingRateMap
850 QD3D12ShadingRateMap(QRhiImplementation *rhi);
851 ~QD3D12ShadingRateMap();
852 void destroy() override;
853 bool createFrom(QRhiTexture *src) override;
855 QD3D12ObjectHandle handle;
856 friend class QRhiD3D12;
859struct QD3D12RenderPassDescriptor :
public QRhiRenderPassDescriptor
861 QD3D12RenderPassDescriptor(QRhiImplementation *rhi);
862 ~QD3D12RenderPassDescriptor();
863 void destroy() override;
864 bool isCompatible(
const QRhiRenderPassDescriptor *other)
const override;
865 QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor()
const override;
866 QVector<quint32> serializedFormat()
const override;
868 void updateSerializedFormat();
870 static const int MAX_COLOR_ATTACHMENTS = 8;
871 int colorAttachmentCount = 0;
872 bool hasDepthStencil =
false;
873 int colorFormat[MAX_COLOR_ATTACHMENTS];
875 bool hasShadingRateMap =
false;
876 QVector<quint32> serializedFormatData;
879struct QD3D12RenderTargetData
881 QD3D12RenderTargetData(QRhiImplementation *) { }
883 QD3D12RenderPassDescriptor *rp =
nullptr;
887 int colorAttCount = 0;
889 QRhiRenderTargetAttachmentTracker::ResIdList currentResIdList;
890 static const int MAX_COLOR_ATTACHMENTS = QD3D12RenderPassDescriptor::MAX_COLOR_ATTACHMENTS;
891 D3D12_CPU_DESCRIPTOR_HANDLE rtv[MAX_COLOR_ATTACHMENTS];
892 D3D12_CPU_DESCRIPTOR_HANDLE dsv;
895struct QD3D12SwapChainRenderTarget :
public QRhiSwapChainRenderTarget
897 QD3D12SwapChainRenderTarget(QRhiImplementation *rhi, QRhiSwapChain *swapchain);
898 ~QD3D12SwapChainRenderTarget();
899 void destroy() override;
901 QSize pixelSize()
const override;
902 float devicePixelRatio()
const override;
903 int sampleCount()
const override;
905 QD3D12RenderTargetData d;
908struct QD3D12TextureRenderTarget :
public QRhiTextureRenderTarget
910 QD3D12TextureRenderTarget(QRhiImplementation *rhi,
911 const QRhiTextureRenderTargetDescription &desc,
913 ~QD3D12TextureRenderTarget();
914 void destroy() override;
916 QSize pixelSize()
const override;
917 float devicePixelRatio()
const override;
918 int sampleCount()
const override;
920 QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
921 bool create() override;
923 QD3D12RenderTargetData d;
924 bool ownsRtv[QD3D12RenderTargetData::MAX_COLOR_ATTACHMENTS];
925 QD3D12Descriptor rtv[QD3D12RenderTargetData::MAX_COLOR_ATTACHMENTS];
926 bool ownsDsv =
false;
927 QD3D12Descriptor dsv;
928 friend class QRhiD3D12;
931struct QD3D12GraphicsPipeline;
932struct QD3D12ComputePipeline;
934struct QD3D12ShaderResourceBindings :
public QRhiShaderResourceBindings
936 QD3D12ShaderResourceBindings(QRhiImplementation *rhi);
937 ~QD3D12ShaderResourceBindings();
938 void destroy() override;
939 bool create() override;
940 void updateResources(UpdateFlags flags) override;
942 QD3D12ObjectHandle createRootSignature(
const QD3D12ShaderStageData *stageData,
int stageCount);
945 int pushConstantRootParamIndex = -1;
948 QVarLengthArray<D3D12_ROOT_PARAMETER1, 2> cbParams[6];
950 D3D12_ROOT_PARAMETER1 srvTables[6] = {};
951 QVarLengthArray<D3D12_DESCRIPTOR_RANGE1, 4> srvRanges[6];
952 quint32 currentSrvRangeOffset[6] = {};
954 QVarLengthArray<D3D12_ROOT_PARAMETER1, 4> samplerTables[6];
955 std::array<D3D12_DESCRIPTOR_RANGE1, 16> samplerRanges[6] = {};
956 int samplerRangeHeads[6] = {};
958 D3D12_ROOT_PARAMETER1 uavTables[6] = {};
959 QVarLengthArray<D3D12_DESCRIPTOR_RANGE1, 4> uavRanges[6];
960 quint32 currentUavRangeOffset[6] = {};
964 void visitUniformBuffer(QD3D12Stage s,
965 const QRhiShaderResourceBinding::Data::UniformBufferData &d,
968 void visitTextures(QD3D12Stage s,
969 const QRhiShaderResourceBinding::TextureAndSampler *d,
971 int baseShaderRegister);
972 void visitSamplers(QD3D12Stage s,
973 const QRhiShaderResourceBinding::TextureAndSampler *d,
975 int baseShaderRegister);
976 void visitStorageBuffer(QD3D12Stage s,
977 const QRhiShaderResourceBinding::Data::StorageBufferData &d,
978 QD3D12ShaderResourceVisitor::StorageOp op,
980 void visitStorageImage(QD3D12Stage s,
981 const QRhiShaderResourceBinding::Data::StorageImageData &d,
982 QD3D12ShaderResourceVisitor::StorageOp op,
989 struct BindingCache {
997 QVarLengthArray<CBuf, 2> cbufs[6];
998 QVarLengthArray<D3D12_CPU_DESCRIPTOR_HANDLE, 8> srvs[6];
999 QVarLengthArray<D3D12_GPU_DESCRIPTOR_HANDLE, 8> samplers[6];
1001 QD3D12ObjectHandle handle;
1002 D3D12_UNORDERED_ACCESS_VIEW_DESC desc;
1004 QVarLengthArray<Uav, 4> uavs[6];
1005 quint32 srvUavCount = 0;
1008 for (
int s = 0; s < 6; ++s) {
1011 samplers[s].clear();
1018 bool bindingCacheValid =
false;
1019 uint bindingCacheGeneration = 0;
1021 void rebuildBindingCache(
const QD3D12ShaderStageData *stageData,
int stageCount);
1025 void cacheUniformBuffer(QD3D12Stage s,
1026 const QRhiShaderResourceBinding::Data::UniformBufferData &d,
1029 void cacheTextures(QD3D12Stage s,
1030 const QRhiShaderResourceBinding::TextureAndSampler *d,
1032 int baseShaderRegister);
1033 void cacheSamplers(QD3D12Stage s,
1034 const QRhiShaderResourceBinding::TextureAndSampler *d,
1036 int baseShaderRegister);
1037 void cacheStorageBuffer(QD3D12Stage s,
1038 const QRhiShaderResourceBinding::Data::StorageBufferData &d,
1039 QD3D12ShaderResourceVisitor::StorageOp op,
1040 int shaderRegister);
1041 void cacheStorageImage(QD3D12Stage s,
1042 const QRhiShaderResourceBinding::Data::StorageImageData &d,
1043 QD3D12ShaderResourceVisitor::StorageOp op,
1044 int shaderRegister);
1046 struct BoundUniformBufferData {
1050 struct BoundSampledTextureData {
1053 uint texGeneration = 0;
1054 quint64 samplerId = 0;
1055 uint samplerGeneration = 0;
1057 QVarLengthArray<Entry, 1> d;
1059 struct BoundStorageImageData {
1063 struct BoundStorageBufferData {
1067 struct BoundResourceData {
1068 BoundUniformBufferData ubuf = {};
1069 BoundSampledTextureData stex;
1070 BoundStorageImageData simage = {};
1071 BoundStorageBufferData sbuf = {};
1073 QVarLengthArray<BoundResourceData, 8> boundResourceData;
1075 bool hasDynamicOffset =
false;
1076 uint generation = 0;
1077 QD3D12GraphicsPipeline *lastUsedGraphicsPipeline =
nullptr;
1078 QD3D12ComputePipeline *lastUsedComputePipeline =
nullptr;
1079 uint lastUsedPipelineGeneration = 0;
1081 friend class QRhiD3D12;
1082 friend struct QD3D12ShaderResourceVisitor;
1085struct QD3D12GraphicsPipeline :
public QRhiGraphicsPipeline
1087 QD3D12GraphicsPipeline(QRhiImplementation *rhi);
1088 ~QD3D12GraphicsPipeline();
1089 void destroy() override;
1090 bool create() override;
1092 QD3D12ObjectHandle handle;
1093 QD3D12ObjectHandle rootSigHandle;
1094 int pushConstantRootParamIndex = -1;
1095 std::array<QD3D12ShaderStageData, 5> stageData;
1096 D3D12_PRIMITIVE_TOPOLOGY topology;
1097 UINT viewInstanceMask = 0;
1098 uint generation = 0;
1099 friend class QRhiD3D12;
1102struct QD3D12ComputePipeline :
public QRhiComputePipeline
1104 QD3D12ComputePipeline(QRhiImplementation *rhi);
1105 ~QD3D12ComputePipeline();
1106 void destroy() override;
1107 bool create() override;
1109 QD3D12ObjectHandle handle;
1110 QD3D12ObjectHandle rootSigHandle;
1111 int pushConstantRootParamIndex = -1;
1112 QD3D12ShaderStageData stageData;
1113 uint generation = 0;
1114 friend class QRhiD3D12;
1117struct QD3D12CommandBuffer :
public QRhiCommandBuffer
1119 QD3D12CommandBuffer(QRhiImplementation *rhi);
1120 ~QD3D12CommandBuffer();
1121 void destroy() override;
1123 const QRhiNativeHandles *nativeHandles();
1125 D3D12GraphicsCommandList *cmdList =
nullptr;
1126 QRhiD3D12CommandBufferNativeHandles nativeHandlesStruct;
1136 recordingPass = NoPass;
1137 currentTarget =
nullptr;
1139 resetPerPassState();
1142 void resetPerPassState()
1144 currentGraphicsPipeline =
nullptr;
1145 currentComputePipeline =
nullptr;
1146 currentPipelineGeneration = 0;
1147 currentGraphicsSrb =
nullptr;
1148 currentComputeSrb =
nullptr;
1149 currentSrbGeneration = 0;
1150 currentIndexBuffer = {};
1151 currentIndexOffset = 0;
1152 currentIndexFormat = DXGI_FORMAT_R16_UINT;
1153 currentVertexBuffers = {};
1154 currentVertexOffsets = {};
1155 hasShadingRateSet =
false;
1156 hasShadingRateMapSet =
false;
1157 hasCustomScissorSet =
false;
1158 currentViewport = {};
1162 PassType recordingPass;
1163 QRhiRenderTarget *currentTarget;
1166 QD3D12GraphicsPipeline *currentGraphicsPipeline;
1167 QD3D12ComputePipeline *currentComputePipeline;
1168 uint currentPipelineGeneration;
1169 QRhiShaderResourceBindings *currentGraphicsSrb;
1170 QRhiShaderResourceBindings *currentComputeSrb;
1171 uint currentSrbGeneration;
1172 QD3D12ObjectHandle currentIndexBuffer;
1173 quint32 currentIndexOffset;
1174 DXGI_FORMAT currentIndexFormat;
1175 std::array<QD3D12ObjectHandle, D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT> currentVertexBuffers;
1176 std::array<quint32, D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT> currentVertexOffsets;
1177 bool hasShadingRateSet;
1178 bool hasShadingRateMapSet;
1179 bool hasCustomScissorSet;
1180 QRhiViewport currentViewport;
1183 double lastGpuTime = 0;
1186struct QD3D12SwapChain :
public QRhiSwapChain
1188 QD3D12SwapChain(QRhiImplementation *rhi);
1190 void destroy() override;
1192 QRhiCommandBuffer *currentFrameCommandBuffer() override;
1193 QRhiRenderTarget *currentFrameRenderTarget() override;
1194 QRhiRenderTarget *currentFrameRenderTarget(StereoTargetBuffer targetBuffer) override;
1196 QSize surfacePixelSize() override;
1197 bool isFormatSupported(Format f) override;
1198 QRhiSwapChainHdrInfo hdrInfo() override;
1200 QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
1201 bool createOrResize() override;
1203 void releaseBuffers();
1204 void waitCommandCompletionForFrameSlot(
int frameSlot);
1205 void addCommandCompletionSignalForCurrentFrameSlot();
1206 void chooseFormats();
1208 QWindow *window =
nullptr;
1209 IDXGISwapChain1 *sourceSwapChain1 =
nullptr;
1210 IDXGISwapChain3 *swapChain =
nullptr;
1212 UINT swapInterval = 1;
1213 UINT swapChainFlags = 0;
1214 BOOL stereo =
false;
1215 DXGI_FORMAT colorFormat;
1216 DXGI_FORMAT srgbAdjustedColorFormat;
1217 DXGI_COLOR_SPACE_TYPE hdrColorSpace;
1218 IDCompositionTarget *dcompTarget =
nullptr;
1219 IDCompositionVisual *dcompVisual =
nullptr;
1220 static const UINT BUFFER_COUNT = 3;
1221 QD3D12ObjectHandle colorBuffers[BUFFER_COUNT];
1222 QD3D12Descriptor rtvs[BUFFER_COUNT];
1223 QD3D12Descriptor rtvsRight[BUFFER_COUNT];
1224 DXGI_SAMPLE_DESC sampleDesc;
1225 QD3D12ObjectHandle msaaBuffers[QD3D12_FRAMES_IN_FLIGHT];
1226 QD3D12Descriptor msaaRtvs[QD3D12_FRAMES_IN_FLIGHT];
1227 QD3D12RenderBuffer *ds =
nullptr;
1228 UINT currentBackBufferIndex = 0;
1229 QD3D12SwapChainRenderTarget rtWrapper;
1230 QD3D12SwapChainRenderTarget rtWrapperRight;
1231 QD3D12CommandBuffer cbWrapper;
1232 HANDLE frameLatencyWaitableObject =
nullptr;
1234 struct FrameResources {
1235 ID3D12Fence *fence =
nullptr;
1236 HANDLE fenceEvent =
nullptr;
1237 UINT64 fenceCounter = 0;
1238 D3D12GraphicsCommandList *cmdList =
nullptr;
1239 } frameRes[QD3D12_FRAMES_IN_FLIGHT];
1241 int currentFrameSlot = 0;
1242 int lastFrameLatencyWaitSlot = -1;
1245template<
typename T, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE Type>
1246struct alignas(
void*) QD3D12PipelineStateSubObject
1248 D3D12_PIPELINE_STATE_SUBOBJECT_TYPE type = Type;
1252class QD3D12Adapter :
public QRhiAdapter
1255 QRhiDriverInfo info()
const override;
1258 QRhiDriverInfo adapterInfo;
1261class QRhiD3D12 :
public QRhiImplementation
1265 static constexpr quint32 SMALL_STAGING_AREA_BYTES_PER_FRAME_START = 512 * 1024;
1266 static constexpr quint32 SMALL_STAGING_AREA_BYTES_PER_FRAME_MAX = 16 * 1024 * 1024;
1269 static constexpr int SMALL_STAGING_AREA_LOW_DEMAND_FRAMES = 60;
1271 static constexpr quint32 SHADER_VISIBLE_CBV_SRV_UAV_HEAP_PER_FRAME_START_SIZE = 16384;
1273 QRhiD3D12(QRhiD3D12InitParams *params, QRhiD3D12NativeHandles *importDevice =
nullptr);
1275 bool create(QRhi::Flags flags) override;
1276 void destroy() override;
1277 QRhi::AdapterList enumerateAdaptersBeforeCreate(QRhiNativeHandles *nativeHandles)
const override;
1279 QRhiGraphicsPipeline *createGraphicsPipeline() override;
1280 QRhiComputePipeline *createComputePipeline() override;
1281 QRhiShaderResourceBindings *createShaderResourceBindings() override;
1282 QRhiBuffer *createBuffer(QRhiBuffer::Type type,
1283 QRhiBuffer::UsageFlags usage,
1284 quint32 size) override;
1285 QRhiRenderBuffer *createRenderBuffer(QRhiRenderBuffer::Type type,
1286 const QSize &pixelSize,
1288 QRhiRenderBuffer::Flags flags,
1289 QRhiTexture::Format backingFormatHint) override;
1290 QRhiTexture *createTexture(QRhiTexture::Format format,
1291 const QSize &pixelSize,
1295 QRhiTexture::Flags flags) override;
1296 QRhiSampler *createSampler(QRhiSampler::Filter magFilter,
1297 QRhiSampler::Filter minFilter,
1298 QRhiSampler::Filter mipmapMode,
1299 QRhiSampler:: AddressMode u,
1300 QRhiSampler::AddressMode v,
1301 QRhiSampler::AddressMode w) override;
1303 QRhiTextureRenderTarget *createTextureRenderTarget(
const QRhiTextureRenderTargetDescription &desc,
1304 QRhiTextureRenderTarget::Flags flags) override;
1306 QRhiShadingRateMap *createShadingRateMap() override;
1308 QRhiSwapChain *createSwapChain() override;
1309 QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags) override;
1310 QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags) override;
1311 QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags) override;
1312 QRhi::FrameOpResult endOffscreenFrame(QRhi::EndFrameFlags flags) override;
1313 QRhi::FrameOpResult finish() override;
1315 void resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
1317 void beginPass(QRhiCommandBuffer *cb,
1318 QRhiRenderTarget *rt,
1319 const QColor &colorClearValue,
1320 const QRhiDepthStencilClearValue &depthStencilClearValue,
1321 QRhiResourceUpdateBatch *resourceUpdates,
1322 QRhiCommandBuffer::BeginPassFlags flags) override;
1323 void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
1325 void setGraphicsPipeline(QRhiCommandBuffer *cb,
1326 QRhiGraphicsPipeline *ps) override;
1328 void setShaderResources(QRhiCommandBuffer *cb,
1329 QRhiShaderResourceBindings *srb,
1330 int dynamicOffsetCount,
1331 const QRhiCommandBuffer::DynamicOffset *dynamicOffsets) override;
1333 void setVertexInput(QRhiCommandBuffer *cb,
1334 int startBinding,
int bindingCount,
const QRhiCommandBuffer::VertexInput *bindings,
1335 QRhiBuffer *indexBuf, quint32 indexOffset,
1336 QRhiCommandBuffer::IndexFormat indexFormat) override;
1338 void setViewport(QRhiCommandBuffer *cb,
const QRhiViewport &viewport) override;
1339 void setScissor(QRhiCommandBuffer *cb,
const QRhiScissor &scissor) override;
1340 void setBlendConstants(QRhiCommandBuffer *cb,
const QColor &c) override;
1341 void setStencilRef(QRhiCommandBuffer *cb, quint32 refValue) override;
1342 void setPushConstants(QRhiCommandBuffer *cb, quint32 offset, quint32 size,
const void *data) override;
1343 void setShadingRate(QRhiCommandBuffer *cb,
const QSize &coarsePixelSize) override;
1345 void draw(QRhiCommandBuffer *cb, quint32 vertexCount,
1346 quint32 instanceCount, quint32 firstVertex, quint32 firstInstance) override;
1348 void drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
1349 quint32 instanceCount, quint32 firstIndex,
1350 qint32 vertexOffset, quint32 firstInstance) override;
1352 void drawIndirect(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer,
1353 quint32 indirectBufferOffset, quint32 drawCount, quint32 stride) override;
1355 void drawIndexedIndirect(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer,
1356 quint32 indirectBufferOffset, quint32 drawCount, quint32 stride) override;
1358 void debugMarkBegin(QRhiCommandBuffer *cb,
const QByteArray &name) override;
1359 void debugMarkEnd(QRhiCommandBuffer *cb) override;
1360 void debugMarkMsg(QRhiCommandBuffer *cb,
const QByteArray &msg) override;
1362 void beginComputePass(QRhiCommandBuffer *cb,
1363 QRhiResourceUpdateBatch *resourceUpdates,
1364 QRhiCommandBuffer::BeginPassFlags flags) override;
1365 void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
1366 void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) override;
1367 void dispatch(QRhiCommandBuffer *cb,
int x,
int y,
int z) override;
1368 void dispatchIndirect(QRhiCommandBuffer *cb, QRhiBuffer *indirectBuffer,
1369 quint32 indirectBufferOffset) override;
1371 void drawIndirectCount(QRhiCommandBuffer *cb,
1372 QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset,
1373 QRhiBuffer *countBuffer, quint32 countBufferOffset,
1374 quint32 maxDrawCount, quint32 stride) override;
1375 void drawIndexedIndirectCount(QRhiCommandBuffer *cb,
1376 QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset,
1377 QRhiBuffer *countBuffer, quint32 countBufferOffset,
1378 quint32 maxDrawCount, quint32 stride) override;
1379 ID3D12CommandSignature *indirectDrawCommandSignature(
bool indexed, quint32 stride);
1381 const QRhiNativeHandles *nativeHandles(QRhiCommandBuffer *cb) override;
1382 void beginExternal(QRhiCommandBuffer *cb) override;
1383 void endExternal(QRhiCommandBuffer *cb) override;
1384 double lastCompletedGpuTime(QRhiCommandBuffer *cb) override;
1386 QList<
int> supportedSampleCounts()
const override;
1387 QList<QSize> supportedShadingRates(
int sampleCount)
const override;
1388 int ubufAlignment()
const override;
1389 bool isYUpInFramebuffer()
const override;
1390 bool isYUpInNDC()
const override;
1391 bool isClipDepthZeroToOne()
const override;
1392 QMatrix4x4 clipSpaceCorrMatrix()
const override;
1393 bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags)
const override;
1394 bool isFeatureSupported(QRhi::Feature feature)
const override;
1395 int resourceLimit(QRhi::ResourceLimit limit)
const override;
1396 const QRhiNativeHandles *nativeHandles() override;
1397 QRhiDriverInfo driverInfo()
const override;
1398 QRhiStats statistics() override;
1399 bool makeThreadLocalNativeContextCurrent() override;
1400 void setQueueSubmitParams(QRhiNativeHandles *params) override;
1401 void releaseCachedResources() override;
1402 bool isDeviceLost()
const override;
1404 QByteArray pipelineCacheData() override;
1405 void setPipelineCacheData(
const QByteArray &data) override;
1413 void recordSmallStagingAreaDemand(quint32 byteSize)
1415 smallStagingAreaBytesNeeded[currentFrameSlot] += byteSize;
1417 void resetAndResizeSmallStagingArea(
int frameSlot);
1419 ID3D12PipelineState *loadOrCreatePipelineState(
const D3D12_PIPELINE_STATE_STREAM_DESC *streamDesc,
1420 const QByteArray &cacheKey,
1422 bool ensurePipelineLibrary();
1423 bool createPipelineLibrary(
const QByteArray &blob);
1424 void destroyPipelineLibrary();
1427 DXGI_SAMPLE_DESC effectiveSampleDesc(
int sampleCount, DXGI_FORMAT format)
const;
1428 bool ensureDirectCompositionDevice();
1429 bool startCommandListForCurrentFrameSlot(D3D12GraphicsCommandList **cmdList);
1430 void enqueueResourceUpdates(QD3D12CommandBuffer *cbD, QRhiResourceUpdateBatch *resourceUpdates);
1431 void finishActiveReadbacks(
bool forced =
false);
1432 bool ensureShaderVisibleDescriptorHeapCapacity(QD3D12ShaderVisibleDescriptorHeap *h,
1433 D3D12_DESCRIPTOR_HEAP_TYPE type,
1435 quint32 neededDescriptorCount,
1437 void bindShaderVisibleHeaps(QD3D12CommandBuffer *cbD);
1438 void setDefaultScissor(QD3D12CommandBuffer *cbD);
1440 bool debugLayer =
false;
1441#ifdef QRHI_D3D12_INFOQUEUE1_AVAILABLE
1442 ID3D12InfoQueue1 *infoQueue1 =
nullptr;
1443 DWORD infoQueueCallbackCookie = 0;
1445 UINT maxFrameLatency = 2;
1446 ID3D12Device2 *dev =
nullptr;
1447 D3D_FEATURE_LEVEL minimumFeatureLevel = D3D_FEATURE_LEVEL(0);
1448 LUID adapterLuid = {};
1449 bool importedDevice =
false;
1450 bool importedCommandQueue =
false;
1451 QRhi::Flags rhiFlags;
1452 IDXGIFactory2 *dxgiFactory =
nullptr;
1453 bool supportsAllowTearing =
false;
1454 IDXGIAdapter1 *activeAdapter =
nullptr;
1455 QRhiDriverInfo driverInfoStruct;
1456 QRhiD3D12NativeHandles nativeHandlesStruct;
1457 bool deviceLost =
false;
1458 ID3D12CommandQueue *cmdQueue =
nullptr;
1459 ID3D12Fence *fullFence =
nullptr;
1460 HANDLE fullFenceEvent =
nullptr;
1461 UINT64 fullFenceCounter = 0;
1462 ID3D12CommandAllocator *cmdAllocators[QD3D12_FRAMES_IN_FLIGHT] = {};
1463 QD3D12MemoryAllocator vma;
1464 QD3D12CpuDescriptorPool rtvPool;
1465 QD3D12CpuDescriptorPool dsvPool;
1466 QD3D12CpuDescriptorPool cbvSrvUavPool;
1467 QD3D12ObjectPool<QD3D12Resource> resourcePool;
1468 QD3D12ObjectPool<QD3D12Pipeline> pipelinePool;
1469 QD3D12ObjectPool<QD3D12RootSignature> rootSignaturePool;
1470 QD3D12ReleaseQueue releaseQueue;
1471 QD3D12ResourceBarrierGenerator barrierGen;
1472 QD3D12SamplerManager samplerMgr;
1473 QD3D12MipmapGenerator mipmapGen;
1474 QD3D12MipmapGenerator3D mipmapGen3D;
1475 QD3D12StagingArea smallStagingAreas[QD3D12_FRAMES_IN_FLIGHT];
1476 quint32 smallStagingAreaBytesNeeded[QD3D12_FRAMES_IN_FLIGHT] = {};
1477 int smallStagingAreaLowDemandFrames[QD3D12_FRAMES_IN_FLIGHT] = {};
1478 QD3D12ShaderVisibleDescriptorHeap shaderVisibleCbvSrvUavHeap;
1479 UINT64 timestampTicksPerSecond = 0;
1480 QD3D12QueryHeap timestampQueryHeap;
1481 QD3D12StagingArea timestampReadbackArea;
1482 IDCompositionDevice *dcompDevice =
nullptr;
1483 QD3D12SwapChain *currentSwapChain =
nullptr;
1484 QSet<QD3D12SwapChain *> swapchains;
1485 QD3D12ShaderBytecodeCache shaderBytecodeCache {
"Shader bytecode cache" };
1486 QVarLengthArray<QD3D12Readback, 4> activeReadbacks;
1487 bool offscreenActive =
false;
1488 QD3D12CommandBuffer *offscreenCb[QD3D12_FRAMES_IN_FLIGHT] = {};
1489 UINT shadingRateImageTileSize = 0;
1490 ID3D12CommandSignature *drawCommandSignature =
nullptr;
1491 ID3D12CommandSignature *drawIndexedCommandSignature =
nullptr;
1492 ID3D12CommandSignature *dispatchCommandSignature =
nullptr;
1493#ifdef QRHI_D3D12_PIPELINE_LIBRARY_AVAILABLE
1494 ID3D12PipelineLibrary1 *pipelineLibrary =
nullptr;
1497 QByteArray pipelineLibraryBlob;
1499 QSet<QByteArray> pipelineLibraryNames;
1501 QHash<quint32, ID3D12CommandSignature *> drawCommandSignaturesByStride;
1502 QHash<quint32, ID3D12CommandSignature *> drawIndexedCommandSignaturesByStride;
1505 bool multiView =
false;
1506 bool textureViewFormat =
false;
1508 bool vrsMap =
false;
1509 bool vrsAdditionalRates =
false;