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 QRHIVULKAN_P_H
5#define QRHIVULKAN_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
20QT_BEGIN_NAMESPACE
21
22class QVulkanFunctions;
23class QVulkanDeviceFunctions;
24
25static const int QVK_FRAMES_IN_FLIGHT = 2;
26
27static const int QVK_DESC_SETS_PER_POOL = 128;
28static const int QVK_UNIFORM_BUFFERS_PER_POOL = 256;
29static const int QVK_COMBINED_IMAGE_SAMPLERS_PER_POOL = 256;
30static const int QVK_STORAGE_BUFFERS_PER_POOL = 128;
31static const int QVK_STORAGE_IMAGES_PER_POOL = 128;
32
33static const int QVK_MAX_ACTIVE_TIMESTAMP_PAIRS = 16;
34
35// no vk_mem_alloc.h available here, void* is good enough
36typedef void * QVkAlloc;
37typedef void * QVkAllocator;
38
39struct QVkBuffer : public QRhiBuffer
40{
41 QVkBuffer(QRhiImplementation *rhi, Type type, UsageFlags usage, quint32 size);
42 ~QVkBuffer();
43 void destroy() override;
44 bool create() override;
45 QRhiBuffer::NativeBuffer nativeBuffer() override;
46 char *beginFullDynamicBufferUpdateForCurrentFrame() override;
47 void endFullDynamicBufferUpdateForCurrentFrame() override;
48
49 VkBuffer buffers[QVK_FRAMES_IN_FLIGHT];
50 QVkAlloc allocations[QVK_FRAMES_IN_FLIGHT];
51 struct DynamicUpdate {
52 quint32 offset;
53 QRhiBufferData data;
54 };
55 QVarLengthArray<DynamicUpdate, 16> pendingDynamicUpdates[QVK_FRAMES_IN_FLIGHT];
56 VkBuffer stagingBuffers[QVK_FRAMES_IN_FLIGHT];
57 QVkAlloc stagingAllocations[QVK_FRAMES_IN_FLIGHT];
58 struct UsageState {
59 VkAccessFlags access = 0;
60 VkPipelineStageFlags stage = 0;
61 };
62 UsageState usageState[QVK_FRAMES_IN_FLIGHT];
63 int lastActiveFrameSlot = -1;
64 uint generation = 0;
65 friend class QRhiVulkan;
66};
67
68Q_DECLARE_TYPEINFO(QVkBuffer::DynamicUpdate, Q_RELOCATABLE_TYPE);
69
70struct QVkTexture;
71
72struct QVkRenderBuffer : public QRhiRenderBuffer
73{
74 QVkRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize,
75 int sampleCount, Flags flags,
76 QRhiTexture::Format backingFormatHint);
77 ~QVkRenderBuffer();
78 void destroy() override;
79 bool create() override;
80 QRhiTexture::Format backingFormat() const override;
81
82 VkDeviceMemory memory = VK_NULL_HANDLE;
83 VkImage image = VK_NULL_HANDLE;
84 VkImageView imageView = VK_NULL_HANDLE;
85 VkSampleCountFlagBits samples;
86 QVkTexture *backingTexture = nullptr;
87 VkFormat vkformat;
88 int lastActiveFrameSlot = -1;
89 uint generation = 0;
90 friend class QRhiVulkan;
91};
92
93struct QVkTexture : public QRhiTexture
94{
95 QVkTexture(QRhiImplementation *rhi, Format format, const QSize &pixelSize, int depth,
96 int arraySize, int sampleCount, Flags flags);
97 ~QVkTexture();
98 void destroy() override;
99 bool create() override;
100 bool createFrom(NativeTexture src) override;
101 NativeTexture nativeTexture() override;
102 void setNativeLayout(int layout) override;
103
104 bool prepareCreate(QSize *adjustedSize = nullptr);
105 bool finishCreate();
106 VkImageView perLevelImageViewForLoadStore(int level);
107
108 VkImage image = VK_NULL_HANDLE;
109 VkImageView imageView = VK_NULL_HANDLE;
110 QVkAlloc imageAlloc = nullptr;
111 VkBuffer stagingBuffers[QVK_FRAMES_IN_FLIGHT];
112 QVkAlloc stagingAllocations[QVK_FRAMES_IN_FLIGHT];
113 VkImageView perLevelImageViews[QRhi::MAX_MIP_LEVELS];
114 bool owns = true;
115 struct UsageState {
116 // no tracking of subresource layouts (some operations can keep
117 // subresources in different layouts for some time, but that does not
118 // need to be kept track of)
119 VkImageLayout layout;
120 VkAccessFlags access;
121 VkPipelineStageFlags stage;
122 };
123 UsageState usageState;
124 VkFormat vkformat;
125 uint mipLevelCount = 0;
126 VkSampleCountFlagBits samples;
127 VkFormat viewFormat;
128 VkFormat viewFormatForSampling;
129 int lastActiveFrameSlot = -1;
130 uint generation = 0;
131 friend class QRhiVulkan;
132};
133
134struct QVkSampler : public QRhiSampler
135{
136 QVkSampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode,
137 AddressMode u, AddressMode v, AddressMode w);
138 ~QVkSampler();
139 void destroy() override;
140 bool create() override;
141
142 VkSampler sampler = VK_NULL_HANDLE;
143 int lastActiveFrameSlot = -1;
144 uint generation = 0;
145 friend class QRhiVulkan;
146};
147
148struct QVkRenderPassDescriptor : public QRhiRenderPassDescriptor
149{
150 QVkRenderPassDescriptor(QRhiImplementation *rhi);
151 ~QVkRenderPassDescriptor();
152 void destroy() override;
153 bool isCompatible(const QRhiRenderPassDescriptor *other) const override;
154 QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() const override;
155 QVector<quint32> serializedFormat() const override;
156 const QRhiNativeHandles *nativeHandles() override;
157
158 void updateSerializedFormat();
159
160 VkRenderPass rp = VK_NULL_HANDLE;
161 bool ownsRp = false;
162 QVarLengthArray<VkAttachmentDescription, 8> attDescs;
163 QVarLengthArray<VkAttachmentReference, 8> colorRefs;
164 QVarLengthArray<VkAttachmentReference, 8> resolveRefs;
165 QVarLengthArray<VkSubpassDependency, 2> subpassDeps;
166 bool hasDepthStencil = false;
167 bool hasDepthStencilResolve = false;
168 uint32_t multiViewCount = 0;
169 VkAttachmentReference dsRef;
170 VkAttachmentReference dsResolveRef;
171 QVector<quint32> serializedFormatData;
172 QRhiVulkanRenderPassNativeHandles nativeHandlesStruct;
173 int lastActiveFrameSlot = -1;
174};
175
176struct QVkRenderTargetData
177{
178 VkFramebuffer fb = VK_NULL_HANDLE;
179 QVkRenderPassDescriptor *rp = nullptr;
180 QSize pixelSize;
181 float dpr = 1;
182 int sampleCount = 1;
183 int colorAttCount = 0;
184 int dsAttCount = 0;
185 int resolveAttCount = 0;
186 int dsResolveAttCount = 0;
187 int multiViewCount = 0;
188 QRhiRenderTargetAttachmentTracker::ResIdList currentResIdList;
189 static const int MAX_COLOR_ATTACHMENTS = 8;
190};
191
192struct QVkSwapChainRenderTarget : public QRhiSwapChainRenderTarget
193{
194 QVkSwapChainRenderTarget(QRhiImplementation *rhi, QRhiSwapChain *swapchain);
195 ~QVkSwapChainRenderTarget();
196 void destroy() override;
197
198 QSize pixelSize() const override;
199 float devicePixelRatio() const override;
200 int sampleCount() const override;
201
202 QVkRenderTargetData d;
203};
204
205struct QVkTextureRenderTarget : public QRhiTextureRenderTarget
206{
207 QVkTextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc, Flags flags);
208 ~QVkTextureRenderTarget();
209 void destroy() override;
210
211 QSize pixelSize() const override;
212 float devicePixelRatio() const override;
213 int sampleCount() const override;
214
215 QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
216 bool create() override;
217
218 QVkRenderTargetData d;
219 VkImageView rtv[QVkRenderTargetData::MAX_COLOR_ATTACHMENTS];
220 VkImageView dsv = VK_NULL_HANDLE;
221 VkImageView resrtv[QVkRenderTargetData::MAX_COLOR_ATTACHMENTS];
222 VkImageView resdsv = VK_NULL_HANDLE;
223 int lastActiveFrameSlot = -1;
224 friend class QRhiVulkan;
225};
226
227struct QVkShaderResourceBindings : public QRhiShaderResourceBindings
228{
229 QVkShaderResourceBindings(QRhiImplementation *rhi);
230 ~QVkShaderResourceBindings();
231 void destroy() override;
232 bool create() override;
233 void updateResources(UpdateFlags flags) override;
234
235 QVarLengthArray<QRhiShaderResourceBinding, 8> sortedBindings;
236 bool hasSlottedResource = false;
237 bool hasDynamicOffset = false;
238 int poolIndex = -1;
239 VkDescriptorSetLayout layout = VK_NULL_HANDLE;
240 VkDescriptorSet descSets[QVK_FRAMES_IN_FLIGHT]; // multiple sets to support dynamic buffers
241 int lastActiveFrameSlot = -1;
242 uint generation = 0;
243
244 // Keep track of the generation number of each referenced QRhi* to be able
245 // to detect that the underlying descriptor set became out of date and they
246 // need to be written again with the up-to-date VkBuffer etc. objects.
247 struct BoundUniformBufferData {
248 quint64 id;
249 uint generation;
250 };
251 struct BoundSampledTextureData {
252 int count;
253 struct {
254 quint64 texId;
255 uint texGeneration;
256 quint64 samplerId;
257 uint samplerGeneration;
258 } d[QRhiShaderResourceBinding::Data::MAX_TEX_SAMPLER_ARRAY_SIZE];
259 };
260 struct BoundStorageImageData {
261 quint64 id;
262 uint generation;
263 };
264 struct BoundStorageBufferData {
265 quint64 id;
266 uint generation;
267 };
268 struct BoundResourceData {
269 union {
270 BoundUniformBufferData ubuf;
271 BoundSampledTextureData stex;
272 BoundStorageImageData simage;
273 BoundStorageBufferData sbuf;
274 };
275 };
276 QVarLengthArray<BoundResourceData, 8> boundResourceData[QVK_FRAMES_IN_FLIGHT];
277
278 friend class QRhiVulkan;
279};
280
281Q_DECLARE_TYPEINFO(QVkShaderResourceBindings::BoundResourceData, Q_RELOCATABLE_TYPE);
282
283struct QVkGraphicsPipeline : public QRhiGraphicsPipeline
284{
285 QVkGraphicsPipeline(QRhiImplementation *rhi);
286 ~QVkGraphicsPipeline();
287 void destroy() override;
288 bool create() override;
289
290 VkPipelineLayout layout = VK_NULL_HANDLE;
291 VkPipeline pipeline = VK_NULL_HANDLE;
292 int lastActiveFrameSlot = -1;
293 uint generation = 0;
294 friend class QRhiVulkan;
295};
296
297struct QVkComputePipeline : public QRhiComputePipeline
298{
299 QVkComputePipeline(QRhiImplementation *rhi);
300 ~QVkComputePipeline();
301 void destroy() override;
302 bool create() override;
303
304 VkPipelineLayout layout = VK_NULL_HANDLE;
305 VkPipeline pipeline = VK_NULL_HANDLE;
306 int lastActiveFrameSlot = -1;
307 uint generation = 0;
308 friend class QRhiVulkan;
309};
310
311struct QVkCommandBuffer : public QRhiCommandBuffer
312{
313 QVkCommandBuffer(QRhiImplementation *rhi);
314 ~QVkCommandBuffer();
315 void destroy() override;
316
317 const QRhiNativeHandles *nativeHandles();
318
319 VkCommandBuffer cb = VK_NULL_HANDLE; // primary
320 QRhiVulkanCommandBufferNativeHandles nativeHandlesStruct;
321
322 enum PassType {
323 NoPass,
324 RenderPass,
325 ComputePass
326 };
327
328 void resetState() {
329 recordingPass = NoPass;
330 passUsesSecondaryCb = false;
331 lastGpuTime = 0;
332 currentTarget = nullptr;
333 activeSecondaryCbStack.clear();
334 resetCommands();
335 resetCachedState();
336 }
337
338 void resetCachedState() {
339 currentGraphicsPipeline = nullptr;
340 currentComputePipeline = nullptr;
341 currentPipelineGeneration = 0;
342 currentGraphicsSrb = nullptr;
343 currentComputeSrb = nullptr;
344 currentSrbGeneration = 0;
345 currentDescSetSlot = -1;
346 currentIndexBuffer = VK_NULL_HANDLE;
347 currentIndexOffset = 0;
348 currentIndexFormat = VK_INDEX_TYPE_UINT16;
349 memset(s: currentVertexBuffers, c: 0, n: sizeof(currentVertexBuffers));
350 memset(s: currentVertexOffsets, c: 0, n: sizeof(currentVertexOffsets));
351 inExternal = false;
352 }
353
354 PassType recordingPass;
355 bool passUsesSecondaryCb;
356 double lastGpuTime = 0;
357 QRhiRenderTarget *currentTarget;
358 QRhiGraphicsPipeline *currentGraphicsPipeline;
359 QRhiComputePipeline *currentComputePipeline;
360 uint currentPipelineGeneration;
361 QRhiShaderResourceBindings *currentGraphicsSrb;
362 QRhiShaderResourceBindings *currentComputeSrb;
363 uint currentSrbGeneration;
364 int currentDescSetSlot;
365 VkBuffer currentIndexBuffer;
366 quint32 currentIndexOffset;
367 VkIndexType currentIndexFormat;
368 static const int VERTEX_INPUT_RESOURCE_SLOT_COUNT = 32;
369 VkBuffer currentVertexBuffers[VERTEX_INPUT_RESOURCE_SLOT_COUNT];
370 quint32 currentVertexOffsets[VERTEX_INPUT_RESOURCE_SLOT_COUNT];
371 QVarLengthArray<VkCommandBuffer, 4> activeSecondaryCbStack;
372 bool inExternal;
373
374 struct {
375 QHash<QRhiResource *, QPair<VkAccessFlags, bool> > writtenResources;
376 void reset() {
377 writtenResources.clear();
378 }
379 } computePassState;
380
381 struct Command {
382 enum Cmd {
383 CopyBuffer,
384 CopyBufferToImage,
385 CopyImage,
386 CopyImageToBuffer,
387 ImageBarrier,
388 BufferBarrier,
389 BlitImage,
390 BeginRenderPass,
391 EndRenderPass,
392 BindPipeline,
393 BindDescriptorSet,
394 BindVertexBuffer,
395 BindIndexBuffer,
396 SetViewport,
397 SetScissor,
398 SetBlendConstants,
399 SetStencilRef,
400 Draw,
401 DrawIndexed,
402 DebugMarkerBegin,
403 DebugMarkerEnd,
404 DebugMarkerInsert,
405 TransitionPassResources,
406 Dispatch,
407 ExecuteSecondary
408 };
409 Cmd cmd;
410
411 union Args {
412 struct {
413 VkBuffer src;
414 VkBuffer dst;
415 VkBufferCopy desc;
416 } copyBuffer;
417 struct {
418 VkBuffer src;
419 VkImage dst;
420 VkImageLayout dstLayout;
421 int count;
422 int bufferImageCopyIndex;
423 } copyBufferToImage;
424 struct {
425 VkImage src;
426 VkImageLayout srcLayout;
427 VkImage dst;
428 VkImageLayout dstLayout;
429 VkImageCopy desc;
430 } copyImage;
431 struct {
432 VkImage src;
433 VkImageLayout srcLayout;
434 VkBuffer dst;
435 VkBufferImageCopy desc;
436 } copyImageToBuffer;
437 struct {
438 VkPipelineStageFlags srcStageMask;
439 VkPipelineStageFlags dstStageMask;
440 int count;
441 int index;
442 } imageBarrier;
443 struct {
444 VkPipelineStageFlags srcStageMask;
445 VkPipelineStageFlags dstStageMask;
446 int count;
447 int index;
448 } bufferBarrier;
449 struct {
450 VkImage src;
451 VkImageLayout srcLayout;
452 VkImage dst;
453 VkImageLayout dstLayout;
454 VkFilter filter;
455 VkImageBlit desc;
456 } blitImage;
457 struct {
458 VkRenderPassBeginInfo desc;
459 int clearValueIndex;
460 bool useSecondaryCb;
461 } beginRenderPass;
462 struct {
463 } endRenderPass;
464 struct {
465 VkPipelineBindPoint bindPoint;
466 VkPipeline pipeline;
467 } bindPipeline;
468 struct {
469 VkPipelineBindPoint bindPoint;
470 VkPipelineLayout pipelineLayout;
471 VkDescriptorSet descSet;
472 int dynamicOffsetCount;
473 int dynamicOffsetIndex;
474 } bindDescriptorSet;
475 struct {
476 int startBinding;
477 int count;
478 int vertexBufferIndex;
479 int vertexBufferOffsetIndex;
480 } bindVertexBuffer;
481 struct {
482 VkBuffer buf;
483 VkDeviceSize ofs;
484 VkIndexType type;
485 } bindIndexBuffer;
486 struct {
487 VkViewport viewport;
488 } setViewport;
489 struct {
490 VkRect2D scissor;
491 } setScissor;
492 struct {
493 float c[4];
494 } setBlendConstants;
495 struct {
496 uint32_t ref;
497 } setStencilRef;
498 struct {
499 uint32_t vertexCount;
500 uint32_t instanceCount;
501 uint32_t firstVertex;
502 uint32_t firstInstance;
503 } draw;
504 struct {
505 uint32_t indexCount;
506 uint32_t instanceCount;
507 uint32_t firstIndex;
508 int32_t vertexOffset;
509 uint32_t firstInstance;
510 } drawIndexed;
511 struct {
512#ifdef VK_EXT_debug_utils
513 VkDebugUtilsLabelEXT label;
514 int labelNameIndex;
515#endif
516 } debugMarkerBegin;
517 struct {
518 } debugMarkerEnd;
519 struct {
520#ifdef VK_EXT_debug_utils
521 VkDebugUtilsLabelEXT label;
522 int labelNameIndex;
523#endif
524 } debugMarkerInsert;
525 struct {
526 int trackerIndex;
527 } transitionResources;
528 struct {
529 int x, y, z;
530 } dispatch;
531 struct {
532 VkCommandBuffer cb;
533 } executeSecondary;
534 } args;
535 };
536
537 QRhiBackendCommandList<Command> commands;
538 QVarLengthArray<QRhiPassResourceTracker, 8> passResTrackers;
539 int currentPassResTrackerIndex;
540
541 void resetCommands() {
542 commands.reset();
543 resetPools();
544
545 passResTrackers.clear();
546 currentPassResTrackerIndex = -1;
547 }
548
549 void resetPools() {
550 pools.clearValue.clear();
551 pools.bufferImageCopy.clear();
552 pools.dynamicOffset.clear();
553 pools.vertexBuffer.clear();
554 pools.vertexBufferOffset.clear();
555 pools.debugMarkerData.clear();
556 pools.imageBarrier.clear();
557 pools.bufferBarrier.clear();
558 }
559
560 struct {
561 QVarLengthArray<VkClearValue, 4> clearValue;
562 QVarLengthArray<VkBufferImageCopy, 16> bufferImageCopy;
563 QVarLengthArray<uint32_t, 4> dynamicOffset;
564 QVarLengthArray<VkBuffer, 4> vertexBuffer;
565 QVarLengthArray<VkDeviceSize, 4> vertexBufferOffset;
566 QVarLengthArray<QByteArray, 4> debugMarkerData;
567 QVarLengthArray<VkImageMemoryBarrier, 8> imageBarrier;
568 QVarLengthArray<VkBufferMemoryBarrier, 8> bufferBarrier;
569 } pools;
570
571 friend class QRhiVulkan;
572};
573
574struct QVkSwapChain : public QRhiSwapChain
575{
576 QVkSwapChain(QRhiImplementation *rhi);
577 ~QVkSwapChain();
578 void destroy() override;
579
580 QRhiCommandBuffer *currentFrameCommandBuffer() override;
581 QRhiRenderTarget *currentFrameRenderTarget() override;
582 QRhiRenderTarget *currentFrameRenderTarget(StereoTargetBuffer targetBuffer) override;
583
584 QSize surfacePixelSize() override;
585 bool isFormatSupported(Format f) override;
586
587 QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
588 bool createOrResize() override;
589
590 bool ensureSurface();
591
592 static const quint32 EXPECTED_MAX_BUFFER_COUNT = 4;
593
594 QWindow *window = nullptr;
595 QSize pixelSize;
596 bool supportsReadback = false;
597 bool stereo = false;
598 VkSwapchainKHR sc = VK_NULL_HANDLE;
599 int bufferCount = 0;
600 VkSurfaceKHR surface = VK_NULL_HANDLE;
601 VkSurfaceKHR lastConnectedSurface = VK_NULL_HANDLE;
602 VkFormat colorFormat = VK_FORMAT_B8G8R8A8_UNORM;
603 VkColorSpaceKHR colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
604 QVkRenderBuffer *ds = nullptr;
605 VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
606 QVarLengthArray<VkPresentModeKHR, 8> supportedPresentationModes;
607 VkDeviceMemory msaaImageMem = VK_NULL_HANDLE;
608 QVkSwapChainRenderTarget rtWrapper;
609 QVkSwapChainRenderTarget rtWrapperRight;
610 QVkCommandBuffer cbWrapper;
611
612 struct ImageResources {
613 VkImage image = VK_NULL_HANDLE;
614 VkImageView imageView = VK_NULL_HANDLE;
615 VkFramebuffer fb = VK_NULL_HANDLE;
616 VkImage msaaImage = VK_NULL_HANDLE;
617 VkImageView msaaImageView = VK_NULL_HANDLE;
618 enum LastUse {
619 ScImageUseNone,
620 ScImageUseRender,
621 ScImageUseTransferSource
622 };
623 LastUse lastUse = ScImageUseNone;
624 };
625 QVarLengthArray<ImageResources, EXPECTED_MAX_BUFFER_COUNT> imageRes;
626
627 struct FrameResources {
628 VkSemaphore imageSem = VK_NULL_HANDLE;
629 VkSemaphore drawSem = VK_NULL_HANDLE;
630 bool imageAcquired = false;
631 bool imageSemWaitable = false;
632 VkFence cmdFence = VK_NULL_HANDLE;
633 bool cmdFenceWaitable = false;
634 VkCommandBuffer cmdBuf = VK_NULL_HANDLE; // primary
635 int timestampQueryIndex = -1;
636 } frameRes[QVK_FRAMES_IN_FLIGHT];
637
638 quint32 currentImageIndex = 0; // index in imageRes
639 quint32 currentFrameSlot = 0; // index in frameRes
640 int frameCount = 0;
641
642 friend class QRhiVulkan;
643};
644
645class QRhiVulkan : public QRhiImplementation
646{
647public:
648 QRhiVulkan(QRhiVulkanInitParams *params, QRhiVulkanNativeHandles *importParams = nullptr);
649
650 bool create(QRhi::Flags flags) override;
651 void destroy() override;
652
653 QRhiGraphicsPipeline *createGraphicsPipeline() override;
654 QRhiComputePipeline *createComputePipeline() override;
655 QRhiShaderResourceBindings *createShaderResourceBindings() override;
656 QRhiBuffer *createBuffer(QRhiBuffer::Type type,
657 QRhiBuffer::UsageFlags usage,
658 quint32 size) override;
659 QRhiRenderBuffer *createRenderBuffer(QRhiRenderBuffer::Type type,
660 const QSize &pixelSize,
661 int sampleCount,
662 QRhiRenderBuffer::Flags flags,
663 QRhiTexture::Format backingFormatHint) override;
664 QRhiTexture *createTexture(QRhiTexture::Format format,
665 const QSize &pixelSize,
666 int depth,
667 int arraySize,
668 int sampleCount,
669 QRhiTexture::Flags flags) override;
670 QRhiSampler *createSampler(QRhiSampler::Filter magFilter,
671 QRhiSampler::Filter minFilter,
672 QRhiSampler::Filter mipmapMode,
673 QRhiSampler:: AddressMode u,
674 QRhiSampler::AddressMode v,
675 QRhiSampler::AddressMode w) override;
676
677 QRhiTextureRenderTarget *createTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc,
678 QRhiTextureRenderTarget::Flags flags) override;
679
680 QRhiSwapChain *createSwapChain() override;
681 QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags) override;
682 QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags) override;
683 QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags) override;
684 QRhi::FrameOpResult endOffscreenFrame(QRhi::EndFrameFlags flags) override;
685 QRhi::FrameOpResult finish() override;
686
687 void resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
688
689 void beginPass(QRhiCommandBuffer *cb,
690 QRhiRenderTarget *rt,
691 const QColor &colorClearValue,
692 const QRhiDepthStencilClearValue &depthStencilClearValue,
693 QRhiResourceUpdateBatch *resourceUpdates,
694 QRhiCommandBuffer::BeginPassFlags flags) override;
695 void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
696
697 void setGraphicsPipeline(QRhiCommandBuffer *cb,
698 QRhiGraphicsPipeline *ps) override;
699
700 void setShaderResources(QRhiCommandBuffer *cb,
701 QRhiShaderResourceBindings *srb,
702 int dynamicOffsetCount,
703 const QRhiCommandBuffer::DynamicOffset *dynamicOffsets) override;
704
705 void setVertexInput(QRhiCommandBuffer *cb,
706 int startBinding, int bindingCount, const QRhiCommandBuffer::VertexInput *bindings,
707 QRhiBuffer *indexBuf, quint32 indexOffset,
708 QRhiCommandBuffer::IndexFormat indexFormat) override;
709
710 void setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) override;
711 void setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) override;
712 void setBlendConstants(QRhiCommandBuffer *cb, const QColor &c) override;
713 void setStencilRef(QRhiCommandBuffer *cb, quint32 refValue) override;
714
715 void draw(QRhiCommandBuffer *cb, quint32 vertexCount,
716 quint32 instanceCount, quint32 firstVertex, quint32 firstInstance) override;
717
718 void drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
719 quint32 instanceCount, quint32 firstIndex,
720 qint32 vertexOffset, quint32 firstInstance) override;
721
722 void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) override;
723 void debugMarkEnd(QRhiCommandBuffer *cb) override;
724 void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override;
725
726 void beginComputePass(QRhiCommandBuffer *cb,
727 QRhiResourceUpdateBatch *resourceUpdates,
728 QRhiCommandBuffer::BeginPassFlags flags) override;
729 void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
730 void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) override;
731 void dispatch(QRhiCommandBuffer *cb, int x, int y, int z) override;
732
733 const QRhiNativeHandles *nativeHandles(QRhiCommandBuffer *cb) override;
734 void beginExternal(QRhiCommandBuffer *cb) override;
735 void endExternal(QRhiCommandBuffer *cb) override;
736 double lastCompletedGpuTime(QRhiCommandBuffer *cb) override;
737
738 QList<int> supportedSampleCounts() const override;
739 int ubufAlignment() const override;
740 bool isYUpInFramebuffer() const override;
741 bool isYUpInNDC() const override;
742 bool isClipDepthZeroToOne() const override;
743 QMatrix4x4 clipSpaceCorrMatrix() const override;
744 bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const override;
745 bool isFeatureSupported(QRhi::Feature feature) const override;
746 int resourceLimit(QRhi::ResourceLimit limit) const override;
747 const QRhiNativeHandles *nativeHandles() override;
748 QRhiDriverInfo driverInfo() const override;
749 QRhiStats statistics() override;
750 bool makeThreadLocalNativeContextCurrent() override;
751 void releaseCachedResources() override;
752 bool isDeviceLost() const override;
753
754 QByteArray pipelineCacheData() override;
755 void setPipelineCacheData(const QByteArray &data) override;
756
757 VkResult createDescriptorPool(VkDescriptorPool *pool);
758 bool allocateDescriptorSet(VkDescriptorSetAllocateInfo *allocInfo, VkDescriptorSet *result, int *resultPoolIndex);
759 uint32_t chooseTransientImageMemType(VkImage img, uint32_t startIndex);
760 bool createTransientImage(VkFormat format, const QSize &pixelSize, VkImageUsageFlags usage,
761 VkImageAspectFlags aspectMask, VkSampleCountFlagBits samples,
762 VkDeviceMemory *mem, VkImage *images, VkImageView *views, int count);
763
764 bool recreateSwapChain(QRhiSwapChain *swapChain);
765 void releaseSwapChainResources(QRhiSwapChain *swapChain);
766
767 VkFormat optimalDepthStencilFormat();
768 VkSampleCountFlagBits effectiveSampleCountBits(int sampleCount);
769 bool createDefaultRenderPass(QVkRenderPassDescriptor *rpD,
770 bool hasDepthStencil,
771 VkSampleCountFlagBits samples,
772 VkFormat colorFormat);
773 bool createOffscreenRenderPass(QVkRenderPassDescriptor *rpD,
774 const QRhiColorAttachment *colorAttachmentsBegin,
775 const QRhiColorAttachment *colorAttachmentsEnd,
776 bool preserveColor,
777 bool preserveDs,
778 bool storeDs,
779 QRhiRenderBuffer *depthStencilBuffer,
780 QRhiTexture *depthTexture,
781 QRhiTexture *depthResolveTexture);
782 bool ensurePipelineCache(const void *initialData = nullptr, size_t initialDataSize = 0);
783 VkShaderModule createShader(const QByteArray &spirv);
784
785 void prepareNewFrame(QRhiCommandBuffer *cb);
786 VkCommandBuffer startSecondaryCommandBuffer(QVkRenderTargetData *rtD = nullptr);
787 void endAndEnqueueSecondaryCommandBuffer(VkCommandBuffer cb, QVkCommandBuffer *cbD);
788 QRhi::FrameOpResult startPrimaryCommandBuffer(VkCommandBuffer *cb);
789 QRhi::FrameOpResult endAndSubmitPrimaryCommandBuffer(VkCommandBuffer cb, VkFence cmdFence,
790 VkSemaphore *waitSem, VkSemaphore *signalSem);
791 void waitCommandCompletion(int frameSlot);
792 VkDeviceSize subresUploadByteSize(const QRhiTextureSubresourceUploadDescription &subresDesc) const;
793 using BufferImageCopyList = QVarLengthArray<VkBufferImageCopy, 16>;
794 void prepareUploadSubres(QVkTexture *texD, int layer, int level,
795 const QRhiTextureSubresourceUploadDescription &subresDesc,
796 size_t *curOfs, void *mp,
797 BufferImageCopyList *copyInfos);
798 void enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdateBatch *resourceUpdates);
799 void executeBufferHostWritesForSlot(QVkBuffer *bufD, int slot);
800 void enqueueTransitionPassResources(QVkCommandBuffer *cbD);
801 void recordPrimaryCommandBuffer(QVkCommandBuffer *cbD);
802 void trackedRegisterBuffer(QRhiPassResourceTracker *passResTracker,
803 QVkBuffer *bufD,
804 int slot,
805 QRhiPassResourceTracker::BufferAccess access,
806 QRhiPassResourceTracker::BufferStage stage);
807 void trackedRegisterTexture(QRhiPassResourceTracker *passResTracker,
808 QVkTexture *texD,
809 QRhiPassResourceTracker::TextureAccess access,
810 QRhiPassResourceTracker::TextureStage stage);
811 void recordTransitionPassResources(QVkCommandBuffer *cbD, const QRhiPassResourceTracker &tracker);
812 void activateTextureRenderTarget(QVkCommandBuffer *cbD, QVkTextureRenderTarget *rtD);
813 void executeDeferredReleases(bool forced = false);
814 void finishActiveReadbacks(bool forced = false);
815
816 void setObjectName(uint64_t object, VkObjectType type, const QByteArray &name, int slot = -1);
817 void trackedBufferBarrier(QVkCommandBuffer *cbD, QVkBuffer *bufD, int slot,
818 VkAccessFlags access, VkPipelineStageFlags stage);
819 void trackedImageBarrier(QVkCommandBuffer *cbD, QVkTexture *texD,
820 VkImageLayout layout, VkAccessFlags access, VkPipelineStageFlags stage);
821 void depthStencilExplicitBarrier(QVkCommandBuffer *cbD, QVkRenderBuffer *rbD);
822 void subresourceBarrier(QVkCommandBuffer *cbD, VkImage image,
823 VkImageLayout oldLayout, VkImageLayout newLayout,
824 VkAccessFlags srcAccess, VkAccessFlags dstAccess,
825 VkPipelineStageFlags srcStage, VkPipelineStageFlags dstStage,
826 int startLayer, int layerCount,
827 int startLevel, int levelCount);
828 void updateShaderResourceBindings(QRhiShaderResourceBindings *srb, int descSetIdx = -1);
829 void ensureCommandPoolForNewFrame();
830 double elapsedSecondsFromTimestamp(quint64 timestamp[2], bool *ok);
831 void printExtraErrorInfo(VkResult err);
832
833 QVulkanInstance *inst = nullptr;
834 QWindow *maybeWindow = nullptr;
835 QByteArrayList requestedDeviceExtensions;
836 bool importedDevice = false;
837 VkPhysicalDevice physDev = VK_NULL_HANDLE;
838 VkDevice dev = VK_NULL_HANDLE;
839 VkCommandPool cmdPool[QVK_FRAMES_IN_FLIGHT] = {};
840 quint32 gfxQueueFamilyIdx = 0;
841 quint32 gfxQueueIdx = 0;
842 VkQueue gfxQueue = VK_NULL_HANDLE;
843 quint32 timestampValidBits = 0;
844 bool importedAllocator = false;
845 QVkAllocator allocator = nullptr;
846 QVulkanFunctions *f = nullptr;
847 QVulkanDeviceFunctions *df = nullptr;
848 QRhi::Flags rhiFlags;
849 VkPhysicalDeviceFeatures physDevFeatures;
850#ifdef VK_VERSION_1_1
851 VkPhysicalDeviceMultiviewFeatures multiviewFeaturesIfApi11;
852#endif
853#ifdef VK_VERSION_1_2
854 VkPhysicalDeviceVulkan11Features physDevFeatures11IfApi12OrNewer;
855 VkPhysicalDeviceVulkan12Features physDevFeatures12;
856#endif
857#ifdef VK_VERSION_1_3
858 VkPhysicalDeviceVulkan13Features physDevFeatures13;
859#endif
860 VkPhysicalDeviceProperties physDevProperties;
861 VkDeviceSize ubufAlign;
862 VkDeviceSize texbufAlign;
863 bool deviceLost = false;
864 bool releaseCachedResourcesCalledBeforeFrameStart = false;
865
866#ifdef VK_EXT_debug_utils
867 PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT = nullptr;
868 PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT = nullptr;
869 PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT = nullptr;
870 PFN_vkCmdInsertDebugUtilsLabelEXT vkCmdInsertDebugUtilsLabelEXT = nullptr;
871#endif
872
873 PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR = nullptr;
874 PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
875 PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
876 PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
877 PFN_vkQueuePresentKHR vkQueuePresentKHR;
878 PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
879 PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
880 PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
881
882#ifdef VK_KHR_create_renderpass2
883 PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = nullptr;
884#endif
885
886 struct {
887 bool compute = false;
888 bool wideLines = false;
889 bool debugUtils = false;
890 bool vertexAttribDivisor = false;
891 bool texture3DSliceAs2D = false;
892 bool tessellation = false;
893 bool geometryShader = false;
894 bool nonFillPolygonMode = false;
895 bool multiView = false;
896 bool renderPass2KHR = false;
897 bool depthStencilResolveKHR = false;
898 QVersionNumber apiVersion;
899 } caps;
900
901 VkPipelineCache pipelineCache = VK_NULL_HANDLE;
902 struct DescriptorPoolData {
903 DescriptorPoolData() { }
904 DescriptorPoolData(VkDescriptorPool pool_)
905 : pool(pool_)
906 { }
907 VkDescriptorPool pool = VK_NULL_HANDLE;
908 int refCount = 0;
909 int allocedDescSets = 0;
910 };
911 QVarLengthArray<DescriptorPoolData, 8> descriptorPools;
912 QVarLengthArray<VkCommandBuffer, 4> freeSecondaryCbs[QVK_FRAMES_IN_FLIGHT];
913
914 VkQueryPool timestampQueryPool = VK_NULL_HANDLE;
915 QBitArray timestampQueryPoolMap;
916
917 VkFormat optimalDsFormat = VK_FORMAT_UNDEFINED;
918 QMatrix4x4 clipCorrectMatrix;
919
920 QVkSwapChain *currentSwapChain = nullptr;
921 QSet<QVkSwapChain *> swapchains;
922 QRhiVulkanNativeHandles nativeHandlesStruct;
923 QRhiDriverInfo driverInfoStruct;
924
925 struct OffscreenFrame {
926 OffscreenFrame(QRhiImplementation *rhi)
927 {
928 for (int i = 0; i < QVK_FRAMES_IN_FLIGHT; ++i)
929 cbWrapper[i] = new QVkCommandBuffer(rhi);
930 }
931 ~OffscreenFrame()
932 {
933 for (int i = 0; i < QVK_FRAMES_IN_FLIGHT; ++i)
934 delete cbWrapper[i];
935 }
936 bool active = false;
937 QVkCommandBuffer *cbWrapper[QVK_FRAMES_IN_FLIGHT];
938 VkFence cmdFence = VK_NULL_HANDLE;
939 int timestampQueryIndex = -1;
940 } ofr;
941
942 struct TextureReadback {
943 int activeFrameSlot = -1;
944 QRhiReadbackDescription desc;
945 QRhiReadbackResult *result;
946 VkBuffer stagingBuf;
947 QVkAlloc stagingAlloc;
948 quint32 byteSize;
949 QSize pixelSize;
950 QRhiTexture::Format format;
951 };
952 QVarLengthArray<TextureReadback, 2> activeTextureReadbacks;
953 struct BufferReadback {
954 int activeFrameSlot = -1;
955 QRhiReadbackResult *result;
956 quint32 byteSize;
957 VkBuffer stagingBuf;
958 QVkAlloc stagingAlloc;
959 };
960 QVarLengthArray<BufferReadback, 2> activeBufferReadbacks;
961
962 struct DeferredReleaseEntry {
963 enum Type {
964 Pipeline,
965 ShaderResourceBindings,
966 Buffer,
967 RenderBuffer,
968 Texture,
969 Sampler,
970 TextureRenderTarget,
971 RenderPass,
972 StagingBuffer,
973 SecondaryCommandBuffer
974 };
975 Type type;
976 int lastActiveFrameSlot; // -1 if not used otherwise 0..FRAMES_IN_FLIGHT-1
977 union {
978 struct {
979 VkPipeline pipeline;
980 VkPipelineLayout layout;
981 } pipelineState;
982 struct {
983 int poolIndex;
984 VkDescriptorSetLayout layout;
985 } shaderResourceBindings;
986 struct {
987 VkBuffer buffers[QVK_FRAMES_IN_FLIGHT];
988 QVkAlloc allocations[QVK_FRAMES_IN_FLIGHT];
989 VkBuffer stagingBuffers[QVK_FRAMES_IN_FLIGHT];
990 QVkAlloc stagingAllocations[QVK_FRAMES_IN_FLIGHT];
991 } buffer;
992 struct {
993 VkDeviceMemory memory;
994 VkImage image;
995 VkImageView imageView;
996 } renderBuffer;
997 struct {
998 VkImage image;
999 VkImageView imageView;
1000 QVkAlloc allocation;
1001 VkBuffer stagingBuffers[QVK_FRAMES_IN_FLIGHT];
1002 QVkAlloc stagingAllocations[QVK_FRAMES_IN_FLIGHT];
1003 VkImageView extraImageViews[QRhi::MAX_MIP_LEVELS];
1004 } texture;
1005 struct {
1006 VkSampler sampler;
1007 } sampler;
1008 struct {
1009 VkFramebuffer fb;
1010 VkImageView rtv[QVkRenderTargetData::MAX_COLOR_ATTACHMENTS];
1011 VkImageView resrtv[QVkRenderTargetData::MAX_COLOR_ATTACHMENTS];
1012 VkImageView dsv;
1013 VkImageView resdsv;
1014 } textureRenderTarget;
1015 struct {
1016 VkRenderPass rp;
1017 } renderPass;
1018 struct {
1019 VkBuffer stagingBuffer;
1020 QVkAlloc stagingAllocation;
1021 } stagingBuffer;
1022 struct {
1023 VkCommandBuffer cb;
1024 } secondaryCommandBuffer;
1025 };
1026 };
1027 QList<DeferredReleaseEntry> releaseQueue;
1028};
1029
1030Q_DECLARE_TYPEINFO(QRhiVulkan::DescriptorPoolData, Q_RELOCATABLE_TYPE);
1031Q_DECLARE_TYPEINFO(QRhiVulkan::DeferredReleaseEntry, Q_RELOCATABLE_TYPE);
1032Q_DECLARE_TYPEINFO(QRhiVulkan::TextureReadback, Q_RELOCATABLE_TYPE);
1033Q_DECLARE_TYPEINFO(QRhiVulkan::BufferReadback, Q_RELOCATABLE_TYPE);
1034
1035QT_END_NAMESPACE
1036
1037#endif
1038

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtbase/src/gui/rhi/qrhivulkan_p.h