X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;ds=sidebyside;f=source%2Fbackends%2Fvulkan%2Ftexture_backend.cpp;h=db420991ee1ebf17861c8b26c6aa4666f49b93fd;hb=295a0851bd3bcfba75c3e6a94b63cd8f5ee4ea53;hp=dd19c63664b88658fe06917798742bbcbb4fd2f5;hpb=7b0a38db12c3d1aacb59520a3f4baa16d9ec0048;p=libs%2Fgl.git diff --git a/source/backends/vulkan/texture_backend.cpp b/source/backends/vulkan/texture_backend.cpp index dd19c636..db420991 100644 --- a/source/backends/vulkan/texture_backend.cpp +++ b/source/backends/vulkan/texture_backend.cpp @@ -1,3 +1,4 @@ +#include #include "device.h" #include "error.h" #include "synchronizer.h" @@ -34,6 +35,11 @@ VulkanTexture::~VulkanTexture() if(view_handle) dq.destroy(view_handle); + if(mip_view_handles.size()>1) + { + for(VkImageView i: mip_view_handles) + dq.destroy(i); + } if(handle) dq.destroy(handle, memory_id); } @@ -43,13 +49,17 @@ void VulkanTexture::allocate() const Texture &self = *static_cast(this); const VulkanFunctions &vk = device.get_functions(); + VkFormat vk_format = static_cast(get_vulkan_pixelformat(self.storage_fmt)); + VkFormatProperties props; + vk.GetPhysicalDeviceFormatProperties(vk_format, props); + VkImageCreateInfo image_info = { }; image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - image_info.format = static_cast(get_vulkan_pixelformat(self.storage_fmt)); + image_info.format = vk_format; image_info.extent.width = 1; image_info.extent.height = 1; image_info.extent.depth = 1; - image_info.mipLevels = 1; + image_info.mipLevels = self.n_levels; image_info.arrayLayers = 1; image_info.samples = VK_SAMPLE_COUNT_1_BIT; image_info.tiling = VK_IMAGE_TILING_OPTIMAL; @@ -57,6 +67,7 @@ void VulkanTexture::allocate() image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; image_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT; + PixelComponents comp = get_components(self.storage_fmt); if(comp==DEPTH_COMPONENT || comp==STENCIL_INDEX) image_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; @@ -65,6 +76,9 @@ void VulkanTexture::allocate() fill_image_info(&image_info); + if((props.optimalTilingFeatures&VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) && image_info.samples==VK_SAMPLE_COUNT_1_BIT) + image_info.usage |= VK_IMAGE_USAGE_STORAGE_BIT; + /* SwapChainTexture may have already provided the image. Create_info is filled anyway because some of its fields are used for view_info. */ if(!handle) @@ -73,14 +87,25 @@ void VulkanTexture::allocate() memory_id = device.get_allocator().allocate(handle, DEVICE_MEMORY); // Trigger a layout transition if the image is used before uploading data. - change_layout(0, -1, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true); + change_layout(-1, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true); } + view_handle = create_view(-1); + + if(!debug_name.empty()) + set_vulkan_object_names(); +} + +VkImageView VulkanTexture::create_view(int level) const +{ + const Texture &self = *static_cast(this); + const VulkanFunctions &vk = device.get_functions(); + VkImageViewCreateInfo view_info = { }; view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; view_info.image = handle_cast<::VkImage>(handle); view_info.viewType = static_cast(view_type); - view_info.format = image_info.format; + view_info.format = static_cast(get_vulkan_pixelformat(self.storage_fmt)); const unsigned *swizzle_order = get_vulkan_swizzle(self.swizzle); view_info.components.r = static_cast(swizzle_order[0]); @@ -89,69 +114,51 @@ void VulkanTexture::allocate() view_info.components.a = static_cast(swizzle_order[3]); view_info.subresourceRange.aspectMask = get_vulkan_aspect(get_components(self.storage_fmt)); - view_info.subresourceRange.baseMipLevel = 0; - view_info.subresourceRange.levelCount = image_info.mipLevels; + view_info.subresourceRange.baseMipLevel = max(level, 0); + view_info.subresourceRange.levelCount = (level<0 ? VK_REMAINING_MIP_LEVELS : 1); view_info.subresourceRange.baseArrayLayer = 0; - view_info.subresourceRange.layerCount = image_info.arrayLayers; + view_info.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; - vk.CreateImageView(view_info, view_handle); + VkImageView view; + vk.CreateImageView(view_info, view); - if(!debug_name.empty()) - set_vulkan_object_names(); + return view; } -void VulkanTexture::stage_pixels(void *staging, const void *data, size_t count) +void VulkanTexture::create_mip_views() const { const Texture &self = *static_cast(this); - if(self.swizzle==RGBA_TO_RGB) - { - const uint32_t *src = static_cast(data); - uint32_t *dst = static_cast(staging); - size_t i = 0; - for(; i+3>24)|(src[1]<<8)|0xFF000000; - dst[2] = (src[1]>>16)|(src[2]<<16)|0xFF000000; - dst[3] = (src[2]>>8)|0xFF000000; - src += 3; - dst += 4; - } - - if(i(src); - for(; i(data); - size_t data_size = count*get_pixel_size(self.storage_fmt); - copy(src, src+data_size, static_cast(staging)); + for(unsigned i=0; i(this)->n_levels; + TransferQueue &tq = device.get_transfer_queue(); for(unsigned i=0; i+1(this); VkImageBlit region = { }; - region.srcSubresource.aspectMask = get_vulkan_aspect(get_components(static_cast(this)->storage_fmt)); + region.srcSubresource.aspectMask = get_vulkan_aspect(get_components(self.storage_fmt)); region.srcSubresource.mipLevel = i; region.srcSubresource.baseArrayLayer = 0; region.srcSubresource.layerCount = 1; @@ -160,17 +167,19 @@ void VulkanTexture::generate_mipmap_levels(unsigned n_levels) fill_mipmap_blit(i, ®ion); - vk.CmdBlitImage(cmd_buf, handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + vkCmd.BlitImage(handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion, VK_FILTER_LINEAR); }); } } -void VulkanTexture::change_layout(unsigned n_levels, int level, unsigned layout, bool discard) const +void VulkanTexture::change_layout(int level, unsigned layout, bool discard) const { - unsigned aspect = get_vulkan_aspect(get_components(static_cast(this)->storage_fmt)); - if(n_levels>0) - device.get_synchronizer().split_image_mipmap(handle, aspect, n_levels); + const Texture &self = *static_cast(this); + + unsigned aspect = get_vulkan_aspect(get_components(self.storage_fmt)); + if(level>=0) + device.get_synchronizer().split_image_mipmap(handle, aspect, self.n_levels); device.get_synchronizer().change_image_layout(handle, aspect, level, layout, discard); } @@ -202,6 +211,17 @@ void VulkanTexture::set_vulkan_object_names() const name_info.objectHandle = reinterpret_cast(view_handle); name_info.pObjectName = view_name.c_str(); vk.SetDebugUtilsObjectName(name_info); + + if(mip_view_handles.size()>1) + { + for(unsigned i=0; i(mip_view_handles[i]); + name_info.pObjectName = view_name.c_str(); + vk.SetDebugUtilsObjectName(name_info); + } + } #endif }