MarijnS95
<!-- ⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ If you do not follow the guidelines, or do not use the template below, your issue will be closed with no exceptions! ⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ The template below shows what you need to include in a good bug report, and you MUST use it. More information in the docs: https://github.com/baldurk/renderdoc/blob/v1.x/docs/CONTRIBUTING/Filing-Issues.md It is *expressly* forbidden to ask for help with capturing copyrighted programs that you did not create and do not have the source code for. For example this includes capturing commercial games that you did not create, or capturing Google Maps or Google Earth. I'm happy to help, but you have to ensure I fully understand what you want and have the information I need. If you're unsure, please read the guide above for full information on what is expected for filing issues. --> ## Description of Bug <!-- Here you can enter a description of what you are doing and what bug you are running into. --> <!-- This is a good time to describe what you want to do, what is actually happening, and what you'd expect to happen instead. --> We have a custom application (desktop and Android) that relies on features like buffer device address and ray tracing. When the Vulkan _instance and physical device_ agree on Vulkan >= 1.2, we set our `apiVersion` to >= 1.2 and use `VkPhysicalDeviceBufferDeviceAddressFeatures` without enabling the `VK_KHR_buffer_device_address` device extension, because it was promoted to 1.2. Unfortunately **some times** our app on Android fails to start under RenderDoc, showing a log and crash like the following: ``` 09-11 22:10:36.996 19878 19934 I renderdoc: @6aa4603c0000001a@ RDOC 019878: [22:10:36] vk_device_funcs.cpp(5056) - Log - Acceleration structures enabled, ALL MEMORY WILL BE MARKED AS BDA ... 09-11 22:10:37.102 19878 19951 I renderdoc: @6aa4603d00000037@ RDOC 019878: [22:10:37] vk_resource_funcs.cpp(2251) - Error - Device address bit specified but no device address extension enabled ... 09-11 22:10:37.178 19878 19951 F libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 19951 (RenderLoop Rend), pid 19878 (our app) ... 09-11 22:10:37.396 19963 19963 F DEBUG : #01 pc 0000000000e5fa70 /data/app/~~JF18wqHwacIm8bbJiyWyiA==/org.renderdoc.renderdoccmd.arm64-hjXlT1ceqpPPCSkO4I78hQ==/lib/arm64/libVkLayer_GLES_RenderDoc.so (WrappedVulkan::vkAllocateMemory(VkDevice_T*, VkMemoryAllocateInfo const*, VkAllocationCallbacks const*, VkDeviceMemory_T**)+6776) (BuildId: cca8fae158109ffc) ``` This never happens on desktop. AI [^1] deduced that the actual crash in `vkAllocateMemory` is an unconditional call to one of the BDA functions, because the extension wasn't initialized. [^1]: Noting that this issue was hand-written though, AI was only used to analyze some of the code and point me to the right "assumed" call sites where things are going wrong. https://github.com/baldurk/renderdoc/blob/0628f10b9a21d21f4230dbf7d925211c128238ce/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp#L826-L839 Not reading too much into the crash itself, I'd rather like to know why [the above error about `ext_KHR_buffer_device_address` not being initialized](https://github.com/baldurk/renderdoc/blob/0628f10b9a21d21f4230dbf7d925211c128238ce/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp#L2211) is **sometimes** getting thrown in the first place. Quick side-note: when manually enabling the `VK_KHR_buffer_device_address` extension, this problem only moves to the next 1.2-stabilized extension: `VK_KHR_timeline_semaphore` and us loading `vkWaitSemaphore()`. ### Implied cause On Android, thanks to Adreno logs, we see that multiple instances are being created on different API versions. On a functional run (this one was taken without RenderDoc to see the original `Engine name`): ``` 09-12 16:43:55.277 12272 12311 I AdrenoVK-0: Engine Name : android framework 09-12 16:43:55.277 12272 12311 I AdrenoVK-0: Engine Version : 0x00000000 09-12 16:43:55.277 12272 12311 I AdrenoVK-0: Api Version : 0x00401000 ... 09-12 16:43:55.288 12272 12318 I AdrenoVK-0: Engine Name : Our App 09-12 16:43:55.288 12272 12318 I AdrenoVK-0: Engine Version : 0x00001000 09-12 16:43:55.288 12272 12318 I AdrenoVK-0: Api Version : 0x00403000 ``` **Android initializes an `android framework` instance**, where `0x00401000` corresponds to Vulkan 1.1 and our app's `0x00403000` corresponds to Vulkan 1.3. On a broken run with RenderDoc capturing however, these are the (slightly stripped for brevity) capture logs: ``` renderdoc: @6aa564af00000010@ RDOC 011566: [16:41:51] vk_layer.cpp( 70) - Log - Creating internal instance to bump layer refcount vulkan : Loaded layer VK_LAYER_RENDERDOC_Capture ... AdrenoVK-0: Engine Name : RenderDoc AdrenoVK-0: Engine Version : 0x0042f000 AdrenoVK-0: Api Version : 0x00403000 vulkan : internal vkGetInstanceProcAddr called for vkCreateInstance with an instance renderdoc: @6aa564af00000011@ RDOC 011566: [16:41:51] vk_device_funcs.cpp( 975) - Log - Initialised capture layer in Vulkan instance. renderdoc: @6aa564af00000012@ RDOC 011566: [16:41:51] vk_layer.cpp( 89) - Log - Created own instance B40000734CA594D0: VK_SUCCESS ... AdrenoVK-0: Engine Name : RenderDoc AdrenoVK-0: Engine Version : 0x0042f000 AdrenoVK-0: Api Version : 0x00403000 vulkan : internal vkGetInstanceProcAddr called for vkCreateInstance with an instance renderdoc: @6aa564af00000013@ RDOC 011566: [16:41:51] core.cpp(2317) - Log - Adding Vulkan device frame capturer for 0xB40000747C987A30 renderdoc: @6aa564af00000014@ RDOC 011566: [16:41:51] vk_device_funcs.cpp( 975) - Log - Initialised capture layer in Vulkan instance. ... AdrenoVK-0: Engine Name : RenderDoc AdrenoVK-0: Engine Version : 0x0042f000 AdrenoVK-0: Api Version : 0x00401000 vulkan : internal vkGetInstanceProcAddr called for vkCreateInstance with an instance renderdoc: @6aa564af0000001a@ RDOC 011566: [16:41:51] core.cpp(2317) - Log - Adding Vulkan device frame capturer for 0xB40000747C999370 renderdoc: @6aa564af0000001b@ RDOC 011566: [16:41:51] vk_device_funcs.cpp( 975) - Log - Initialised capture layer in Vulkan instance. ``` **As you can see here, the 1.1 API instance is last!** Thanks to some AI assistance, it seems that the global instance is being **overwritten** each time the captured app calls `vkCreateInstance`, so the last instance and version wins despite every instance being wrapped individually: https://github.com/baldurk/renderdoc/blob/ce50614f0e77d007982b776cbc85b8494720459d/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp#L809-L810 https://github.com/baldurk/renderdoc/blob/ce50614f0e77d007982b776cbc85b8494720459d/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp#L833 https://github.com/baldurk/renderdoc/blob/ce50614f0e77d007982b776cbc85b8494720459d/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp#L853-L855 When our app ultimately calls `vkCreateDevice()`, that 1.1 API version is copied: https://github.com/baldurk/renderdoc/blob/0628f10b9a21d21f4230dbf7d925211c128238ce/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp#L5133-L5134 And reading device extensions, just down at these lines: https://github.com/baldurk/renderdoc/blob/0628f10b9a21d21f4230dbf7d925211c128238ce/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp#L5156-L5157 Will falsely flag `ext_KHR_buffer_device_address` as "not supported" because we never put the name in `ppEnabledExtensionNames` (as our app implied Vulkan 1.3 support), while `record->instDevInfo->vulkanVersion` is initialized to Vulkan 1.1 but `ver` here requires Vulkan 1.2. ### How to solve? I'd love to have PR'd a solution, but I believe anything "good enough" involves supporting this multi-instance scenario (and tracking (p)device parents properly) rather than a workaround that patches through a "more accurate" Vulkan version. Happy to be proven wrong (a more simple solution exists, or this AI reduction is truly incorrect) though! Also happy to spend more AI tokens on this if it'd help (writing a repro in a test-case, or proposing/drafting an actual fix. Thanks for reading all this either way! ## Steps to reproduce <!-- Please list the steps that someone can take to reproduce the bug. --> <!-- If you can share your capture or your application, PLEASE DO THAT NOW. It is by far the easiest way to demonstrate a bug. You can share it privately via email to [email protected] and mention it here. --> <!-- If you cannot share because of privacy or other reasons, please state that and give as much extra information as you can. --> <!-- Steps like "run my application" or "load this capture" are not useful unless you share the application or capture. Be specific! --> Since this situation happens specifically on Android and depends on the "random" order of instance creation, I think I can set up a small Vulkan sample that always initializes a Vulkan 1.2+ instance plus stabilized feature, then initializes a second Vulkan instance on 1.1, and ultimately create a device on the 1.2 instance while trying to use 1.2 functionality on it, like BDA. Let me know if that's needed! ## Environment <!-- if you are running a nightly build, list the date or commit hash for the version --> * RenderDoc version: Latest compiled from 60c83d0483fa848e5f90123739bcc1cc0e31f4f2 * Operating System: Android * Graphics API: Vulkan 1.3 <!-- More details here never hurt! For example your GPU, driver version, etc. --> ## Driveby issues flagged by myself and AI - While attempting to debug this, I first landed on https://github.com/baldurk/renderdoc/blob/0628f10b9a21d21f4230dbf7d925211c128238ce/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp#L4432-L4437 (before knowing that's for _replay_, not _capture_!): this only checks if the captured app had enabled `vulkan12Features.bufferDeviceAddress`, but it doesn't check if it was enabled via `VkPhysicalDeviceBufferDeviceAddressFeatures` instead? - I haven't tested yet, but that'd mean our captures likely won't play back? - Same issue for the other checks, supposedly. - AI also flagged that `vulkan12Features` is _what the original captured app enabled_, versus `avail12Features` which was freshly queried what the replay device supports. - For things like https://github.com/baldurk/renderdoc/blob/ce50614f0e77d007982b776cbc85b8494720459d/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp#L5154-L5165, it flagged that if the calling app enabled `0` extensions, the loop never executes and neither does the version check for promoted extensions to enable `vulkanVersion >= ver`...