[NimLang] SIGSEGV vkCreateImageView()

Problem:
I don’t understand what’s lead to this, I’ve practically copy-pasted the tutorial and translated it to nim.

I’ve verified that the function pointer is not null.

I’ve tracked down the only null value that can be passed to the function comes from ‘vkGetSwapchainImagesKHR’->‘pSwapchainImages’ (see Logs).

I wouldn’t expect it to fill my array with null values, but I’m new so I don’t know.

Would help to at least know a better way to debug this, so that I can track down my null pointer.

Relevant Logs:

vkGetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages) returns VkResult VK_SUCCESS (0):

device:                         VkDevice = 0000000004A76518

swapchain:                      VkSwapchainKHR = 0000000000000000

pSwapchainImageCount:           uint32_t* = 3

pSwapchainImages:               VkImage* = 00000000007203D8

    pSwapchainImages[0]:            VkImage = 0000000000000000

    pSwapchainImages[1]:            VkImage = 0000000000000000

    pSwapchainImages[2]:            VkImage = 0000000000000000

Finished createSwapChain
Attempting createImageViews
Indice: 0
Thread 0, Frame 0:

vkCreateImageView(device, pCreateInfo, pAllocator, pView) returns VkResult
Traceback (most recent call last)
D:\git\RTS\src\main.nim(763) main
D:\git\RTS\src\main.nim(759) main
D:\git\RTS\src\main.nim(701) initVulkan
D:\git\RTS\src\main.nim(519) createImageViews # Note: vkCreateImageView call located here.
SIGSEGV: Illegal storage access. (Attempt to read from nil?)

Seems you have debugged it. Your swapchain is VK_NULL_HANDLE, therefore your swapchain images are garbage. Now see where you got your swapchain from and why it is 0.

It does seem like the pSwapchain is also null.

VkSwapchainKHR* is the pointer to the value right? Weird, I don’t see why that should be the case, it should be “000000000048EB40”, I even verify the address in a print right before it.

Also markdown doesn’t seem to want to keep the whitespace this time. (Fixed)

Relevant Logs:

(____Fn pointer____, _____device_____, ____pCreateInfo___, _, __pSwapchain___)
(“00007FF9241D9BD0”, “00000000048F7AB8”, “00000000006FFB40”, …, “000000000048EB40”)

vkCreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain) returns VkResult VK_SUCCESS (0):

device:                         VkDevice = 00000000048F7AB8
pCreateInfo:                    const VkSwapchainCreateInfoKHR* = 00000000006FFB40:
    sType:                          VkStructureType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR (1000001000)
    pNext:                          const void* = NULL
    flags:                          VkSwapchainCreateFlagsKHR = 0
    surface:                        VkSurfaceKHR = 00000000008BB390
    minImageCount:                  uint32_t = 3
    imageFormat:                    VkFormat = VK_FORMAT_B8G8R8A8_SRGB (50)
    imageColorSpace:                VkColorSpaceKHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR (0)
    imageExtent:                    VkExtent2D = 00000000006FFB6C:
        width:                          uint32_t = 800
        height:                         uint32_t = 600
    imageArrayLayers:               uint32_t = 1
    imageUsage:                     VkImageUsageFlags = 16 (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
    imageSharingMode:               VkSharingMode = VK_SHARING_MODE_EXCLUSIVE (0)
    queueFamilyIndexCount:          uint32_t = 0
    pQueueFamilyIndices:            const uint32_t* = UNUSED
    preTransform:                   VkSurfaceTransformFlagBitsKHR = 1 (VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
    compositeAlpha:                 VkCompositeAlphaFlagBitsKHR = 1 (VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)
    presentMode:                    VkPresentModeKHR = VK_PRESENT_MODE_FIFO_KHR (2)
    clipped:                        VkBool32 = 1
    oldSwapchain:                   VkSwapchainKHR = 0000000000000000
pAllocator:                     const VkAllocationCallbacks* = NULL
pSwapchain:                     VkSwapchainKHR* = 0000000000000000

Yep, just pointer. Seems you are on the right track. Remains to be seen what did you actually pass to vkCreateSwapchain in your code instead of the variable you intended.

EDIT: Actually not sure rn if the api dump shows the pointer value or the handle.

Tell me if you want the entire thing.

'addr “identifier” ’ in Nim is the equivilent of C’s '&“identifier” '.

the echo has ptrToHex(swapChainPtr) which I use to verify that swapChainPtr is a valid ptr, it’s what is at the top of the logs in my previous post.

Nim:

var swapChainPtr = addr swapChain

echo ((ptrToHex(vkCreateSwapchainKHR), toHex(uint(device)), ptrToHex(addr createInfo), nil, ptrToHex(swapChainPtr))

if vkCreateSwapchainKHR(device, addr createInfo, nil, swapChainPtr) != VK_SUCCESS:
raise newException(Exception, “failed to create swap chain!”)

PS: Actually the value in the api_dump for vkCreate* functions is the returned handle. VkSwapchainKHR* is there just to confuse people. If the pointer was nullptr it would probably crash instead…

I guess it returned null handle. Do you query present support? Try asigning something to swapChain if it at least gets overwritten by the vkCreateSwapchainKHR.

It does seem like the swapChain just passes through unedited. (As in I tried editing it, I set it to 10 and it came out unchanged)

weieieierd. Well this will suck to debug. I assume things like vkcube work for you? Or the original version of the tutorial for that matter.

VkCube does work, first thing I did when I installed vulkan and I am assuming if I copy paste the C++ from the tutorial and link it to Vulkan it would work.

BTW do you have Validation Layers enabled? Judging by VkSurfaceKHR = 00000000008BB390 I think not, otherwise it would be some simpler value like 0000000001.

Yeah, I don’t, I never finished implementing them, I am about to try and see what info I can get out of it.

Not much to implement. Just run your code with env set to VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation.

Another weird thing is that, it doesn’t sigsegv on vkCreateSwapchainKHR when api dump is on, else it will sigsegv on vkCreateSwapchainKHR

I am switching to C++ on this journey to create a game engine with Vulkan. Thank you to @krOoze for helping me.

If you are trying to work Vulkan in Nim, I would recommend to stick to OpenGL for a while longer or contribute to NimGL so we get good Vulkan support in Nim. There is a lot of hoops to jump through to get Vulkan working on Nim right now, I am not ready for it, but if anyone reading are, I say good luck.

If someone creates a working Hello triangle in Nim from the Vulkan tutorial do message me the code, I’ll deal with changing the solution here. If you want it here’s my code, it might work on your machine, it’s supposedly a direct translation to Nim: https://pastebin.com/6v6eu5Xp

You can’t develop without Vulkan validation layers. Debugging is close to impossible without them. Also, think about using RenderDoc integration and Vulkan debug markers.

What makes them so awesome is the fact that the are very detailed:

2020-08-05 11:59:32.765303 error 5828 [vulkan-renderer] Validation Error: [ VUID-VkPipelineLayoutCreateInfo-pSetLayouts-parameter ] Object 0: handle = 0x555555906850, type = VK_OBJECT_TYPE_INSTANCE; | MessageID = 0xb3f957d3 | Invalid VkDescriptorSetLayout Object 0x560000000056. The Vulkan spec states: If setLayoutCount is not 0, pSetLayouts must be a valid pointer to an array of setLayoutCount valid VkDescriptorSetLayout handles (https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#VUID-VkPipelineLayoutCreateInfo-pSetLayouts-parameter)

They even contain a link to the corresponding section in Vulkan spec!
Also, after debugging you can turn them off easily.

Best regards
Johannes.

I actually have setup the validation layer, the problem is that VkSwapchainKHR either SIGSEGVs or when dump_api is enabled, it returns a VK_NULL_HANDLE to pSwapchain and the validation layer doesn’t mention anything about it.