bkaradzic / bgfx

Cross-platform, graphics API agnostic, "Bring Your Own Engine/Framework" style rendering library.
https://bkaradzic.github.io/bgfx/overview.html
BSD 2-Clause "Simplified" License
14.59k stars 1.92k forks source link

[vulkan] example-07-callback does not work well with a tiling wm. #3304

Open mcourteaux opened 3 weeks ago

mcourteaux commented 3 weeks ago

Describe the bug This issue seems related to frame buffers not following nicely the window size.

Starting in Vulkan (with Debug) crashes with:

../../../src/renderer_vk.cpp (683): BGFX ---E-          RenderPass, Validation, 0: Validation Error: [ VUID-VkRenderPassBeginInfo-pNext-02852 ] Object 0: handle = 0xd10d270000000018, type = VK_OBJECT_TYPE_RENDER_PASS; Object 1: handle = 0x27d60e0000000019, type = VK_OBJECT_TYPE_FRAMEBUFFER; | MessageID = 0xdb2c5767 | vkCmdBeginRenderPass(): pRenderPassBegin->renderArea offset.x (0) + extent.width (1280) is greater than framebuffer width (621). The Vulkan spec states: If the pNext chain does not contain VkDeviceGroupRenderPassBeginInfo or its deviceRenderAreaCount member is equal to 0, renderArea.offset.x + renderArea.extent.width must be less than or equal to VkFramebufferCreateInfo::width the framebuffer was created with (https://vulkan.lunarg.com/doc/view/1.3.280.0/linux/1.3-extensions/vkspec.html#VUID-VkRenderPassBeginInfo-pNext-02852)
../../../src/renderer_vk.cpp (683): BGFX ---E-          RenderPass, Validation, 0: Validation Error: [ VUID-VkRenderPassBeginInfo-pNext-02852 ] Object 0: handle = 0xd10d270000000018, type = VK_OBJECT_TYPE_RENDER_PASS; Object 1: handle = 0x27d60e0000000019, type = VK_OBJECT_TYPE_FRAMEBUFFER; | MessageID = 0xdb2c5767 | vkCmdBeginRenderPass(): pRenderPassBegin->renderArea offset.x (0) + extent.width (1280) is greater than framebuffer width (621). The Vulkan spec states: If the pNext chain does not contain VkDeviceGroupRenderPassBeginInfo or its deviceRenderAreaCount member is equal to 0, renderArea.offset.x + renderArea.extent.width must be less than or equal to VkFramebufferCreateInfo::width the framebuffer was created with (https://vulkan.lunarg.com/doc/view/1.3.280.0/linux/1.3-extensions/vkspec.html#VUID-VkRenderPassBeginInfo-pNext-02852)
vkObject(0): ALLOC 0x14e0e4b0 of 424 byte(s)
vkObject(0): ALLOC 0x14e0fe20 of 2552 byte(s)
../../../src/bgfx.cpp(57): ALLOC 0x14e0fdf0 of 32 byte(s)
../../../src/renderer_vk.cpp(3766): ALLOC 0x14e20d20 of 15166 byte(s)
../../../src/renderer_vk.cpp(583): FREE 0x14e0e4b0
../../../src/renderer_vk.cpp(3778): FREE 0x14e20d20
vkCommand(0): ALLOC 0x14d52250 of 24 byte(s)
../../../src/renderer_vk.cpp(583): FREE 0x14d52250
../../../src/renderer_vk.cpp(7969): ASSERT VK_SUCCESS == vkresult -> vkWaitForFences(device, 1, &m_completedFence, 1U, (18446744073709551615UL)); VK error 0xfffffffc: VK_ERROR_DEVICE_LOST
Fatal error: 0x00000000: vkWaitForFences(device, 1, &m_completedFence, 1U, (18446744073709551615UL)); VK error 0xfffffffc: VK_ERROR_DEVICE_LOSTzsh: IOT instruction (core dumped)  ../../.build/linux64_gcc/bin/example-07-callbackDebug

Notice that the validation mechanism is complaining about unmatched resolutions. Starting in OpenGL works for a bit, but you can see that the resolution is wrong:

image

After about 5, the resolution adjusts and I see (note that the updated resolution happened together with the printing of the line I marked in the yellow rectangle):

image

Afterwards quitting the example app crashes it with segfault:

image


Looking at the code, it seems that this 5 seconds is not random:

https://github.com/bkaradzic/bgfx/blob/530a558b11afa4375bdb926b398dbe65a5fc6b4b/examples/07-callback/callback.cpp#L391-L419

I believe the problem to be originating from the fact that the app is not processing events, and therefore not seeing the correct frame size yet. I suspect most people never see this issue, as the app probably gets initialized with the correct resolution and then does 5 seconds of not listening to events, but as I'm using a tiling window manager, the app doesn't get to choose it's resolution at startup. Vulkan says:

pRenderPassBegin->renderArea offset.x (0) + extent.width (1280) is greater than framebuffer width (621). The Vulkan spec states: If the pNext chain does not contain VkDeviceGroupRenderPassBeginInfo or its deviceRenderAreaCount member is equal to 0, renderArea.offset.x + renderArea.extent.width must be less than or equal to VkFramebufferCreateInfo::width the framebuffer was created with (https://vulkan.lunarg.com/doc/view/1.3.280.0/linux/1.3-extensions/vkspec.html#VUID-VkRenderPassBeginInfo-pNext-02852)

You can tell that OpenGL just ignores the window size and just does its thing regarding the first 5 seconds. Vulkan crashes badly with a device lost error.

Looking at the recording with OpenGL, I see:

image

So, it's like the backbuffer actually has the full resolution, but is just not rendered too completely.