KarmaEngine
Game Engine for practical learning and research purposes
Loading...
Searching...
No Matches
VulkanRenderPass.h
Go to the documentation of this file.
1
10
11#pragma once
12
14#include "Core/KarmaTypes.h"
15#include "KarmaMemory.h"
16#include "Core.h"
17
18namespace Karma
19{
43 template <typename TAttachmentReferenceType>
44 struct FVulkanAttachmentReference : public TAttachmentReferenceType
45 {
46 FVulkanAttachmentReference()
47 {
48 ZeroStruct();
49 }
50
56 FVulkanAttachmentReference(const VkAttachmentReference& AttachmentReferenceIn, VkImageAspectFlags AspectMask)
57 {
58 SetAttachment(AttachmentReferenceIn, AspectMask);
59 }
60
78 inline void SetAttachment(const VkAttachmentReference& AttachmentReferenceIn, VkImageAspectFlags AspectMask) { checkNoEntry(); }
79
85 inline void SetAttachment(const FVulkanAttachmentReference<TAttachmentReferenceType>& AttachmentReferenceIn, VkImageAspectFlags AspectMask) { *this = AttachmentReferenceIn; }
86
96 inline void SetDepthStencilAttachment(const VkAttachmentReference& AttachmentReferenceIn, const VkAttachmentReferenceStencilLayout* StencilReference, VkImageAspectFlags AspectMask, bool bSupportsParallelRendering) { checkNoEntry(); }
97
103 inline void ZeroStruct() {}
104 //inline void SetAspect(uint32_t Aspect) {}
105 };
106
113 template <>
114 inline void FVulkanAttachmentReference<VkAttachmentReference>::SetAttachment(const VkAttachmentReference& AttachmentReferenceIn, VkImageAspectFlags AspectMask)
115 {
116 attachment = AttachmentReferenceIn.attachment;
117 layout = AttachmentReferenceIn.layout;
118 }
119
126 template <>
127 inline void FVulkanAttachmentReference<VkAttachmentReference>::SetDepthStencilAttachment(const VkAttachmentReference& AttachmentReferenceIn,
128 const VkAttachmentReferenceStencilLayout* StencilReference, VkImageAspectFlags AspectMask, bool bSupportsParallelRendering)
129 {
130 attachment = AttachmentReferenceIn.attachment;
131 //const VkImageLayout StencilLayout = StencilReference ? StencilReference->stencilLayout : VK_IMAGE_LAYOUT_UNDEFINED;
132
133 layout = AttachmentReferenceIn.layout; //GetMergedDepthStencilLayout(AttachmentReferenceIn.layout, StencilLayout);
134 }
135
143 template<>
145 {
146 attachment = 0;
147 layout = VK_IMAGE_LAYOUT_UNDEFINED;
148 }
149
162 template<typename TAttachmentDescriptionType>
164 {
165 };
166
172 template<>
173 struct FVulkanAttachmentDescription<VkAttachmentDescription>
174 : public VkAttachmentDescription
175 {
182 {
183 FMemory::Memzero(this, sizeof(VkAttachmentDescription));
184 }
185
193 FVulkanAttachmentDescription(const VkAttachmentDescription& InDesc)
194 {
195 flags = InDesc.flags;
196 format = InDesc.format;
197 samples = InDesc.samples;
198 loadOp = InDesc.loadOp;
199 storeOp = InDesc.storeOp;
200 stencilLoadOp = InDesc.stencilLoadOp;
201 stencilStoreOp = InDesc.stencilStoreOp;
202 initialLayout = InDesc.initialLayout;
203 finalLayout = InDesc.finalLayout;
204 }
205
213 FVulkanAttachmentDescription(const VkAttachmentDescription& InDesc, const VkAttachmentDescriptionStencilLayout* InStencilDesc, bool bSupportsParallelRendering)
214 {
215 //flags = InDesc.flags;
216 format = InDesc.format;
217 samples = InDesc.samples;
218 loadOp = InDesc.loadOp;
219 storeOp = InDesc.storeOp;
220 stencilLoadOp = InDesc.stencilLoadOp;
221 stencilStoreOp = InDesc.stencilStoreOp;
222
223 /*const bool bHasStencilLayout = VulkanFormatHasStencil(InDesc.format) && (InStencilDesc != nullptr);
224 const VkImageLayout StencilInitialLayout = bHasStencilLayout ? InStencilDesc->stencilInitialLayout : VK_IMAGE_LAYOUT_UNDEFINED;
225 initialLayout = GetMergedDepthStencilLayout(InDesc.initialLayout, StencilInitialLayout);
226 const VkImageLayout StencilFinalLayout = bHasStencilLayout ? InStencilDesc->stencilFinalLayout : VK_IMAGE_LAYOUT_UNDEFINED;
227 finalLayout = GetMergedDepthStencilLayout(InDesc.finalLayout, StencilFinalLayout);
228 */
229 }
230 };
231
245 template <typename TSubpassDescriptionType>
247 {
248 };
249
253 template<>
254 struct FVulkanSubpassDescription<VkSubpassDescription>
255 : public VkSubpassDescription
256 {
265 {
266 FMemory::Memzero(this, sizeof(VkSubpassDescription));
267 pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
268 }
269
278 void SetColorAttachments(const KarmaVector<FVulkanAttachmentReference<VkAttachmentReference>>& ColorAttachmentReferences, int OverrideCount = -1)
279 {
280 colorAttachmentCount = (OverrideCount == -1) ? ColorAttachmentReferences.Num() : OverrideCount;
281 pColorAttachments = ColorAttachmentReferences.GetData();
282 }
283
284 /*void SetResolveAttachments(const KarmaVector<FVulkanAttachmentReference<VkAttachmentReference>>& ResolveAttachmentReferences)
285 {
286 if (ResolveAttachmentReferences.Num() > 0)
287 {
288 check(colorAttachmentCount == ResolveAttachmentReferences.Num());
289 pResolveAttachments = ResolveAttachmentReferences.GetData();
290 }
291 }*/
292
301 {
302 pDepthStencilAttachment = static_cast<VkAttachmentReference*>(DepthStencilAttachmentReference);
303 }
304
305 /*void SetInputAttachments(FVulkanAttachmentReference<VkAttachmentReference>* InputAttachmentReferences, uint32 NumInputAttachmentReferences)
306 {
307 pInputAttachments = static_cast<VkAttachmentReference*>(InputAttachmentReferences);
308 inputAttachmentCount = NumInputAttachmentReferences;
309 }
310
311 void SetShadingRateAttachment(void* /* ShadingRateAttachmentInfo)
312 {
313 // No-op without VK_KHR_create_renderpass2
314 }
315
316 void SetMultiViewMask(uint32_t Mask)
317 {
318 // No-op without VK_KHR_create_renderpass2
319 }*/
320 };
321
333 template <typename TSubpassDependencyType>
335 : public TSubpassDependencyType
336 {
337 };
338
344 template<>
345 struct FVulkanSubpassDependency<VkSubpassDependency>
346 : public VkSubpassDependency
347 {
356 {
357 FMemory::Memzero(this, sizeof(VkSubpassDependency));
358 }
359 };
360
368 template <typename T>
370 {
371 };
372
376 template<>
377 struct FVulkanRenderPassCreateInfo<VkRenderPassCreateInfo>
378 : public VkRenderPassCreateInfo
379 {
388 {
389 //ZeroVulkanStruct(*this, VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
390 this->sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
391 FMemory::Memzero(((uint8_t*)&(*this)) + sizeof(VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO), sizeof(VkRenderPassCreateInfo) - sizeof(VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO));
392 }
393
399 VkRenderPass Create(FVulkanDevice& Device)
400 {
401 VkRenderPass Handle = VK_NULL_HANDLE;
402 //VERIFYVULKANRESULT_EXPANDED(VulkanRHI::vkCreateRenderPass(Device.GetInstanceHandle(), this, VULKAN_CPU_ALLOCATOR, &Handle));
403 VkResult result = vkCreateRenderPass(Device.GetLogicalDevice(), this, nullptr, &Handle);
404
405 KR_CORE_ASSERT(result == VK_SUCCESS, "Failed to create render pass");
406
407 KR_CORE_INFO("Renderpass created successfully");
408
409 return Handle;
410 }
411 };
412
418 enum
419 {
420 MaxSimultaneousRenderTargets = 8,
421 MaxSimultaneousRenderTargets_NumBits = 3,
422 };
423 static_assert(MaxSimultaneousRenderTargets <= (1 << MaxSimultaneousRenderTargets_NumBits), "MaxSimultaneousRenderTargets will not fit on MaxSimultaneousRenderTargets_NumBits");
424
433 {
438 {
442 VkAttachmentDescriptionFlags AttachmentFlags;
443
448
452 VkSampleCountFlagBits AttachmentSampleCount;
453
457 VkAttachmentLoadOp AttachmentLoadOperation;
458
462 VkAttachmentStoreOp AttachmentStoreOperation;
463
468
473
494
499 };
500
505 {
509 uint32_t attachment;
510
519 VkImageLayout layout;
520 };
521
522 KarmaVector<FAttachmentInfo> m_AttachmentsInfo;// color + depth
523 KarmaVector<FAttachmentRefInfo> m_ColorAttachmentsRefInfo;
524 bool bHasDepthAttachment;
525 FAttachmentRefInfo m_DepthAttachmentReference;
526 VkRect2D m_RenderArea;
527 };
528
535 {
536 public:
543 //FVulkanRenderTargetLayout(const FGraphicsPipelineStateInitializer& Initializer);
544
545 // Experimental layout constructor (layout as in VulkanContext). We need to make this generic somehow
547
548 //FVulkanRenderTargetLayout(FVulkanDevice& InDevice, const FRHISetRenderTargetsInfo& RTInfo);
549 //FVulkanRenderTargetLayout(FVulkanDevice& InDevice, const FRHIRenderPassInfo& RPInfo, VkImageLayout CurrentDepthLayout, VkImageLayout CurrentStencilLayout);
550
551 // Getters
552 inline const VkAttachmentReference* GetColorAttachmentReferences() const { return m_NumColorAttachments > 0 ? m_ColorReferences : nullptr; }
553 inline const VkAttachmentReference* GetDepthAttachmentReference() const { return bHasDepthStencil ? &m_DepthReference : nullptr; }
554 inline const VkAttachmentReferenceStencilLayout* GetStencilAttachmentReference() const { return bHasDepthStencil ? &m_StencilReference : nullptr; }
555 inline uint32_t GetNumColorAttachments() const { return m_NumColorAttachments; }
556 inline uint32_t GetNumAttachmentDescriptions() const { return m_NumAttachmentDescriptions; }
557 inline const VkAttachmentDescription* GetAttachmentDescriptions() const { return m_AttachmentDescriptions; }
558 inline const VkRect2D& GetRenderArea() const { return m_RenderArea; }
559
560 private:
561 VkAttachmentReference m_ColorReferences[MaxSimultaneousRenderTargets];
562
563 // Depth attachment ref
564 VkAttachmentReference m_DepthReference;
565
566 // Probabbly not required
567 VkAttachmentReferenceStencilLayout m_StencilReference;
568
569 uint8_t m_NumColorAttachments;
570 uint8_t m_NumAttachmentDescriptions;
571
577 VkAttachmentDescription m_AttachmentDescriptions[MaxSimultaneousRenderTargets * 2 + 2];
578
579 // Do we have a depth stencil
580 uint8_t bHasDepthStencil;
581
582 VkRect2D m_RenderArea;
583 };
584
591 {
592 public:
593 inline VkRenderPass GetHandle() const { return m_RenderPass; }
594
595 inline const FVulkanRenderTargetLayout& GetLayout() const { return m_Layout; }
596
597 // May become private once we have FVulkanRenderPassManager
598
599 //FVulkanRenderPass() = default;
600
607
612
613 private:
614 VkRenderPass m_RenderPass;
616
617 FVulkanDevice& m_Device;
618 };
619
625 template <typename TSubpassDescriptionClass, typename TSubpassDependencyClass, typename TAttachmentReferenceClass, typename TAttachmentDescriptionClass, typename TRenderPassCreateInfoClass>
627 {
628 public:
635 : m_Device(InDevice)
636 {
637 }
638
645 {
646 uint32_t NumSubpasses = 0;
647 uint32_t NumDependencies = 0;
648
649 // Grab (and optionally convert) attachment references.
650 uint32_t NumColorAttachments = RTLayout.GetNumColorAttachments();
651
652 // Do we have a depth attachment
653 const bool bHasDepthStencilAttachmentReference = (RTLayout.GetDepthAttachmentReference() != nullptr);
654
655 // VkAttachmentDescription for color/depth attachments
656 for (uint32_t Attachment = 0; Attachment < RTLayout.GetNumAttachmentDescriptions(); ++Attachment)
657 {
658 /*if (bHasDepthStencilAttachmentReference && (Attachment == m_DepthStencilAttachmentReference.attachment))
659 {
660 //m_AttachmentDescriptions.Add(TAttachmentDescriptionClass(RTLayout.GetAttachmentDescriptions()[Attachment], RTLayout.GetStencilDescription(), false/*Device.SupportsParallelRendering()));
661 }
662 else*/
663 //{
664 m_AttachmentDescriptions.Add(TAttachmentDescriptionClass(RTLayout.GetAttachmentDescriptions()[Attachment]));
665 //}
666 }
667
668 // VkAttachmentReference for color attachments
669 for (uint32_t ColorAttachment = 0; ColorAttachment < NumColorAttachments; ++ColorAttachment)
670 {
671 m_ColorAttachmentReferences.Add(TAttachmentReferenceClass(RTLayout.GetColorAttachmentReferences()[ColorAttachment], 0));
672 }
673
674 // VkAttachmentReference for depth attachment
675 if (bHasDepthStencilAttachmentReference)
676 {
677 // For depth attachment reference, attachment and layout should also be given by GetDepthAttachmentReference only
678 m_DepthStencilAttachmentReference.SetDepthStencilAttachment(*RTLayout.GetDepthAttachmentReference(), RTLayout.GetStencilAttachmentReference(), 0, false/*m_Device.SupportsParallelRendering()*/);
679
680 // Why are these needed when attachment and layout are assigned in m_DepthStencilAttachmentReference
681 //m_DepthStencilAttachment.attachment = RTLayout.GetDepthAttachmentReference()->attachment;
682 //m_DepthStencilAttachment.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
683 }
684
685 // main subpass (using only single pass)
686 {
687 TSubpassDescriptionClass& SubpassDesc = m_SubpassDescriptions[NumSubpasses++];
688
689 SubpassDesc.SetColorAttachments(m_ColorAttachmentReferences, NumColorAttachments);
690
691 if (bHasDepthStencilAttachmentReference)
692 {
693 SubpassDesc.SetDepthStencilAttachment(&m_DepthStencilAttachmentReference);
694 }
695 }
696
697 // using single dependency (vulkancontext experimental)
698 TSubpassDependencyClass& SubpassDep = m_SubpassDependencies[NumDependencies++];
699 SubpassDep.srcSubpass = VK_SUBPASS_EXTERNAL;
700 SubpassDep.dstSubpass = 0;
701 SubpassDep.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
702 SubpassDep.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
703 SubpassDep.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
704 //SubpassDep.dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
705 SubpassDep.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
706
707 m_CreateInfo.attachmentCount = m_AttachmentDescriptions.Num();
708 m_CreateInfo.pAttachments = m_AttachmentDescriptions.GetData();
709 m_CreateInfo.subpassCount = NumSubpasses;
710 m_CreateInfo.pSubpasses = m_SubpassDescriptions;
711 m_CreateInfo.dependencyCount = NumDependencies;
712 m_CreateInfo.pDependencies = m_SubpassDependencies;
713 }
714
720 VkRenderPass Create(const FVulkanRenderTargetLayout& RTLayout)
721 {
722 BuildCreateInfo(RTLayout);
723
724 return m_CreateInfo.Create(m_Device);
725 }
726
727 private:
728 TSubpassDescriptionClass m_SubpassDescriptions[8];
729 TSubpassDependencyClass m_SubpassDependencies[8];
730
731 KarmaVector<TAttachmentReferenceClass> m_ColorAttachmentReferences;
732 KarmaVector<TAttachmentReferenceClass> m_ResolveAttachmentReferences;
733
734 KarmaVector<TAttachmentDescriptionClass> m_AttachmentDescriptions;
735
736 TAttachmentReferenceClass m_DepthStencilAttachmentReference;
737 TAttachmentReferenceClass m_DepthStencilAttachment;
738
739 TRenderPassCreateInfoClass m_CreateInfo;
740 FVulkanDevice& m_Device;
741 };
742
743 VkRenderPass CreateVulkanRenderPass(FVulkanDevice& Device, const FVulkanRenderTargetLayout& RTLayout);
744}
This file contains the macros for Karma's classes' general purpose use, including assertions and stor...
#define checkNoEntry()
Denotes code paths that should never be reached.
Definition Core.h:117
This file contains the class FMemory..
This file contains the custom types used in Engine's logic.
#define KR_CORE_INFO(...)
A macro for logging information in the Core part.
Definition Log.h:85
Declaration of the FVulkanDevice class for managing Vulkan device resources.
Manages Vulkan device resources and operations.
Definition VulkanDevice.h:33
VkDevice GetLogicalDevice() const
Retrieves the Vulkan logical device handle.
Definition VulkanDevice.h:84
FVulkanRenderPassBuilder(FVulkanDevice &InDevice)
Constructor.
Definition VulkanRenderPass.h:634
VkRenderPass Create(const FVulkanRenderTargetLayout &RTLayout)
Create the Vulkan renderpass.
Definition VulkanRenderPass.h:720
void BuildCreateInfo(const FVulkanRenderTargetLayout &RTLayout)
Build the VkRenderPassCreateInfo structure from the supplied FVulkanRenderTargetLayout.
Definition VulkanRenderPass.h:644
FVulkanRenderPass(FVulkanDevice &Device, const FVulkanRenderTargetLayout &RTLayout)
Constructor to create a renderpass with supplied rendertarget layout.
Definition VulkanRenderPass.cpp:58
~FVulkanRenderPass()
Destroys renderpass.
Definition VulkanRenderPass.cpp:64
Data structure for Vulkan's render targets (color buffers and depth buffer).
Definition VulkanRenderPass.h:535
FVulkanRenderTargetLayout()=default
Default constructor provided for FVulkanRenderPass class constructor.
Template (for VkSubpassDescription(2)) definition of FVulkanSubpassDescription.
Definition VulkanRenderPass.h:247
Karma's std::vector wrapper with additional functionalities.
Definition KarmaTypes.h:243
static FORCEINLINE void * Memzero(void *Dest, SIZE_T Count)
Zeros the Count number of characters of object pointed by Dest.
Definition KarmaMemory.h:134
FVulkanAttachmentDescription(const VkAttachmentDescription &InDesc)
Constructor to copy from VkAttachmentDescription.
Definition VulkanRenderPass.h:193
FVulkanAttachmentDescription(const VkAttachmentDescription &InDesc, const VkAttachmentDescriptionStencilLayout *InStencilDesc, bool bSupportsParallelRendering)
Seems like we are not supporting VkAttachmentDescriptionStencilLayout.
Definition VulkanRenderPass.h:213
FVulkanAttachmentDescription()
Default constructor to zero initialize the structure.
Definition VulkanRenderPass.h:181
Template (for VkAttachmentDescription(2)) definition of FVulkanAttachmentDescription.
Definition VulkanRenderPass.h:164
Template definition of FVulkanAttachmentReference with specializations done later.
Definition VulkanRenderPass.h:45
void SetAttachment(const VkAttachmentReference &AttachmentReferenceIn, VkImageAspectFlags AspectMask)
Disable method enforced here (checkNoEntry()).
Definition VulkanRenderPass.h:78
void SetDepthStencilAttachment(const VkAttachmentReference &AttachmentReferenceIn, const VkAttachmentReferenceStencilLayout *StencilReference, VkImageAspectFlags AspectMask, bool bSupportsParallelRendering)
Disable method enforced here (checkNoEntry()).
Definition VulkanRenderPass.h:96
FVulkanAttachmentReference(const VkAttachmentReference &AttachmentReferenceIn, VkImageAspectFlags AspectMask)
Constructor to copy from VkAttachmentReference.
Definition VulkanRenderPass.h:56
void SetAttachment(const FVulkanAttachmentReference< TAttachmentReferenceType > &AttachmentReferenceIn, VkImageAspectFlags AspectMask)
Template definition of SetAttachment (specialized out-of-class definition exists).
Definition VulkanRenderPass.h:85
void ZeroStruct()
Template definition for zero initialization. Specialized out-of-class definition exists.
Definition VulkanRenderPass.h:103
VkRenderPass Create(FVulkanDevice &Device)
Actual renderpass creation function.
Definition VulkanRenderPass.h:399
FVulkanRenderPassCreateInfo()
Constructor to initialize the renderpass create info structure.
Definition VulkanRenderPass.h:387
Template definition of FVulkanRenderPassCreateInfo for VkRenderPassCreateInfo(2).
Definition VulkanRenderPass.h:370
Information about a single attachment in the renderpass.
Definition VulkanRenderPass.h:438
VkSampleCountFlagBits AttachmentSampleCount
Attachment sample count.
Definition VulkanRenderPass.h:452
VkAttachmentStoreOp AttachmentStoreOperation
what to do with attachment data after rendering
Definition VulkanRenderPass.h:462
VkAttachmentLoadOp AttachmentLoadOperation
what to do with attachment data before rendering
Definition VulkanRenderPass.h:457
VkImageLayout AttachmentFinalLayout
Attachment layout at the end of renderpass.
Definition VulkanRenderPass.h:498
VkImageLayout AttachmentInitialLayout
Attachment layout before renderpass begins.
Definition VulkanRenderPass.h:493
VkFormat AttachmentFormat
Format of the attachment (color format VK_FORMAT_R8G8B8A8_UNORM for instance).
Definition VulkanRenderPass.h:447
VkAttachmentLoadOp AttachmentStencilLoadOperation
what to do with stencil data before rendering
Definition VulkanRenderPass.h:467
VkAttachmentDescriptionFlags AttachmentFlags
Attachment description flags.
Definition VulkanRenderPass.h:442
VkAttachmentStoreOp AttachmentStencilStoreOperation
what to do with stencil data after rendering
Definition VulkanRenderPass.h:472
Reference to an attachment in the renderpass.
Definition VulkanRenderPass.h:505
VkImageLayout layout
The variable specifies which layout we would like the attachment to have during a subpass that uses t...
Definition VulkanRenderPass.h:519
uint32_t attachment
The parameter specifies which attachment to reference by its index in the attachment descriptions arr...
Definition VulkanRenderPass.h:509
Data structure to hold information about Vulkan renderpass attachments (like color and depth attachme...
Definition VulkanRenderPass.h:433
FVulkanSubpassDependency()
Default constructor to zero initialize the structure.
Definition VulkanRenderPass.h:355
Template definition of FVulkanSubpassDependency.
Definition VulkanRenderPass.h:336
FVulkanSubpassDescription()
Default constructor to zero initialize the structure.
Definition VulkanRenderPass.h:264
void SetDepthStencilAttachment(FVulkanAttachmentReference< VkAttachmentReference > *DepthStencilAttachmentReference)
Set depth-stencil attachment for the subpass.
Definition VulkanRenderPass.h:300
void SetColorAttachments(const KarmaVector< FVulkanAttachmentReference< VkAttachmentReference > > &ColorAttachmentReferences, int OverrideCount=-1)
Set color attachments for the subpass.
Definition VulkanRenderPass.h:278