X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbackends%2Fvulkan%2Fframebuffer_backend.cpp;fp=source%2Fbackends%2Fvulkan%2Fframebuffer_backend.cpp;h=5b83c3db6b67e8be5c65acd31225ec64d8ec6ebf;hb=99ca354f18119f82f1adeca100cd665a8f640317;hp=0000000000000000000000000000000000000000;hpb=4cd245dafe6a7ee5c93edca5aee2d146f1155309;p=libs%2Fgl.git diff --git a/source/backends/vulkan/framebuffer_backend.cpp b/source/backends/vulkan/framebuffer_backend.cpp new file mode 100644 index 00000000..5b83c3db --- /dev/null +++ b/source/backends/vulkan/framebuffer_backend.cpp @@ -0,0 +1,111 @@ +#include +#include "device.h" +#include "framebuffer.h" +#include "framebuffer_backend.h" +#include "vulkan.h" + +using namespace std; + +namespace Msp { +namespace GL { + +VulkanFramebuffer::VulkanFramebuffer(bool): + device(Device::get_current()) +{ } + +VulkanFramebuffer::VulkanFramebuffer(VulkanFramebuffer &&other): + device(other.device), + handle(other.handle), + debug_name(move(other.debug_name)) +{ + other.handle = 0; +} + +VulkanFramebuffer::~VulkanFramebuffer() +{ + if(handle) + device.get_destroy_queue().destroy(handle); +} + +bool VulkanFramebuffer::is_format_supported(const FrameFormat &fmt) +{ + const VulkanFunctions &vk = device.get_functions(); + for(FrameAttachment a: fmt) + { + PixelFormat pf = get_attachment_pixelformat(a); + PixelComponents comp = get_components(pf); + VkFormatProperties props; + vk.GetPhysicalDeviceFormatProperties(static_cast(get_vulkan_pixelformat(pf)), props); + if(comp==DEPTH_COMPONENT || comp==STENCIL_INDEX) + { + if(!(props.optimalTilingFeatures&VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) + return false; + } + else if(!(props.optimalTilingFeatures&VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT)) + return false; + } + + return true; +} + +void VulkanFramebuffer::update(unsigned) const +{ + const Framebuffer &self = *static_cast(this); + const VulkanFunctions &vk = device.get_functions(); + + if(handle) + device.get_destroy_queue().destroy(handle); + + VkImageView vk_attachments[FrameFormat::MAX_ATTACHMENTS] = { }; + unsigned i = 0; + for(const Framebuffer::Attachment &a: self.attachments) + { + if(a.tex->view_type!=VK_IMAGE_VIEW_TYPE_2D || a.level || a.layer) + throw logic_error("Unimplemented texture type in VulkanFramebuffer::update"); + vk_attachments[i++] = a.tex->view_handle; + } + + VkRenderPass render_pass = device.get_pipeline_cache().get_render_pass(self.format, false, false); + + VkFramebufferCreateInfo framebuffer_info = { }; + framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + framebuffer_info.renderPass = handle_cast<::VkRenderPass>(render_pass); + framebuffer_info.attachmentCount = self.format.size(); + framebuffer_info.pAttachments = handle_cast<::VkImageView *>(vk_attachments); + framebuffer_info.width = self.width; + framebuffer_info.height = self.height; + framebuffer_info.layers = 1; + + vk.CreateFramebuffer(framebuffer_info, handle); + + if(!debug_name.empty()) + set_vulkan_object_name(); +} + +void VulkanFramebuffer::set_debug_name(const string &name) +{ +#ifdef DEBUG + debug_name = name; + if(handle) + set_vulkan_object_name(); +#else + (void)name; +#endif +} + +void VulkanFramebuffer::set_vulkan_object_name() const +{ +#ifdef DEBUG + const VulkanFunctions &vk = device.get_functions(); + + VkDebugUtilsObjectNameInfoEXT name_info = { }; + name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + name_info.objectType = VK_OBJECT_TYPE_FRAMEBUFFER; + name_info.objectHandle = reinterpret_cast(handle); + name_info.pObjectName = debug_name.c_str(); + vk.SetDebugUtilsObjectName(name_info); +#endif +} + +} // namespace GL +} // namespace Msp