You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Launching the editor with an empty project with Vulkan validation enabled (--gpu-validation) results in the following message spammed:
VUID-vkCmdDrawIndexed-None-06479(ERROR / SPEC): msgNum: 1397510317 - Validation Error: [ VUID-vkCmdDrawIndexed-None-06479 ] Object 0: handle = 0xf9a57300000043d5, name = RID:694113959674081, type = VK_OBJECT_TYPE_DESCRIPTOR_SET; Object 1: handle = 0x4baaca000000019b, name = RID:665719930899 View, type = VK_OBJECT_TYPE_IMAGE_VIEW; | MessageID = 0x534c50ad | vkCmdDrawIndexed(): the descriptor (VkDescriptorSet 0xf9a57300000043d5[RID:694113959674081], binding 4, index 0) has VkImageView 0x4baaca000000019b[RID:665719930899 View] with format of VK_FORMAT_R32_SFLOAT which doesn't support VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT in.
i(supported features: VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT|VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT|VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT|VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT|VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT|VK_FORMAT_FEATURE_2_BLIT_SRC_BIT|VK_FORMAT_FEATURE_2_BLIT_DST_BIT|VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT|VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT|VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT|VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT|VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT|VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT). The Vulkan spec states: If a VkImageView is sampled with depth comparison, the image view's format features must contain VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT (https://vulkan.lunarg.com/doc/view/1.3.283.0/linux/1.3-extensions/vkspec.html#VUID-vkCmdDrawIndexed-None-06479)
This shader is used when rendering the dark-grey-blueish background of Godot's Editor.
I am not familiar enough with the Canvas2D renderer to fix it, but I gathered the following and I can suggest several solutions:
renderer_canvas_render_rd.cpp creates 2 textures for shadow rendering in RendererCanvasRenderRD::_update_shadow_atlas:
state.shadow_texture which is a "colour" R32_FLOAT texture (technically monochrome).
state.shadow_depth_texture which is a depth D32_FLOAT texture.
Both textures are combined as an FBO for rendering into it.
state.shadow_texture is the texture bound to shadow_atlas_texture for use during rendering. state.shadow_depth_texture is never bound.
If this were 3D rendering, most of the time the colour texture would be pointless (unless it's doing an advanced algorithm) and say there's a mistake and it should be the D32_FLOAT texture the one to be alone. But since I don't know how to even trigger 2D shadows in Godot, perhaps the colour texture is the one that should be bound.
Possible Solution 1
Just get rid of the colour texture, leave the depth texture and bind that.
It is specially suspicious that the colour texture appears to contain depth information.
Possible Solution 2
OK so let's assume the colour R32_FLOAT is needed.
The problem happens because Godot is relying on HW support to do bilinear PCF. This issue affects D3D too:
We cannot do "sampler2DShadow(shadow_atlas_texture, shadow_sampler)" if unsupported for that pixel format.
The solution is to emulate the PCF:
float emulatedPcf2x2( texture2D t, float4 uv, float2 uv_resolution )
{
float r00 =texture2D( sampler2D( t, SAMPLER_NEAREST_CLAMP ), uv.xy ).x;
float r10 =texture2D( sampler2D( t, SAMPLER_NEAREST_CLAMP ), uv.xy +float( 1/uv_resolution.x, 0 ) ).x;
float r01 =texture2D( sampler2D( t, SAMPLER_NEAREST_CLAMP ), uv.xy +float( 0, 1/uv_resolution.y ) ).x;
float r11 =texture2D( sampler2D( t, SAMPLER_NEAREST_CLAMP ), uv.xy +float( 1/uv_resolution ) ).x;
// Perform depth comparisons.
r00 = r00 > uv.w;
r10 = r10 > uv.w;
r01 = r01 > uv.w;
r11 = r11 > uv.w;
// Apply bilinear filtering to depth comparisons.// WARNING: fract() will give the wrong value for negative values. This example code is not accounting for that. Or maybe the "wrong" value is the correct one we need. I haven't given thought about it.float xyFract =fract( uv.xy * uv_resolution.xy );
float t = lerp( r00, r10, xyFract.x );
float s = lerp( r01, r11, xyFract.x );
return lerp( t, s, xyFract.y );
}
I wrote this out of memory, so it may have one or two syntax errors.
Of course this emulation requires 4 fetches, so it's far from ideal.
It could be optimized using Gather4 (which can fetch 4 texels in one sample). Last time I tried that (10 years ago!) I could not get the Gather4 version to run reliably because some drivers would be buggy or would scramble the order of the pixels (e.g. r10 and r01 were swapped, stuff like that).
Possible Solution 3
Just perform a blit or compute copy from the R32_FLOAT to a D32_FLOAT texture and bind the D32_FLOAT instead.
Steps to reproduce
Setup Vulkan Validation Layers
Launch an empty project with -e --gpu-validation
Minimal reproduction project (MRP)
N / A
The text was updated successfully, but these errors were encountered:
Tested versions
4.4-master
System information
Godot v4.4.dev (44fa552) - Ubuntu 24.04.1 LTS 24.04 on X11 - X11 display driver, Multi-window, 2 monitors - Vulkan (Mobile) - dedicated AMD Radeon RX 6800 XT (RADV NAVI21) - AMD Ryzen 9 5900X 12-Core Processor (24 threads)
Issue description
Launching the editor with an empty project with Vulkan validation enabled (
--gpu-validation
) results in the following message spammed:Upon closer inspection the error is caused from:
layout(set = 0, binding = 4) uniform texture2D shadow_atlas_texture;
I am not familiar enough with the Canvas2D renderer to fix it, but I gathered the following and I can suggest several solutions:
renderer_canvas_render_rd.cpp creates 2 textures for shadow rendering in
RendererCanvasRenderRD::_update_shadow_atlas
:state.shadow_texture
which is a "colour" R32_FLOAT texture (technically monochrome).state.shadow_depth_texture
which is a depth D32_FLOAT texture.state.shadow_texture
is the texture bound toshadow_atlas_texture
for use during rendering.state.shadow_depth_texture
is never bound.If this were 3D rendering, most of the time the colour texture would be pointless (unless it's doing an advanced algorithm) and say there's a mistake and it should be the
D32_FLOAT
texture the one to be alone. But since I don't know how to even trigger 2D shadows in Godot, perhaps the colour texture is the one that should be bound.Possible Solution 1
Just get rid of the colour texture, leave the depth texture and bind that.
It is specially suspicious that the colour texture appears to contain depth information.
Possible Solution 2
OK so let's assume the colour R32_FLOAT is needed.
The problem happens because Godot is relying on HW support to do bilinear PCF. This issue affects D3D too:
We cannot do "sampler2DShadow(shadow_atlas_texture, shadow_sampler)" if unsupported for that pixel format.
The solution is to emulate the PCF:
I wrote this out of memory, so it may have one or two syntax errors.
Of course this emulation requires 4 fetches, so it's far from ideal.
It could be optimized using Gather4 (which can fetch 4 texels in one sample). Last time I tried that (10 years ago!) I could not get the Gather4 version to run reliably because some drivers would be buggy or would scramble the order of the pixels (e.g. r10 and r01 were swapped, stuff like that).
Possible Solution 3
Just perform a blit or compute copy from the R32_FLOAT to a D32_FLOAT texture and bind the D32_FLOAT instead.
Steps to reproduce
-e --gpu-validation
Minimal reproduction project (MRP)
N / A
The text was updated successfully, but these errors were encountered: