1 #include <msp/strings/format.h>
3 #include "framebuffer.h"
4 #include "framebuffer_backend.h"
12 VulkanFramebuffer::VulkanFramebuffer(bool):
13 device(Device::get_current())
16 VulkanFramebuffer::VulkanFramebuffer(VulkanFramebuffer &&other):
19 debug_name(move(other.debug_name))
24 VulkanFramebuffer::~VulkanFramebuffer()
26 DestroyQueue &dq = device.get_destroy_queue();
29 for(VkImageView h: view_handles)
34 bool VulkanFramebuffer::is_format_supported(const FrameFormat &fmt)
36 const VulkanFunctions &vk = device.get_functions();
37 for(FrameAttachment a: fmt)
39 PixelFormat pf = get_attachment_pixelformat(a);
40 PixelComponents comp = get_components(pf);
41 VkFormatProperties props;
42 vk.GetPhysicalDeviceFormatProperties(static_cast<VkFormat>(get_vulkan_pixelformat(pf)), props);
43 if(comp==DEPTH_COMPONENT || comp==STENCIL_INDEX)
45 if(!(props.optimalTilingFeatures&VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
48 else if(!(props.optimalTilingFeatures&VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT))
55 void VulkanFramebuffer::update(unsigned mask) const
57 const Framebuffer &self = *static_cast<const Framebuffer *>(this);
58 const VulkanFunctions &vk = device.get_functions();
60 if(self.attachments.size()>view_handles.size())
61 view_handles.resize(self.attachments.size());
64 device.get_destroy_queue().destroy(handle);
66 VkImageView vk_attachments[FrameFormat::MAX_ATTACHMENTS] = { };
68 for(const Framebuffer::Attachment &a: self.attachments)
70 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));
75 a.tex->refresh_mip_views();
79 device.get_destroy_queue().destroy(view_handles[i]);
81 PixelFormat tex_format = a.tex->get_format();
83 VkImageViewCreateInfo view_info = { };
84 view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
85 view_info.image = handle_cast<::VkImage>(a.tex->handle);
86 view_info.viewType = (a.layer<0 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D);
87 view_info.format = static_cast<VkFormat>(get_vulkan_pixelformat(tex_format));
89 view_info.components.r = VK_COMPONENT_SWIZZLE_R;
90 view_info.components.g = VK_COMPONENT_SWIZZLE_G;
91 view_info.components.b = VK_COMPONENT_SWIZZLE_B;
92 view_info.components.a = VK_COMPONENT_SWIZZLE_A;
94 view_info.subresourceRange.aspectMask = get_vulkan_aspect(get_components(tex_format));
95 view_info.subresourceRange.baseMipLevel = a.level;
96 view_info.subresourceRange.levelCount = 1;
97 view_info.subresourceRange.baseArrayLayer = max(a.layer, 0);
98 view_info.subresourceRange.layerCount = (a.layer<0 ? VK_REMAINING_ARRAY_LAYERS : 1);
100 vk.CreateImageView(view_info, view_handles[i]);
105 vk_attachments[i] = a.tex->mip_view_handles[a.level];
106 else if(view_handles[i])
107 vk_attachments[i] = view_handles[i];
109 throw logic_error("unexpected framebuffer configuration");
114 VkRenderPass render_pass = device.get_pipeline_cache().get_render_pass(self.format, false, false, false);
116 VkFramebufferCreateInfo framebuffer_info = { };
117 framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
118 framebuffer_info.renderPass = handle_cast<::VkRenderPass>(render_pass);
119 framebuffer_info.attachmentCount = self.format.size();
120 framebuffer_info.pAttachments = handle_cast<::VkImageView *>(vk_attachments);
121 framebuffer_info.width = self.width;
122 framebuffer_info.height = self.height;
123 framebuffer_info.layers = self.layers;
125 vk.CreateFramebuffer(framebuffer_info, handle);
127 if(!debug_name.empty())
128 set_vulkan_object_name();
131 void VulkanFramebuffer::prepare_image_layouts(bool discard) const
133 for(const Framebuffer::Attachment &a: static_cast<const Framebuffer *>(this)->attachments)
134 a.tex->change_layout(a.level, get_vulkan_attachment_layout(get_components(a.tex->get_format())), (discard && a.layer<0));
137 void VulkanFramebuffer::set_debug_name(const string &name)
142 set_vulkan_object_name();
148 void VulkanFramebuffer::set_vulkan_object_name() const
151 const VulkanFunctions &vk = device.get_functions();
153 VkDebugUtilsObjectNameInfoEXT name_info = { };
154 name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
155 name_info.objectType = VK_OBJECT_TYPE_FRAMEBUFFER;
156 name_info.objectHandle = reinterpret_cast<uint64_t>(handle);
157 name_info.pObjectName = debug_name.c_str();
158 vk.SetDebugUtilsObjectName(name_info);