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
This commit is contained in:
Jeroen Bakker
2025-08-26 14:18:47 +02:00
parent 3417401f0f
commit f82e89183e
4 changed files with 24 additions and 8 deletions

View File

@@ -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

View File

@@ -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));
}
}
}

View File

@@ -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<int> 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;

View File

@@ -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<int> 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;