Overte C++ Documentation
VKFramebuffer.h
1 //
2 // Created by Bradley Austin Davis on 2016/08/07
3 // Adapted for Vulkan in 2022-2025 by dr Karol Suprynowicz.
4 // Copyright 2013-2018 High Fidelity, Inc.
5 // Copyright 2023-2025 Overte e.V.
6 //
7 // Distributed under the Apache License, Version 2.0.
8 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
9 // SPDX-License-Identifier: Apache-2.0
10 //
11 // Contains parts of Vulkan Samples, Copyright (c) 2018, Sascha Willems, distributed on MIT License.
12 
13 #ifndef hifi_gpu_vk_VKFramebuffer_h
14 #define hifi_gpu_vk_VKFramebuffer_h
15 
16 #include "VKShared.h"
17 #include "VKBackend.h"
18 
19 namespace gpu { namespace vk {
20 
21 class VKFramebuffer : public vk::VKObject<Framebuffer> {
22 public:
23  VkRenderPass vkRenderPass {VK_NULL_HANDLE};
24  VkFramebuffer vkFramebuffer {VK_NULL_HANDLE};
25 
26  static VKFramebuffer* sync(vk::VKBackend& backend, const Framebuffer& framebuffer) {
27  VKFramebuffer* object = Backend::getGPUObject<VKFramebuffer>(framebuffer);
28 
29  bool needsUpdate{ false };
30  if (!object ||
31  framebuffer.getDepthStamp() != object->_depthStamp ||
32  framebuffer.getColorStamps() != object->_colorStamps) {
33  needsUpdate = true;
34  }
35 
36  // If GPU object already created and in sync
37  if (!needsUpdate) {
38  return object;
39  } else if (framebuffer.isEmpty()) {
40  // NO framebuffer definition yet so let's avoid thinking
41  return nullptr;
42  }
43 
44  // need to have a gpu object?
45  if (!object) {
46  // All is green, assign the gpuobject to the Framebuffer
47  object = new VKFramebuffer(backend.shared_from_this(), framebuffer);
48  Backend::setGPUObject(framebuffer, object);
49  }
50 
51  object->update();
52  return object;
53  }
54 
55  Stamp _depthStamp { 0 };
56  std::vector<Stamp> _colorStamps;
57 
58  // From VKS
59  struct FramebufferAttachment
60  {
61  VkImage image;
62  VkDeviceMemory memory;
63  VkImageView view;
64  VkFormat format;
65  VkImageSubresourceRange subresourceRange;
66  VkAttachmentDescription description;
67 
71  bool hasDepth()
72  {
73  std::vector<VkFormat> formats =
74  {
75  VK_FORMAT_D16_UNORM,
76  VK_FORMAT_X8_D24_UNORM_PACK32,
77  VK_FORMAT_D32_SFLOAT,
78  VK_FORMAT_D16_UNORM_S8_UINT,
79  VK_FORMAT_D24_UNORM_S8_UINT,
80  VK_FORMAT_D32_SFLOAT_S8_UINT,
81  };
82  return std::find(formats.begin(), formats.end(), format) != std::end(formats);
83  }
84 
88  bool hasStencil()
89  {
90  std::vector<VkFormat> formats =
91  {
92  VK_FORMAT_S8_UINT,
93  VK_FORMAT_D16_UNORM_S8_UINT,
94  VK_FORMAT_D24_UNORM_S8_UINT,
95  VK_FORMAT_D32_SFLOAT_S8_UINT,
96  };
97  return std::find(formats.begin(), formats.end(), format) != std::end(formats);
98  }
99 
103  bool isDepthStencil()
104  {
105  return(hasDepth() || hasStencil());
106  }
107 
108  };
109 
110  // VKTODO: this can be removed in the future, it's redundant
111  std::vector<FramebufferAttachment> attachments;
112 
113 protected:
114 
115  virtual void update();
116  //bool checkStatus(FramebufferStatus target) const;
117  VkResult createFramebuffer();
118  struct VKAttachmentCreateInfo
119  {
120  uint32_t width, height;
121  uint32_t layerCount;
122  VkFormat format;
123  VkImageUsageFlags usage;
124  VkSampleCountFlagBits imageSampleCount = VK_SAMPLE_COUNT_1_BIT;
125  };
126  uint32_t addAttachment(VKAttachmentCreateInfo createinfo, VKTexture *texture);
127 
128  // VKTODO: We need a check on backend.lock(), or to pass backend reference instead
129  VKFramebuffer(const std::weak_ptr<vk::VKBackend>& backend, const Framebuffer& framebuffer) : VKObject(*backend.lock(), framebuffer) {}
130  // VKTODO: Do we need virtual destructor here?
131  ~VKFramebuffer() override;
132 
133 };
134 
135 } }
136 
137 
138 #endif