]> git.tdb.fi Git - libs/gl.git/blob - source/backends/vulkan/framebuffer_backend.cpp
Implement textures and samplers for Vulkan
[libs/gl.git] / source / backends / vulkan / framebuffer_backend.cpp
1 #include <msp/strings/format.h>
2 #include "device.h"
3 #include "framebuffer.h"
4 #include "framebuffer_backend.h"
5 #include "vulkan.h"
6
7 using namespace std;
8
9 namespace Msp {
10 namespace GL {
11
12 VulkanFramebuffer::VulkanFramebuffer(bool):
13         device(Device::get_current())
14 { }
15
16 VulkanFramebuffer::VulkanFramebuffer(VulkanFramebuffer &&other):
17         device(other.device),
18         handle(other.handle),
19         debug_name(move(other.debug_name))
20 {
21         other.handle = 0;
22 }
23
24 VulkanFramebuffer::~VulkanFramebuffer()
25 {
26         if(handle)
27                 device.get_destroy_queue().destroy(handle);
28 }
29
30 bool VulkanFramebuffer::is_format_supported(const FrameFormat &fmt)
31 {
32         const VulkanFunctions &vk = device.get_functions();
33         for(FrameAttachment a: fmt)
34         {
35                 PixelFormat pf = get_attachment_pixelformat(a);
36                 PixelComponents comp = get_components(pf);
37                 VkFormatProperties props;
38                 vk.GetPhysicalDeviceFormatProperties(static_cast<VkFormat>(get_vulkan_pixelformat(pf)), props);
39                 if(comp==DEPTH_COMPONENT || comp==STENCIL_INDEX)
40                 {
41                         if(!(props.optimalTilingFeatures&VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
42                                 return false;
43                 }
44                 else if(!(props.optimalTilingFeatures&VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT))
45                         return false;
46         }
47
48         return true;
49 }
50
51 void VulkanFramebuffer::update(unsigned) const
52 {
53         const Framebuffer &self = *static_cast<const Framebuffer *>(this);
54         const VulkanFunctions &vk = device.get_functions();
55
56         if(handle)
57                 device.get_destroy_queue().destroy(handle);
58
59         VkImageView vk_attachments[FrameFormat::MAX_ATTACHMENTS] = { };
60         unsigned i = 0;
61         for(const Framebuffer::Attachment &a: self.attachments)
62         {
63                 if(a.tex->view_type!=VK_IMAGE_VIEW_TYPE_2D || a.level || a.layer)
64                         throw logic_error("Unimplemented texture type in VulkanFramebuffer::update");
65                 vk_attachments[i++] = a.tex->view_handle;
66         }
67
68         VkRenderPass render_pass = device.get_pipeline_cache().get_render_pass(self.format, false, false, false);
69
70         VkFramebufferCreateInfo framebuffer_info = { };
71         framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
72         framebuffer_info.renderPass = handle_cast<::VkRenderPass>(render_pass);
73         framebuffer_info.attachmentCount = self.format.size();
74         framebuffer_info.pAttachments = handle_cast<::VkImageView *>(vk_attachments);
75         framebuffer_info.width = self.width;
76         framebuffer_info.height = self.height;
77         framebuffer_info.layers = 1;
78
79         vk.CreateFramebuffer(framebuffer_info, handle);
80
81         if(!debug_name.empty())
82                 set_vulkan_object_name();
83 }
84
85 void VulkanFramebuffer::synchronize(bool discard) const
86 {
87         for(const Framebuffer::Attachment &a: static_cast<const Framebuffer *>(this)->attachments)
88                 a.tex->synchronize(a.layer, get_vulkan_attachment_layout(get_components(a.tex->get_format())), discard);
89 }
90
91 void VulkanFramebuffer::set_debug_name(const string &name)
92 {
93 #ifdef DEBUG
94         debug_name = name;
95         if(handle)
96                 set_vulkan_object_name();
97 #else
98         (void)name;
99 #endif
100 }
101
102 void VulkanFramebuffer::set_vulkan_object_name() const
103 {
104 #ifdef DEBUG
105         const VulkanFunctions &vk = device.get_functions();
106
107         VkDebugUtilsObjectNameInfoEXT name_info = { };
108         name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
109         name_info.objectType = VK_OBJECT_TYPE_FRAMEBUFFER;
110         name_info.objectHandle = reinterpret_cast<uint64_t>(handle);
111         name_info.pObjectName = debug_name.c_str();
112         vk.SetDebugUtilsObjectName(name_info);
113 #endif
114 }
115
116 } // namespace GL
117 } // namespace Msp