KhronosGroup / Vulkan-ValidationLayers

Vulkan Validation Layers (VVL)
https://vulkan.lunarg.com/doc/sdk/latest/linux/khronos_validation_layer.html
Other
755 stars 403 forks source link

"Descriptor uninitialized" false positive in GPU-assisted validation + push descriptors #5321

Closed haasn closed 1 year ago

haasn commented 1 year ago

Environment:

        apiVersion        = 1.3.230 (4206822)
        driverVersion     = 22.3.3 (92286979)
        vendorID          = 0x1002
        deviceID          = 0x15d8
        deviceType        = PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU
        deviceName        = AMD Radeon Vega 10 Graphics (RADV RAVEN)

Describe the Issue

I get a seemingly false positive error from GPU-assisted validation on this shader that seems perfectly legitimate to me:

compute shader source:
[  1] #version 450
[  2] #extension GL_ARB_compute_shader : enable
[  3] #extension GL_KHR_shader_subgroup_basic : enable 
[  4] #extension GL_KHR_shader_subgroup_vote : enable 
[  5] #extension GL_KHR_shader_subgroup_arithmetic : enable 
[  6] #extension GL_KHR_shader_subgroup_ballot : enable 
[  7] #extension GL_KHR_shader_subgroup_shuffle : enable 
[  8] #extension GL_ARB_shader_storage_buffer_object : enable
[  9] layout(constant_id=0) const uint _const_2_0 = 1; 
[ 10] layout(constant_id=1) const uint _const_3_0 = 1; 
[ 11] layout(std430, binding=0) readonly restrict buffer _SrcBuf_0_0 {
[ 12]     layout(offset=0) uint src[256];
[ 13] };
[ 14] layout(std430, binding=1) writeonly restrict buffer _DstBuf_1_0 {
[ 15]     layout(offset=0) uint dst[256];
[ 16] };
[ 17] layout (local_size_x = 256, local_size_y = 1) in;
[ 18] 
[ 19] void _main_4_0() {
[ 20] // pl_buf_copy_swap                               
[ 21] {                                                 
[ 22] uint word = src[_const_2_0 + gl_GlobalInvocationID.x];    
[ 23] word = (word & 0xFF00FF00u) >> 8 |                
[ 24]        (word & 0x00FF00FFu) << 8;                 
[ 25] dst[_const_3_0 + gl_GlobalInvocationID.x] = word;         
[ 26] }                                                 
[ 27] 
[ 28] }
[ 29] 
[ 30] void main() {
[ 31] _main_4_0();
[ 32] }
Specialization constant values:
  constant_id=0: 0
  constant_id=1: 0

As you can see from the log in the additional info section, I added some printf debugging to show that I definitely bind a buffer to each descriptor.

Valid Usage ID

vk Validation Error: [ UNASSIGNED-Descriptor uninitialized ] Object 0: handle = 0x1be1f70, name = compute, type = VK_OBJECT_TYPE_QUEUE; | MessageID = 0x893513c7 | Descriptor index 0 is uninitialized. Command buffer (vk_pass_run)(0x2ef7480). Compute Dispatch Index 0. Pipeline (0x1c000000001c). Shader Module (compute)(0x1b000000001b). Shader Instruction Index = 99.  Stage = Compute.  Global invocation ID (x, y, z) = (128, 0, 0 ) Shader validation error occurred in file input at line 23.Unable to find suitable #line directive in SPIR-V OpSource.
    using VkQueue: compute (0x1be1f70)

Additional context

code or terminal output ```logfile ; SPIR-V ; Version: 1.3 ; Generator: Google Shaderc over Glslang; 11 ; Bound: 54 ; Schema: 0 OpCapability Shader %2 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID OpExecutionMode %main LocalSize 256 1 1 %1 = OpString "input" OpSource GLSL 450 %1 "#version 450 #extension GL_ARB_compute_shader : enable #extension GL_KHR_shader_subgroup_basic : enable #extension GL_KHR_shader_subgroup_vote : enable #extension GL_KHR_shader_subgroup_arithmetic : enable #extension GL_KHR_shader_subgroup_ballot : enable #extension GL_KHR_shader_subgroup_shuffle : enable #extension GL_ARB_shader_storage_buffer_object : enable layout(constant_id=0) const uint _const_2_0 = 1; layout(constant_id=1) const uint _const_3_0 = 1; layout(std430, binding=0) readonly restrict buffer _SrcBuf_0_0 { layout(offset=0) uint src[256]; }; layout(std430, binding=1) writeonly restrict buffer _DstBuf_1_0 { layout(offset=0) uint dst[256]; }; layout (local_size_x = 256, local_size_y = 1) in; void _main_4_0() { // pl_buf_copy_swap { uint word = src[_const_2_0 + gl_GlobalInvocationID.x]; word = (word & 0xFF00FF00u) >> 8 | (word & 0x00FF00FFu) << 8; dst[_const_3_0 + gl_GlobalInvocationID.x] = word; } } void main() { _main_4_0(); }" OpSourceExtension "GL_ARB_compute_shader" OpSourceExtension "GL_ARB_shader_storage_buffer_object" OpSourceExtension "GL_GOOGLE_cpp_style_line_directive" OpSourceExtension "GL_GOOGLE_include_directive" OpSourceExtension "GL_KHR_shader_subgroup_arithmetic" OpSourceExtension "GL_KHR_shader_subgroup_ballot" OpSourceExtension "GL_KHR_shader_subgroup_basic" OpSourceExtension "GL_KHR_shader_subgroup_shuffle" OpSourceExtension "GL_KHR_shader_subgroup_vote" OpName %main "main" OpName %_main_4_0_ "_main_4_0(" OpName %word "word" OpName %_SrcBuf_0_0 "_SrcBuf_0_0" OpMemberName %_SrcBuf_0_0 0 "src" OpName %_ "" OpName %_const_2_0 "_const_2_0" OpName %gl_GlobalInvocationID "gl_GlobalInvocationID" OpName %_DstBuf_1_0 "_DstBuf_1_0" OpMemberName %_DstBuf_1_0 0 "dst" OpName %__0 "" OpName %_const_3_0 "_const_3_0" OpModuleProcessed "entry-point main" OpModuleProcessed "client vulkan100" OpModuleProcessed "target-env spirv1.3" OpModuleProcessed "target-env vulkan1.1" OpModuleProcessed "entry-point main" OpDecorate %_arr_uint_uint_256 ArrayStride 4 OpMemberDecorate %_SrcBuf_0_0 0 Restrict OpMemberDecorate %_SrcBuf_0_0 0 NonWritable OpMemberDecorate %_SrcBuf_0_0 0 Offset 0 OpDecorate %_SrcBuf_0_0 Block OpDecorate %_ DescriptorSet 0 OpDecorate %_ Binding 0 OpDecorate %_const_2_0 SpecId 0 OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId OpDecorate %_arr_uint_uint_256_0 ArrayStride 4 OpMemberDecorate %_DstBuf_1_0 0 Restrict OpMemberDecorate %_DstBuf_1_0 0 NonReadable OpMemberDecorate %_DstBuf_1_0 0 Offset 0 OpDecorate %_DstBuf_1_0 Block OpDecorate %__0 DescriptorSet 0 OpDecorate %__0 Binding 1 OpDecorate %_const_3_0 SpecId 1 OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize %void = OpTypeVoid %4 = OpTypeFunction %void %uint = OpTypeInt 32 0 %_ptr_Function_uint = OpTypePointer Function %uint %uint_256 = OpConstant %uint 256 %_arr_uint_uint_256 = OpTypeArray %uint %uint_256 %_SrcBuf_0_0 = OpTypeStruct %_arr_uint_uint_256 %_ptr_StorageBuffer__SrcBuf_0_0 = OpTypePointer StorageBuffer %_SrcBuf_0_0 %_ = OpVariable %_ptr_StorageBuffer__SrcBuf_0_0 StorageBuffer %int = OpTypeInt 32 1 %int_0 = OpConstant %int 0 %_const_2_0 = OpSpecConstant %uint 1 %v3uint = OpTypeVector %uint 3 %_ptr_Input_v3uint = OpTypePointer Input %v3uint %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input %uint_0 = OpConstant %uint 0 %_ptr_Input_uint = OpTypePointer Input %uint %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint %uint_4278255360 = OpConstant %uint 4278255360 %int_8 = OpConstant %int 8 %uint_16711935 = OpConstant %uint 16711935 %_arr_uint_uint_256_0 = OpTypeArray %uint %uint_256 %_DstBuf_1_0 = OpTypeStruct %_arr_uint_uint_256_0 %_ptr_StorageBuffer__DstBuf_1_0 = OpTypePointer StorageBuffer %_DstBuf_1_0 %__0 = OpVariable %_ptr_StorageBuffer__DstBuf_1_0 StorageBuffer %_const_3_0 = OpSpecConstant %uint 1 %uint_1 = OpConstant %uint 1 %gl_WorkGroupSize = OpConstantComposite %v3uint %uint_256 %uint_1 %uint_1 OpLine %1 30 11 %main = OpFunction %void None %4 %6 = OpLabel OpLine %1 31 0 %51 = OpFunctionCall %void %_main_4_0_ OpReturn OpFunctionEnd OpLine %1 19 16 %_main_4_0_ = OpFunction %void None %4 %8 = OpLabel %word = OpVariable %_ptr_Function_uint Function OpLine %1 22 0 %25 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 %26 = OpLoad %uint %25 %27 = OpIAdd %uint %_const_2_0 %26 %29 = OpAccessChain %_ptr_StorageBuffer_uint %_ %int_0 %27 %30 = OpLoad %uint %29 OpStore %word %30 OpLine %1 23 0 %31 = OpLoad %uint %word %33 = OpBitwiseAnd %uint %31 %uint_4278255360 %35 = OpShiftRightLogical %uint %33 %int_8 OpLine %1 24 0 %36 = OpLoad %uint %word %38 = OpBitwiseAnd %uint %36 %uint_16711935 %39 = OpShiftLeftLogical %uint %38 %int_8 %40 = OpBitwiseOr %uint %35 %39 OpStore %word %40 OpLine %1 25 0 %46 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 %47 = OpLoad %uint %46 %48 = OpIAdd %uint %_const_3_0 %47 %49 = OpLoad %uint %word %50 = OpAccessChain %_ptr_StorageBuffer_uint %__0 %int_0 %48 OpStore %50 %49 OpReturn OpFunctionEnd Spent 101.308 ms translating SPIR-V (slow!) vk->CreatePipelineCache(vk->dev, &pcinfo, PL_VK_ALLOC, &pass_vk->cache) vk->CreateShaderModule(vk->dev, &sinfo, PL_VK_ALLOC, &pass_vk->shader) Spent 1.493 ms compiling shader vk_recreate_pipelines(vk, pass, has_spec, VK_NULL_HANDLE, pipe) vk Validation Warning: [ UNASSIGNED-BestPractices-SpirvDeprecated_WorkgroupSize ] Object 0: handle = 0x1cfe7d0, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x7bc61184 | vkCreateComputePipelines(): pCreateInfos[ 0] is using the Workgroup built-in which SPIR-V 1.6 deprecated. The VK_KHR_maintenance4 extension exposes a new LocalSizeId execution mode that should be used instead. using VkDevice: anon (0x1cfe7d0) Spent 0.607 ms creating pipeline vk->GetPipelineCacheData(vk->dev, pass_vk->cache, &cache.len, NULL) vk->GetPipelineCacheData(vk->dev, pass_vk->cache, &cache.len, cache.buf) Pass statistics: size 2224, SPIR-V: vert 0 frag 0 comp 3264 vk->CreateQueryPool(vk->dev, &qinfo, PL_VK_ALLOC, &timer->qpool) vk->AllocateCommandBuffers(vk->dev, &ainfo, &cmd->buf) vk->CreateSemaphore(vk->dev, &sinfo, PL_VK_ALLOC, &cmd->sync.sem) vk->BeginCommandBuffer(cmd->buf, &binfo) Pushing descriptors: 2 binding 0 type 7 count 1 buffer 0x140000000014 offset 0 range 1024 binding 1 type 7 count 1 buffer 0x160000000016 offset 0 range 1024 vk->EndCommandBuffer(cmd->buf) Submitting command 0x2ef7480 on queue 0x1be1f70 (QF 1): signals semaphore 0x1e000000001e = 1 signals 4 callbacks vk Validation Error: [ UNASSIGNED-Descriptor uninitialized ] Object 0: handle = 0x1be1f70, name = compute, type = VK_OBJECT_TYPE_QUEUE; | MessageID = 0x893513c7 | Descriptor index 0 is uninitialized. Command buffer (vk_pass_run)(0x2ef7480). Compute Dispatch Index 0. Pipeline (0x1c000000001c). Shader Module (compute)(0x1b000000001b). Shader Instruction Index = 99. Stage = Compute. Global invocation ID (x, y, z) = (128, 0, 0 ) Shader validation error occurred in file input at line 23.Unable to find suitable #line directive in SPIR-V OpSource. using VkQueue: compute (0x1be1f70) Backtrace: #0 0x000000000045c8ea in vk_dbg_utils_cb+0x22a at build/src/tests/test.vulkan.c+0x5c8ea #1 0x00007fd65f63c662 in vkNegotiateLoaderLayerInterfaceVersion+0x410c22 at /lib64/libVkLayer_khronos_validation.so+0x83c662 #2 0x00007fd65f2b4ea1 in vkNegotiateLoaderLayerInterfaceVersion+0x89461 at /lib64/libVkLayer_khronos_validation.so+0x4b4ea1 #3 0x00007fd65f33b680 in vkNegotiateLoaderLayerInterfaceVersion+0x10fc40 at /lib64/libVkLayer_khronos_validation.so+0x53b680 #4 0x00007fd65f3debab in vkNegotiateLoaderLayerInterfaceVersion+0x1b316b at /lib64/libVkLayer_khronos_validation.so+0x5debab #5 0x00007fd65f3df166 in vkNegotiateLoaderLayerInterfaceVersion+0x1b3726 at /lib64/libVkLayer_khronos_validation.so+0x5df166 #6 0x00007fd65f58d096 in vkNegotiateLoaderLayerInterfaceVersion+0x361656 at /lib64/libVkLayer_khronos_validation.so+0x78d096 #7 0x00007fd65f58d47a in vkNegotiateLoaderLayerInterfaceVersion+0x361a3a at /lib64/libVkLayer_khronos_validation.so+0x78d47a #8 0x00007fd65f1c7db5 in vkNegotiateLoaderLayerInterfaceVersion+0x361a3a at /lib64/libVkLayer_khronos_validation.so+0x3c7db5 #9 0x000000000045bb66 in vk_cmd_submit+0x1d6 at build/src/tests/test.vulkan.c+0x5bb66 #10 0x0000000000462b28 in _end_cmd+0x108 at build/src/tests/test.vulkan.c+0x62b28 #11 0x000000000046ae3e in vk_pass_run+0x7fe at build/src/tests/test.vulkan.c+0x6ae3e #12 0x0000000000417684 in pl_pass_run+0x474 at build/src/tests/test.vulkan.c+0x17684 #13 0x000000000040c8f7 in run_pass+0x37 at build/src/tests/test.vulkan.c+0xc8f7 #14 0x000000000040fd9a in pl_dispatch_compute+0x1da at build/src/tests/test.vulkan.c+0xfd9a #15 0x0000000000419cef in pl_buf_copy_swap+0x3cf at build/src/tests/test.vulkan.c+0x19cef #16 0x000000000047a370 in pl_buffer_tests+0x550 at build/src/tests/test.vulkan.c+0x7a370 #17 0x0000000000404f4c in main+0x54c at build/src/tests/test.vulkan.c+0x4f4c #18 0x00007fd66962c5b0 in __libc_start_call_main+0x82 at /lib64/libc.so.6+0x275b0 #19 0x00007fd66962c679 in __libc_start_main+0x8b at /lib64/libc.so.6+0x27679 #20 0x0000000000408645 in _start+0x25 at build/src/tests/test.vulkan.c+0x8645 ```
haasn commented 1 year ago

I can add that using a VkDescriptorSet instead of vkCmdPushDescriptorSet makes the problem disappear. So the problem to me appears that the descriptor initialization VU does not check for pushed descriptors.

haasn commented 1 year ago

Possibly related to https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/5037#issuecomment-1374253360

haasn commented 1 year ago

I attempted making a GFXR capture to reproduce the issue: https://0x1.st/XQ.gfxr (replay with --validate)

but it does not reproduce the exact error inside the gfxreconstruct replay for me.

tomilov commented 1 year ago

vk::ValidationFeatureEnableEXT::eDebugPrintf, which also uses slot, results in the same problem as vk::ValidationFeatureEnableEXT::eGpuAssisted + vk::ValidationFeatureEnableEXT::eGpuAssistedReserveBindingSlot.

spencer-lunarg commented 1 year ago

I took the GFXR capture and looked at the API dump of what is inside and tried to recreate the related part of the test in https://github.com/KhronosGroup/Vulkan-ValidationLayers/pull/5375

I was not able to re-produce it, not saying it is not a bug, but will have to come back to this later and see if I can reproduce it

I think look more into this your issue is the maxBoundDescriptorSets is 32 and you have 30 empty descriptor slots in your pipeline not being used. The GPU-AV only can work if you provide a free descriptor slot for the validation code to inject the logic to track in the shader (https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/main/docs/gpu_validation.md#descriptor-set-binding-limit) ... this would also explain @tomilov issue too I think

haasn commented 1 year ago

I'm not sure I understand what you're suggesting. I only use 1 descriptor slot for my shader, and one is used by GPU-AV, so that leaves 30 unused, yes? So where exactly is the problem?

spencer-lunarg commented 1 year ago

sorry, I see the unused descriptors are just in the Pipeline Layout, so sorry, please ignore my maxBoundDescriptorSets comment

Cyphall commented 1 year ago

I am also experiencing this issue.

If a descriptor set was bound at some point before in my command buffer, my push-descriptor-based dynamic_rendering pass works with no validation error. However, if my command buffer is fresh from any descriptor set bind, I get this validation error. In both cases, the actual rendering works with no problem.

My VulkanSDK version is 1.3.243.0.