From f82e89183e688b0a2723c3bb38bfd671a772ee4e Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 26 Aug 2025 14:18:47 +0200 Subject: [PATCH] Fix #142110: Vulkan: Only last planar probe is visible When using multiple planar probes only the last one would be visible. The other probes would use the world probe. Reason is that the data of planar probes are stored in layered textures. When updating planar probes framebuffers are created with the correct layer attached. Vulkan backend missed some code paths to clear a single layer when clearing a framebuffer where the previous action had depth write disabled. This PR adds the missing code path. Pull Request: https://projects.blender.org/blender/blender/pulls/145170 --- source/blender/gpu/intern/gpu_framebuffer_private.hh | 11 ++++++++--- source/blender/gpu/vulkan/vk_framebuffer.cc | 9 +++++++-- source/blender/gpu/vulkan/vk_texture.cc | 9 +++++++-- source/blender/gpu/vulkan/vk_texture.hh | 3 ++- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/source/blender/gpu/intern/gpu_framebuffer_private.hh b/source/blender/gpu/intern/gpu_framebuffer_private.hh index 35c8051aa4e..2f91e397db8 100644 --- a/source/blender/gpu/intern/gpu_framebuffer_private.hh +++ b/source/blender/gpu/intern/gpu_framebuffer_private.hh @@ -230,12 +230,17 @@ class FrameBuffer { scissor_set(scissor_rect); } - blender::gpu::Texture *depth_tex() const + inline const GPUAttachment &depth_attachment() const { if (attachments_[GPU_FB_DEPTH_ATTACHMENT].tex) { - return attachments_[GPU_FB_DEPTH_ATTACHMENT].tex; + return attachments_[GPU_FB_DEPTH_ATTACHMENT]; } - return attachments_[GPU_FB_DEPTH_STENCIL_ATTACHMENT].tex; + return attachments_[GPU_FB_DEPTH_STENCIL_ATTACHMENT]; + } + + blender::gpu::Texture *depth_tex() const + { + return depth_attachment().tex; }; blender::gpu::Texture *color_tex(int slot) const diff --git a/source/blender/gpu/vulkan/vk_framebuffer.cc b/source/blender/gpu/vulkan/vk_framebuffer.cc index f1552458178..6f2ac160d09 100644 --- a/source/blender/gpu/vulkan/vk_framebuffer.cc +++ b/source/blender/gpu/vulkan/vk_framebuffer.cc @@ -198,9 +198,14 @@ void VKFrameBuffer::clear(const eGPUFrameBufferBits buffers, buffers, clear_depth, clear_stencil, clear_attachments); } else { - VKTexture *depth_texture = unwrap(unwrap(depth_tex())); + const GPUAttachment &attachment = depth_attachment(); + VKTexture *depth_texture = unwrap(unwrap(attachment.tex)); if (depth_texture != nullptr) { - depth_texture->clear_depth_stencil(buffers, clear_depth, clear_stencil); + depth_texture->clear_depth_stencil( + buffers, + clear_depth, + clear_stencil, + attachment.layer == -1 ? std::nullopt : std::make_optional(attachment.layer)); } } } diff --git a/source/blender/gpu/vulkan/vk_texture.cc b/source/blender/gpu/vulkan/vk_texture.cc index 34fa6764fc5..f003b515d95 100644 --- a/source/blender/gpu/vulkan/vk_texture.cc +++ b/source/blender/gpu/vulkan/vk_texture.cc @@ -122,7 +122,7 @@ void VKTexture::clear(eGPUDataFormat format, const void *data) format, TextureFormat::SFLOAT_32_DEPTH_UINT_8, TextureFormat::SFLOAT_32_DEPTH_UINT_8); - clear_depth_stencil(GPU_DEPTH_BIT | GPU_STENCIL_BIT, clear_depth, 0u); + clear_depth_stencil(GPU_DEPTH_BIT | GPU_STENCIL_BIT, clear_depth, 0u, std::nullopt); return; } @@ -146,7 +146,8 @@ void VKTexture::clear(eGPUDataFormat format, const void *data) void VKTexture::clear_depth_stencil(const eGPUFrameBufferBits buffers, float clear_depth, - uint clear_stencil) + uint clear_stencil, + std::optional layer) { BLI_assert(buffers & (GPU_DEPTH_BIT | GPU_STENCIL_BIT)); VkImageAspectFlags vk_image_aspect_device = to_vk_image_aspect_flag_bits(device_format_get()); @@ -166,6 +167,10 @@ void VKTexture::clear_depth_stencil(const eGPUFrameBufferBits buffers, clear_depth_stencil_image.node_data.vk_image_subresource_range.aspectMask = vk_image_aspect; clear_depth_stencil_image.node_data.vk_image_subresource_range.layerCount = VK_REMAINING_ARRAY_LAYERS; + if (layer.has_value()) { + clear_depth_stencil_image.node_data.vk_image_subresource_range.baseArrayLayer = *layer; + clear_depth_stencil_image.node_data.vk_image_subresource_range.layerCount = 1; + } clear_depth_stencil_image.node_data.vk_image_subresource_range.levelCount = VK_REMAINING_MIP_LEVELS; diff --git a/source/blender/gpu/vulkan/vk_texture.hh b/source/blender/gpu/vulkan/vk_texture.hh index 467866cfc95..5e4322ae42a 100644 --- a/source/blender/gpu/vulkan/vk_texture.hh +++ b/source/blender/gpu/vulkan/vk_texture.hh @@ -84,7 +84,8 @@ class VKTexture : public Texture { void clear(eGPUDataFormat format, const void *data) override; void clear_depth_stencil(const eGPUFrameBufferBits buffer, float clear_depth, - uint clear_stencil); + uint clear_stencil, + std::optional layer); void swizzle_set(const char swizzle_mask[4]) override; void mip_range_set(int min, int max) override; void *read(int mip, eGPUDataFormat format) override;