RADV segfault on vkCmdDrawIndexed call when compiled with GCC 10 with optimizations (-O1 or -O2)
System information
$ inxi -GCS -xx
System: Host: cauldron Kernel: 5.7.9-desktop-1.mga8 x86_64 bits: 64 compiler: gcc v: 10.1.1 Desktop: KDE Plasma 5.19.3
tk: Qt 5.15.0 wm: kwin_x11 dm: SDDM Distro: Mageia 8 mga8
CPU: Topology: Quad Core model: Intel Core i7-8705G bits: 64 type: MT MCP arch: Kaby Lake rev: 9 L2 cache: 8192 KiB
flags: avx avx2 lm nx pae sse sse2 sse3 sse4_1 sse4_2 ssse3 vmx bogomips: 49599
Speed: 980 MHz min/max: 800/3100 MHz Core speeds (MHz): 1: 980 2: 956 3: 935 4: 956 5: 982 6: 966 7: 949 8: 929
Graphics: Device-1: Intel HD Graphics 630 vendor: Hewlett-Packard driver: i915 v: kernel bus ID: 00:02.0 chip ID: 8086:591b
Device-2: Advanced Micro Devices [AMD/ATI] Polaris 22 XL [Radeon RX Vega M GL] vendor: Hewlett-Packard
driver: amdgpu v: kernel bus ID: 01:00.0 chip ID: 1002:694e
Device-3: Cheng Uei Precision Industry (Foxlink) HP Wide Vision FHD Camera type: USB driver: uvcvideo bus ID: 1-5:2
chip ID: 05c8:0815
Display: x11 server: Mageia X.org 1.20.8 compositor: kwin_x11 driver: intel,v4l resolution: 1: 1920x1080
2: 1920x1080 s-dpi: 96
OpenGL: renderer: Mesa Intel HD Graphics 630 (KBL GT2) v: 4.6 Mesa 20.1.1 direct render: Yes
Describe the issue
This is an issue experienced in the open source Godot Engine game engine.
Corresponding Godot bug report: https://github.com/godotengine/godot/issues/40601
When compiling Godot with GCC 10.2.0 RC 1 (other versions untested) with optimizations enabled (-O1
or -O2
reproduce it, -O0
doesn't), Godot's Vulkan rendering backend will trigger a crash in RADV on my AMD Radeon RX Vega M GL.
Here's the stacktrace from a build with -g3 -O1
:
Thread 1 "godot.linuxbsd." received signal SIGSEGV, Segmentation fault.
0x00007ffff78a6ce4 in __memmove_avx_unaligned_erms () from /lib64/libc.so.6
(gdb) bt
#0 0x00007ffff78a6ce4 in __memmove_avx_unaligned_erms () from /lib64/libc.so.6
#1 0x00007ffff54c97ef in memcpy (__len=<optimized out>, __src=0x66f78fc, __dest=<optimized out>) at /usr/include/bits/string_fortified.h:34
#2 radv_flush_constants (cmd_buffer=cmd_buffer@entry=0x66f7110, stages=<optimized out>, stages@entry=31) at ../src/amd/vulkan/radv_cmd_buffer.c:2410
#3 0x00007ffff54ca615 in radv_upload_graphics_shader_descriptors (cmd_buffer=cmd_buffer@entry=0x66f7110, pipeline_is_dirty=pipeline_is_dirty@entry=true) at ../src/amd/vulkan/radv_cmd_buffer.c:2651
#4 0x00007ffff54cd6e0 in radv_draw (cmd_buffer=0x66f7110, info=info@entry=0x7fffffffc0d0) at ../src/amd/vulkan/radv_cmd_buffer.c:4837
#5 0x00007ffff54cf69e in radv_CmdDrawIndexed (commandBuffer=<optimized out>, indexCount=<optimized out>, instanceCount=<optimized out>, firstIndex=<optimized out>, vertexOffset=<optimized out>,
firstInstance=<optimized out>) at ../src/amd/vulkan/radv_cmd_buffer.c:4901
#6 0x0000000001a69bf1 in vkCmdDrawIndexed (commandBuffer=<optimized out>, indexCount=indexCount@entry=6, instanceCount=instanceCount@entry=1, firstIndex=<optimized out>, vertexOffset=vertexOffset@entry=0,
firstInstance=firstInstance@entry=0) at thirdparty/vulkan/loader/trampoline.c:1698
#7 0x0000000001a1beb7 in RenderingDeviceVulkan::draw_list_draw (this=0x62ac330, p_list=<optimized out>, p_use_indices=<optimized out>, p_instances=1, p_procedural_vertices=0)
at drivers/vulkan/rendering_device_vulkan.cpp:6228
#8 0x0000000003362a46 in RasterizerCanvasRD::_render_item (this=this@entry=0x7fffe8427020, p_draw_list=p_draw_list@entry=2, p_item=p_item@entry=0x8d31ca0, p_framebuffer_format=p_framebuffer_format@entry=2,
p_canvas_transform_inverse=..., current_clip=@0x7fffffffc758: 0x0, p_lights=<optimized out>, p_pipeline_variants=<optimized out>) at servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp:788
#9 0x00000000033648c9 in RasterizerCanvasRD::_render_items (this=this@entry=0x7fffe8427020, p_to_render_target=..., p_to_render_target@entry=..., p_item_count=<optimized out>, p_canvas_transform_inverse=...,
p_lights=p_lights@entry=0x0, p_screen_uniform_set=..., p_screen_uniform_set@entry=...) at servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp:1362
#10 0x000000000336552f in RasterizerCanvasRD::canvas_render_items (this=0x7fffe8427020, p_to_render_target=..., p_item_list=<optimized out>, p_modulate=..., p_light_list=0x0, p_canvas_transform=...)
at servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp:1524
#11 0x0000000003354900 in RenderingServerCanvas::_render_canvas_item_tree (this=this@entry=0x6654f90, p_to_render_target=..., p_to_render_target@entry=..., p_child_items=<optimized out>,
p_child_item_count=p_child_item_count@entry=1, p_canvas_item=p_canvas_item@entry=0x0, p_transform=..., p_clip_rect=..., p_modulate=..., p_lights=0x0) at servers/rendering/rendering_server_canvas.cpp:71
#12 0x0000000003354a63 in RenderingServerCanvas::render_canvas (this=0x6654f90, p_render_target=..., p_canvas=p_canvas@entry=0x7735320, p_transform=..., p_lights=0x0, p_masked_lights=p_masked_lights@entry=0x0,
p_clip_rect=...) at servers/rendering/rendering_server_canvas.cpp:265
#13 0x00000000031bd038 in RenderingServerViewport::_draw_viewport (this=this@entry=0x677ad90, p_viewport=p_viewport@entry=0x77342d0, p_eye=p_eye@entry=XRInterface::EYE_MONO)
at servers/rendering/rendering_server_viewport.cpp:257
#14 0x00000000031be22a in RenderingServerViewport::draw_viewports (this=0x677ad90) at servers/rendering/rendering_server_viewport.cpp:413
#15 0x000000000319aefe in RenderingServerRaster::draw (this=0x6076660, p_swap_buffers=<optimized out>, frame_step=0.36177700757980347) at servers/rendering/rendering_server_raster.cpp:112
#16 0x00000000031c3680 in RenderingServerWrapMT::draw (this=0x6caea70, p_swap_buffers=<optimized out>, frame_step=0.36177700757980347) at servers/rendering/rendering_server_wrap_mt.cpp:91
#17 0x0000000000e3dc06 in Main::iteration () at main/main.cpp:2204
#18 0x0000000000e1e256 in OS_LinuxBSD::run (this=this@entry=0x7fffffffd1c0) at platform/linuxbsd/os_linuxbsd.cpp:238
#19 0x0000000000e1d1a7 in main (argc=1, argv=0x7fffffffd6b8) at platform/linuxbsd/godot_linuxbsd.cpp:55
Some more info:
- Compiling with Clang 10.0 does not trigger the issue.
- Compiling with GCC 10.2.0 RC 1 without optimizations does not trigger the issue.
- No error in
dmesg
. - My kernel, mesa and gcc versions are all those packaged in Mageia Cauldron (dev version of Mageia 8). For details on their packaging: mesa.spec, gcc.spec.
So it appears to be an optimization bug from GCC, but before reporting it to GCC developers, I wanted to report it here and see if it can be confirmed, further debugged to give GCC developers a minimal reproduction code on the bad optimization.
Regression
Not tested.
Steps to reproduce
I don't have a minimal reproducer, but Godot is open source and easy to compile.
- Clone https://github.com/godotengine/godot (the Vulkan backend is on the
master
branch) - See https://docs.godotengine.org/en/latest/development/compiling/compiling_for_linuxbsd.html for what dependencies to install
- Run
scons -j8 p=linuxbsd tools=yes target=debug CCFLAGS="-O2"
. Defaults to GCC,target=debug
has no optimization and-g3
, butCCFLAGS="-O2"
will add optimizations (alternatively, usescons -j8 p=linuxbsd tools=yes target=release_debug debug_symbols=full
for-g2 -O2
). - Run the binary in
bin/godot.linuxbsd.tools.64
(orbin/godot.linuxbsd.opt.tools.64
), it should segfault.