1 #include <msp/strings/format.h>
3 #include "framebuffer.h"
4 #include "framebuffer_backend.h"
5 #include "renderpass.h"
13 VulkanFramebuffer::VulkanFramebuffer(bool):
14 device(Device::get_current())
17 VulkanFramebuffer::VulkanFramebuffer(VulkanFramebuffer &&other):
20 debug_name(move(other.debug_name))
25 VulkanFramebuffer::~VulkanFramebuffer()
27 DestroyQueue &dq = device.get_destroy_queue();
30 for(VkImageView h: view_handles)
35 bool VulkanFramebuffer::is_format_supported(const FrameFormat &fmt)
37 const VulkanFunctions &vk = device.get_functions();
38 for(FrameAttachment a: fmt)
40 PixelFormat pf = get_attachment_pixelformat(a);
41 PixelComponents comp = get_components(pf);
42 VkFormatProperties props;
43 vk.GetPhysicalDeviceFormatProperties(static_cast<VkFormat>(get_vulkan_pixelformat(pf)), props);
44 if(comp==DEPTH_COMPONENT || comp==STENCIL_INDEX)
46 if(!(props.optimalTilingFeatures&VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
49 else if(!(props.optimalTilingFeatures&VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT))
56 void VulkanFramebuffer::update(unsigned mask) const
58 const Framebuffer &self = *static_cast<const Framebuffer *>(this);
59 const VulkanFunctions &vk = device.get_functions();
61 if(self.attachments.size()>view_handles.size())
62 view_handles.resize(self.attachments.size());
65 device.get_destroy_queue().destroy(handle);
67 VkImageView vk_attachments[FrameFormat::MAX_ATTACHMENTS] = { };
69 for(const Framebuffer::Attachment &a: self.attachments)
71 bool use_tex_view = (a.tex->view_type==VK_IMAGE_VIEW_TYPE_2D || (a.tex->view_type==VK_IMAGE_VIEW_TYPE_2D_ARRAY && a.layer<0));
76 a.tex->refresh_mip_views();
80 device.get_destroy_queue().destroy(view_handles[i]);
82 PixelFormat tex_format = a.tex->get_format();
84 VkImageViewCreateInfo view_info = { };
85 view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
86 view_info.image = handle_cast<::VkImage>(a.tex->handle);
87 view_info.viewType = (a.layer<0 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D);
88 view_info.format = static_cast<VkFormat>(get_vulkan_pixelformat(tex_format));
90 view_info.components.r = VK_COMPONENT_SWIZZLE_R;
91 view_info.components.g = VK_COMPONENT_SWIZZLE_G;
92 view_info.components.b = VK_COMPONENT_SWIZZLE_B;
93 view_info.components.a = VK_COMPONENT_SWIZZLE_A;
95 view_info.subresourceRange.aspectMask = get_vulkan_aspect(get_components(tex_format));
96 view_info.subresourceRange.baseMipLevel = a.level;
97 view_info.subresourceRange.levelCount = 1;
98 view_info.subresourceRange.baseArrayLayer = max(a.layer, 0);
99 view_info.subresourceRange.layerCount = (a.layer<0 ? VK_REMAINING_ARRAY_LAYERS : 1);
101 vk.CreateImageView(view_info, view_handles[i]);
106 vk_attachments[i] = a.tex->mip_view_handles[a.level];
107 else if(view_handles[i])
108 vk_attachments[i] = view_handles[i];
110 throw logic_error("unexpected framebuffer configuration");
115 RenderPass render_pass;
116 render_pass.framebuffer = &self;
117 render_pass.update(device);
119 VkFramebufferCreateInfo framebuffer_info = { };
120 framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
121 framebuffer_info.renderPass = handle_cast<::VkRenderPass>(render_pass.handle);
122 framebuffer_info.attachmentCount = self.format.size();
123 framebuffer_info.pAttachments = handle_cast<::VkImageView *>(vk_attachments);
124 framebuffer_info.width = self.width;
125 framebuffer_info.height = self.height;
126 framebuffer_info.layers = self.layers;
128 vk.CreateFramebuffer(framebuffer_info, handle);
130 if(!debug_name.empty())
131 set_vulkan_object_name();
134 void VulkanFramebuffer::prepare_image_layouts(bool discard) const
136 for(const Framebuffer::Attachment &a: static_cast<const Framebuffer *>(this)->attachments)
137 a.tex->change_layout(a.level, get_vulkan_attachment_layout(get_components(a.tex->get_format())), (discard && a.layer<0));
140 void VulkanFramebuffer::set_debug_name(const string &name)
145 set_vulkan_object_name();
151 void VulkanFramebuffer::set_vulkan_object_name() const
154 const VulkanFunctions &vk = device.get_functions();
156 VkDebugUtilsObjectNameInfoEXT name_info = { };
157 name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
158 name_info.objectType = VK_OBJECT_TYPE_FRAMEBUFFER;
159 name_info.objectHandle = reinterpret_cast<uint64_t>(handle);
160 name_info.pObjectName = debug_name.c_str();
161 vk.SetDebugUtilsObjectName(name_info);