X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbackends%2Fvulkan%2Fframebuffer_backend.cpp;h=48b25f2ac456dec0e1816308cd16ac2916839804;hb=d98d835a6359844efcbc13b18ea6c93ace117359;hp=5b83c3db6b67e8be5c65acd31225ec64d8ec6ebf;hpb=99ca354f18119f82f1adeca100cd665a8f640317;p=libs%2Fgl.git diff --git a/source/backends/vulkan/framebuffer_backend.cpp b/source/backends/vulkan/framebuffer_backend.cpp index 5b83c3db..48b25f2a 100644 --- a/source/backends/vulkan/framebuffer_backend.cpp +++ b/source/backends/vulkan/framebuffer_backend.cpp @@ -23,8 +23,12 @@ VulkanFramebuffer::VulkanFramebuffer(VulkanFramebuffer &&other): VulkanFramebuffer::~VulkanFramebuffer() { + DestroyQueue &dq = device.get_destroy_queue(); if(handle) - device.get_destroy_queue().destroy(handle); + dq.destroy(handle); + for(VkImageView h: view_handles) + if(h) + dq.destroy(h); } bool VulkanFramebuffer::is_format_supported(const FrameFormat &fmt) @@ -48,11 +52,14 @@ bool VulkanFramebuffer::is_format_supported(const FrameFormat &fmt) return true; } -void VulkanFramebuffer::update(unsigned) const +void VulkanFramebuffer::update(unsigned mask) const { const Framebuffer &self = *static_cast(this); const VulkanFunctions &vk = device.get_functions(); + if(self.attachments.size()>view_handles.size()) + view_handles.resize(self.attachments.size()); + if(handle) device.get_destroy_queue().destroy(handle); @@ -60,12 +67,51 @@ void VulkanFramebuffer::update(unsigned) const 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; + 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)); + + if(mask&(1<refresh_mip_views(); + else + { + if(view_handles[i]) + device.get_destroy_queue().destroy(view_handles[i]); + + PixelFormat tex_format = a.tex->get_format(); + + VkImageViewCreateInfo view_info = { }; + view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + view_info.image = handle_cast<::VkImage>(a.tex->handle); + view_info.viewType = (a.layer<0 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D); + view_info.format = static_cast(get_vulkan_pixelformat(tex_format)); + + view_info.components.r = VK_COMPONENT_SWIZZLE_R; + view_info.components.g = VK_COMPONENT_SWIZZLE_G; + view_info.components.b = VK_COMPONENT_SWIZZLE_B; + view_info.components.a = VK_COMPONENT_SWIZZLE_A; + + view_info.subresourceRange.aspectMask = get_vulkan_aspect(get_components(tex_format)); + view_info.subresourceRange.baseMipLevel = a.level; + view_info.subresourceRange.levelCount = 1; + view_info.subresourceRange.baseArrayLayer = max(a.layer, 0); + view_info.subresourceRange.layerCount = (a.layer<0 ? VK_REMAINING_ARRAY_LAYERS : 1); + + vk.CreateImageView(view_info, view_handles[i]); + } + } + + if(use_tex_view) + vk_attachments[i] = a.tex->mip_view_handles[a.level]; + else if(view_handles[i]) + vk_attachments[i] = view_handles[i]; + else + throw logic_error("unexpected framebuffer configuration"); + + ++i; } - VkRenderPass render_pass = device.get_pipeline_cache().get_render_pass(self.format, false, false); + VkRenderPass render_pass = device.get_pipeline_cache().get_render_pass(self.format, false, false, false); VkFramebufferCreateInfo framebuffer_info = { }; framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; @@ -74,7 +120,7 @@ void VulkanFramebuffer::update(unsigned) const framebuffer_info.pAttachments = handle_cast<::VkImageView *>(vk_attachments); framebuffer_info.width = self.width; framebuffer_info.height = self.height; - framebuffer_info.layers = 1; + framebuffer_info.layers = self.layers; vk.CreateFramebuffer(framebuffer_info, handle); @@ -82,6 +128,12 @@ void VulkanFramebuffer::update(unsigned) const set_vulkan_object_name(); } +void VulkanFramebuffer::prepare_image_layouts(bool discard) const +{ + for(const Framebuffer::Attachment &a: static_cast(this)->attachments) + a.tex->change_layout(a.level, get_vulkan_attachment_layout(get_components(a.tex->get_format())), (discard && a.layer<0)); +} + void VulkanFramebuffer::set_debug_name(const string &name) { #ifdef DEBUG