RADV: SIGFPE on seemingly valid tessellation control shader
System information
λ inxi -GSC -xx
System: Host: xor Kernel: 5.6.3-gentoo x86_64 bits: 64 compiler: gcc v: 9.3.0 Desktop: N/A dm: startx
Distro: Gentoo Base System release 2.7
CPU: Topology: 16-Core (2-Die) model: AMD Ryzen Threadripper 1950X bits: 64 type: MT MCP MCM arch: Zen rev: 1
L2 cache: 8192 KiB
flags: avx avx2 lm nx pae sse sse2 sse3 sse4_1 sse4_2 sse4a ssse3 svm bogomips: 217153
Speed: 2135 MHz min/max: 2200/3400 MHz Core speeds (MHz): 1: 1988 2: 2073 3: 2079 4: 2108 5: 2168
6: 2192 7: 1886 8: 2183 9: 2000 10: 2042 11: 2172 12: 2386 13: 2040 14: 2180 15: 2115 16: 2191 17: 2113
18: 2195 19: 1981 20: 1981 21: 1974 22: 2132 23: 2194 24: 2573 25: 2159 26: 2171 27: 2152 28: 2083
29: 2162 30: 2156 31: 2165 32: 2057
Graphics: Device-1: Advanced Micro Devices [AMD/ATI] Baffin [Radeon RX 550 640SP / RX 560/560X]
vendor: Sapphire Limited driver: amdgpu v: kernel bus ID: 08:00.0 chip ID: 1002:67ff
Device-2: NVIDIA GM204 [GeForce GTX 970] vendor: ASUSTeK driver: vfio-pci v: 0.2 bus ID: 43:00.0
chip ID: 10de:13c2
Display: server: X.Org 1.20.99.1 driver: amdgpu,ati unloaded: modesetting,radeon alternate: fbdev,vesa
resolution: 3840x2160~60Hz
OpenGL: renderer: Radeon RX 560 Series (POLARIS11 DRM 3.36.0 5.6.3-gentoo LLVM 10.0.0)
v: 4.6 Mesa 20.1.0-devel (git-91375f13ce) direct render: Yes
Describe the issue
I hit this SIGFPE while running the Vulkan-ValidationLayers test framework. You should be able to reproduce this by following the build instructions listed in their BUILD.md
(making sure to set -DBUILD_TESTS=on
) and running the tests/vk_layer_validation_tests
binary.
The test that triggers the SIGFPE, VkLayerTest.CreatePipelineExceedMaxTessellationControlInputOutputComponents
is designed to test the handling of tessellation control shaders at (or exceeding) the capacity of input/output components. Shaders where this capacity is exceeded are correctly caught by the validation layer, but the case of components = capacity
triggers the SIGFPE in mesa's shader compiler.
My GPU has:
maxTessellationControlPerVertexInputComponents = 128
maxTessellationControlPerVertexOutputComponents = 128
Resulting in the following shader:
#version 450
layout(location=0) in vec4 v0In[];
layout(location=1) in vec4 v1In[];
layout(location=2) in vec4 v2In[];
layout(location=3) in vec4 v3In[];
layout(location=4) in vec4 v4In[];
layout(location=5) in vec4 v5In[];
layout(location=6) in vec4 v6In[];
layout(location=7) in vec4 v7In[];
layout(location=8) in vec4 v8In[];
layout(location=9) in vec4 v9In[];
layout(location=10) in vec4 v10In[];
layout(location=11) in vec4 v11In[];
layout(location=12) in vec4 v12In[];
layout(location=13) in vec4 v13In[];
layout(location=14) in vec4 v14In[];
layout(location=15) in vec4 v15In[];
layout(location=16) in vec4 v16In[];
layout(location=17) in vec4 v17In[];
layout(location=18) in vec4 v18In[];
layout(location=19) in vec4 v19In[];
layout(location=20) in vec4 v20In[];
layout(location=21) in vec4 v21In[];
layout(location=22) in vec4 v22In[];
layout(location=23) in vec4 v23In[];
layout(location=24) in vec4 v24In[];
layout(location=25) in vec4 v25In[];
layout(location=26) in vec4 v26In[];
layout(location=27) in vec4 v27In[];
layout(location=28) in vec4 v28In[];
layout(location=29) in vec4 v29In[];
layout(location=30) in vec4 v30In[];
layout(location=31) in vec4 v31In[];
layout(location=0) out vec4 v0Out[3];
layout(location=1) out vec4 v1Out[3];
layout(location=2) out vec4 v2Out[3];
layout(location=3) out vec4 v3Out[3];
layout(location=4) out vec4 v4Out[3];
layout(location=5) out vec4 v5Out[3];
layout(location=6) out vec4 v6Out[3];
layout(location=7) out vec4 v7Out[3];
layout(location=8) out vec4 v8Out[3];
layout(location=9) out vec4 v9Out[3];
layout(location=10) out vec4 v10Out[3];
layout(location=11) out vec4 v11Out[3];
layout(location=12) out vec4 v12Out[3];
layout(location=13) out vec4 v13Out[3];
layout(location=14) out vec4 v14Out[3];
layout(location=15) out vec4 v15Out[3];
layout(location=16) out vec4 v16Out[3];
layout(location=17) out vec4 v17Out[3];
layout(location=18) out vec4 v18Out[3];
layout(location=19) out vec4 v19Out[3];
layout(location=20) out vec4 v20Out[3];
layout(location=21) out vec4 v21Out[3];
layout(location=22) out vec4 v22Out[3];
layout(location=23) out vec4 v23Out[3];
layout(location=24) out vec4 v24Out[3];
layout(location=25) out vec4 v25Out[3];
layout(location=26) out vec4 v26Out[3];
layout(location=27) out vec4 v27Out[3];
layout(location=28) out vec4 v28Out[3];
layout(location=29) out vec4 v29Out[3];
layout(location=30) out vec4 v30Out[3];
layout(location=31) out vec4 v31Out[3];
layout(vertices=3) out;
void main(){
}
This triggers the following SIGFPE:
Thread 1 "vk_layer_valida" received signal SIGFPE, Arithmetic exception.
0x00007ffff71264ac in get_tcs_num_patches (family=CHIP_POLARIS11, chip_class=GFX8, tess_offchip_block_dw_size=8192, tcs_num_patch_outputs=<optimized out>, tcs_num_outputs=<optimized out>, tcs_num_inputs=1, tcs_num_output_vertices=3, tcs_num_input_vertices=3) at ../mesa-9999/src/amd/vulkan/radv_shader.h:585
585 if (chip_class >= GFX7 && family != CHIP_STONEY)
(gdb) bt
#0 0x00007ffff71264ac in get_tcs_num_patches (family=CHIP_POLARIS11, chip_class=GFX8, tess_offchip_block_dw_size=8192, tcs_num_patch_outputs=<optimized out>, tcs_num_outputs=<optimized out>, tcs_num_inputs=1, tcs_num_output_vertices=3, tcs_num_input_vertices=3) at ../mesa-9999/src/amd/vulkan/radv_shader.h:585
#1 ac_translate_nir_to_llvm (ac_llvm=ac_llvm@entry=0x7fffffff84a0, shaders=shaders@entry=0x7fffffff90a8, shader_count=shader_count@entry=1, args=0x7fffffff8570) at ../mesa-9999/src/amd/vulkan/radv_nir_to_llvm.c:4010
#2 0x00007ffff712823e in radv_compile_nir_shader (nir_count=1, nir=0x7fffffff90a8, args=0x7fffffff8570, rbinary=0x7fffffff8558, ac_llvm=0x7fffffff84a0) at ../mesa-9999/src/amd/vulkan/radv_nir_to_llvm.c:4432
#3 llvm_compile_shader (device=device@entry=0x55555778f430, shader_count=shader_count@entry=1, shaders=shaders@entry=0x7fffffff90a8, binary=binary@entry=0x7fffffff8558, args=args@entry=0x7fffffff8570) at ../mesa-9999/src/amd/vulkan/radv_nir_to_llvm.c:4432
#4 0x00007ffff713892f in shader_variant_compile (device=device@entry=0x55555778f430, module=module@entry=0x5555580a4f80, shaders=shaders@entry=0x7fffffff90a8, shader_count=shader_count@entry=1, info=0x7fffffffaab0, options=0x7fffffff8cd0, gs_copy_shader=false, keep_shader_info=false, keep_statistic_info=false, binary_out=0x7fffffff90d8, stage=<optimized out>) at ../mesa-9999/src/amd/vulkan/radv_shader.c:1131
#5 0x00007ffff7138cc2 in radv_shader_variant_compile (device=device@entry=0x55555778f430, module=module@entry=0x5555580a4f80, shaders=shaders@entry=0x7fffffff90a8, shader_count=shader_count@entry=1, layout=0x555557d0e7c0, key=key@entry=0x7fffffff9a60, info=0x7fffffffaab0, keep_shader_info=false, keep_statistic_info=false, binary_out=0x7fffffff90d8) at ../mesa-9999/src/amd/vulkan/radv_shader.c:1195
#6 0x00007ffff712ef67 in radv_create_shaders (pipeline=<optimized out>, device=<optimized out>, cache=<optimized out>, key=<optimized out>, pStages=<optimized out>, flags=<optimized out>, pipeline_feedback=<optimized out>, stage_feedbacks=<optimized out>) at ../mesa-9999/src/amd/vulkan/radv_pipeline.c:3070
#7 0x00007ffff7131993 in radv_pipeline_init (pipeline=<optimized out>, device=0x55555778f430, cache=0x5555579e8c90, pCreateInfo=0x55555783f528, extra=0x0) at ../mesa-9999/src/amd/vulkan/radv_pipeline.c:5139
#8 0x00007ffff7133c80 in radv_graphics_pipeline_create (_device=0x55555778f430, _cache=0x5555579e8c90, pCreateInfo=0x55555783f528, extra=0x0, pAllocator=0x0, pPipeline=<optimized out>) at ../mesa-9999/src/amd/vulkan/radv_pipeline.c:5268
#9 0x00007ffff7133d76 in radv_CreateGraphicsPipelines (_device=0x55555778f430, pipelineCache=0x5555579e8c90, count=<optimized out>, pCreateInfos=<optimized out>, pAllocator=0x0, pPipelines=<optimized out>) at ../mesa-9999/src/amd/vulkan/radv_pipeline.c:5293
#10 0x00007fffee1bb19d in DispatchCreateGraphicsPipelines (device=device@entry=0x55555778f430, pipelineCache=0x5555579e8c90, pipelineCache@entry=0x110000000011, createInfoCount=createInfoCount@entry=1, pCreateInfos=0x7fffffffd580, pAllocator=pAllocator@entry=0x0, pPipelines=pPipelines@entry=0x7fffffffd638) at /usr/src/debug/media-libs/vulkan-layers-9999/vulkan-layers-9999/layers/generated/vk_safe_struct.h:684
#11 0x00007fffee1141b8 in vulkan_layer_chassis::CreateGraphicsPipelines (device=0x55555778f430, pipelineCache=<optimized out>, createInfoCount=1, pCreateInfos=0x7fffffffd580, pAllocator=0x0, pPipelines=<optimized out>) at /usr/src/debug/media-libs/vulkan-layers-9999/vulkan-layers-9999/layers/generated/chassis.cpp:711
#12 0x00005555555e0644 in CreatePipelineHelper::CreateGraphicsPipeline (this=this@entry=0x7fffffffd340, implicit_destroy=implicit_destroy@entry=true, do_late_bind=do_late_bind@entry=true) at /home/nand/dev/Vulkan-ValidationLayers/tests/vkrenderframework.h:71
#13 0x00005555556745b8 in CreatePipelineHelper::OneshotTest<VkLayerTest_CreatePipelineExceedMaxTessellationControlInputOutputComponents_Test, VkLayerTest_CreatePipelineExceedMaxTessellationControlInputOutputComponents_Test::TestBody()::<lambda(CreatePipelineHelper&)>, char const*> (positive_test=true, errors=std::vector of length 1, capacity 5864056557040 = {...}, flags=8, info_override=..., test=...)
at /usr/lib/gcc/x86_64-pc-linux-gnu/9.3.0/include/g++-v9/bits/stl_iterator.h:907
#14 CreatePipelineHelper::OneshotTest<VkLayerTest_CreatePipelineExceedMaxTessellationControlInputOutputComponents_Test, VkLayerTest_CreatePipelineExceedMaxTessellationControlInputOutputComponents_Test::TestBody()::<lambda(CreatePipelineHelper&)>, char const*> (positive_test=true, error=0x555555e5727f "", flags=8, info_override=..., test=...) at /home/nand/dev/Vulkan-ValidationLayers/tests/layer_validation_tests.h:466
#15 VkLayerTest_CreatePipelineExceedMaxTessellationControlInputOutputComponents_Test::TestBody (this=<optimized out>) at /home/nand/dev/Vulkan-ValidationLayers/tests/vklayertests_pipeline_shader.cpp:4454
#16 0x00007ffff7dc9e35 in testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void> (object=object@entry=0x555557db7620, method=<optimized out>, location=location@entry=0x7ffff7dd3b79 "the test body") at /home/nand/dev/Vulkan-ValidationLayers/external/googletest/googletest/src/gtest.cc:2424
#17 0x00007ffff7dd1d7a in testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void> (object=object@entry=0x555557db7620, method=&virtual testing::Test::TestBody(), location=location@entry=0x7ffff7dd3b79 "the test body") at /home/nand/dev/Vulkan-ValidationLayers/external/googletest/googletest/src/gtest-internal-inl.h:807
#18 0x00007ffff7dc069f in testing::Test::Run (this=this@entry=0x555557db7620) at /home/nand/dev/Vulkan-ValidationLayers/external/googletest/googletest/src/gtest.cc:2517
#19 0x00007ffff7dc09a9 in testing::TestInfo::Run (this=0x5555569ba710) at /home/nand/dev/Vulkan-ValidationLayers/external/googletest/googletest/src/gtest.cc:2693
#20 0x00007ffff7dc0a49 in testing::TestCase::Run (this=0x5555569af810) at /home/nand/dev/Vulkan-ValidationLayers/external/googletest/googletest/src/gtest.cc:2811
#21 0x00007ffff7dc4600 in testing::internal::UnitTestImpl::RunAllTests (this=0x5555569af4b0) at /home/nand/dev/Vulkan-ValidationLayers/external/googletest/googletest/src/gtest.cc:5154
#22 0x00007ffff7dca44a in testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> (object=object@entry=0x5555569af4b0, method=<optimized out>, location=location@entry=0x7ffff7dd5c00 "auxiliary test code (environments or event listeners)") at /home/nand/dev/Vulkan-ValidationLayers/external/googletest/googletest/src/gtest.cc:2424
#23 0x00007ffff7dd2244 in testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> (object=0x5555569af4b0, method=(bool (testing::internal::UnitTestImpl::*)(class testing::internal::UnitTestImpl * const)) 0x7ffff7dc431a <testing::internal::UnitTestImpl::RunAllTests()>, location=location@entry=0x7ffff7dd5c00 "auxiliary test code (environments or event listeners)")
at /home/nand/dev/Vulkan-ValidationLayers/external/googletest/googletest/src/gtest-internal-inl.h:807
#24 0x00007ffff7dc0748 in testing::UnitTest::Run (this=0x7ffff7de4280 <testing::UnitTest::GetInstance()::instance>) at /home/nand/dev/Vulkan-ValidationLayers/external/googletest/googletest/include/gtest/gtest.h:1340
#25 0x00005555555e012c in RUN_ALL_TESTS () at /home/nand/dev/Vulkan-ValidationLayers/external/googletest/googletest/include/gtest/gtest.h:2341
#26 main (argc=<optimized out>, argv=<optimized out>) at /home/nand/dev/Vulkan-ValidationLayers/tests/layer_validation_tests.cpp:3082
Note: indicated line number is wrong. The actual division by zero happens in the following line, in which output_patch_size=0
:
num_patches = MIN2(num_patches, hardware_lds_size / (input_patch_size + output_patch_size));
(Note: Even though there have been very recent changes (as of today) to this function, the problem has existed for at least a week, and the actual issue seems to be in one of the higher-level functions, since ctx.args->shader_info->tcs.outputs_written
is already 0 by the time this function is called.)