From f7ccec2bcc84d10eb43b1ccbc8661328831778a9 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 18 Sep 2023 13:45:53 +0200 Subject: [PATCH] Vulkan: Fix Generate Mipmaps for Array Textures Array textures stores the array length inside the size of the image. In vulkan the size mustn't contain the array length, but it should be set as a separate parameter. This logic wasn't implemented when updating the mipmap chain. Patch also includes some smaller fixes where textures would not yet be allocated on the device, but was expected to be. Pull Request: https://projects.blender.org/blender/blender/pulls/112518 --- .../blender/gpu/vulkan/vk_descriptor_set.cc | 1 + source/blender/gpu/vulkan/vk_framebuffer.cc | 1 + source/blender/gpu/vulkan/vk_texture.cc | 21 ++++++++++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/source/blender/gpu/vulkan/vk_descriptor_set.cc b/source/blender/gpu/vulkan/vk_descriptor_set.cc index cceef036260..5b6c400bb5f 100644 --- a/source/blender/gpu/vulkan/vk_descriptor_set.cc +++ b/source/blender/gpu/vulkan/vk_descriptor_set.cc @@ -181,6 +181,7 @@ void VKDescriptorSetTracker::update(VKContext &context) } /* TODO: Based on the actual usage we should use * VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL/VK_IMAGE_LAYOUT_GENERAL. */ + binding.texture->ensure_allocated(); binding.texture->layout_ensure(context, VK_IMAGE_LAYOUT_GENERAL); VkDescriptorImageInfo image_info = {}; image_info.sampler = binding.vk_sampler; diff --git a/source/blender/gpu/vulkan/vk_framebuffer.cc b/source/blender/gpu/vulkan/vk_framebuffer.cc index cc9a7312b29..159d033c658 100644 --- a/source/blender/gpu/vulkan/vk_framebuffer.cc +++ b/source/blender/gpu/vulkan/vk_framebuffer.cc @@ -493,6 +493,7 @@ void VKFrameBuffer::color_attachment_layout_ensure(VKContext &context, return; } + color_texture->ensure_allocated(); color_texture->layout_ensure(context, requested_layout); dirty_attachments_ = true; } diff --git a/source/blender/gpu/vulkan/vk_texture.cc b/source/blender/gpu/vulkan/vk_texture.cc index 35e924af5b3..7291758e7f3 100644 --- a/source/blender/gpu/vulkan/vk_texture.cc +++ b/source/blender/gpu/vulkan/vk_texture.cc @@ -61,6 +61,19 @@ void VKTexture::generate_mipmap() mip_size_get(src_mipmap, src_size); mip_size_get(dst_mipmap, dst_size); + /* GPU Texture stores the array length in the first unused dimension size. + * Vulkan uses layers and the array length should be removed from the dimensions. */ + if (ELEM(this->type_get(), GPU_TEXTURE_1D_ARRAY)) { + src_size.y = 1; + src_size.z = 1; + dst_size.y = 1; + dst_size.z = 1; + } + if (ELEM(this->type_get(), GPU_TEXTURE_2D_ARRAY)) { + src_size.z = 1; + dst_size.z = 1; + } + layout_ensure(context, IndexRange(src_mipmap, 1), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, @@ -362,6 +375,7 @@ bool VKTexture::init_internal(GPUTexture *src, int mip_offset, int layer_offset, VKTexture *texture = unwrap(unwrap(src)); source_texture_ = texture; mip_min_ = mip_offset; + mip_max_ = mip_offset; layer_offset_ = layer_offset; use_stencil_ = use_stencil; flags_ |= IMAGE_VIEW_DIRTY; @@ -376,7 +390,11 @@ bool VKTexture::is_texture_view() const void VKTexture::ensure_allocated() { - BLI_assert(!is_texture_view()); + if (is_texture_view()) { + source_texture_->ensure_allocated(); + return; + } + if (!is_allocated()) { allocate(); } @@ -563,6 +581,7 @@ void VKTexture::layout_ensure(VKContext &context, const VkImageLayout current_layout, const VkImageLayout requested_layout) { + BLI_assert(vk_image_ != VK_NULL_HANDLE); VkImageMemoryBarrier barrier{}; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.oldLayout = current_layout;