Skip to content

Making a Vulkan layer? #619

Open
Open

Description

@YellowOnion

I was gonna ask this on matrix but the link doesn't work anymore, the cert on the website seems dead.

My Vulkan understanding is rather basic, I'm using this guide https://renderdoc.org/vulkan-layer-guide.html

I've been trying to understand the API and to create the export shims to call a more high level polymorphic implementation that I want to write.

For clarity sake, I'm using qualified imports.

I want to implement createInstance, for this I'm trying to write a shim to convert to the high level API.

foreign export ccall "Kairos_createInstance" c_createInstance
  :: Ptr (Vk.SomeStruct Vk.InstanceCreateInfo)
  -> Ptr (Vk.AllocationCallbacks)
  -> Ptr (Ptr Vk.Instance_T)
  -> IO Vk.Result

This seems to work, but I'm unsure how to correctly convert Ptr (Vk.SomeStruct a) to the type (Vk.Extendss b es) => (a b es), I think I want to use peekSomeCStruct , but the return type is still just SomeStruct?

I'm struggling to piece all the parts together, I don't feel very confident with my understanding of the higher level polymorphic types, and grepping the source code I can't find many examples of my use case.

Any help would be much appreciated.

Also as an aside, I have a hunch due to the nature of vulkan layers, I need to recompile this library with safe calls?

Activity

  1. dpwiz commented on Mar 21, 2026

    @dpwiz
    Collaborator

    Is there any specific thing that you want to do with the struct or its extensions?
    If you only need the first layer and let the rest pass through, then you're set. SomeStruct will hide the chain so you wouldn't be bothered by the rest.
    If you want to find some particular extension in the pNext chain that would involve some more dancing.
    Try to create an extended structure, poke it to a buffer, then experiment in REPL with whatever the Extends module provides.

  2. YellowOnion commented on Mar 21, 2026

    @YellowOnion
    Author

    There's a few things that need to be done with VkLayerInstanceCreateInfo, from my understanding this is core to making any sort of layer.

    I eventually got something "working", ended up with this error:

     peekChainHead: invalid argument (Unrecognized struct type: STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)
    

    Here's the code:

    foreign export ccall "Kairos_GetInstanceProcAddr" c_getInstanceProcAddr
      :: Ptr Vk.Instance_T
      -> CString
      -> IO Vk.PFN_vkVoidFunction
    
    c_getInstanceProcAddr :: Ptr Vk.Instance_T -> CString -> IO (Vk.PFN_vkVoidFunction)
    c_getInstanceProcAddr inst name' = do
      name <- peekCString name'
      putStrLn $ "getInstance for " ++ name
    
      return $ castFunPtr $ case name of
        "vkCreateInstance" -> pCreateInstance
        _                  -> nullFunPtr
    
    foreign import ccall "&Kairos_CreateInstance"
            pCreateInstance :: FunPtr c_createInstance
    foreign export ccall "Kairos_CreateInstance" c_createInstance
      :: Ptr (Vk.SomeStruct Vk.InstanceCreateInfo)
      -> Ptr (Vk.AllocationCallbacks)
      -> Ptr (Vk.Instance_T)
      -> IO Vk.Result
    
    c_createInstance
      :: Ptr (Vk.SomeStruct Vk.InstanceCreateInfo)
      -> Ptr (Vk.AllocationCallbacks)
      -> Ptr (Vk.Instance_T)
      -> IO Vk.Result
    c_createInstance info cbs inst = do
      info' <- Vk.peekSomeCStruct info
      cbs' <- Vk.peekCStruct cbs
      inst' <- Vk.Instance inst <$> initInstanceCmds inst
      Vk.withSomeStruct info' $ \info -> do
        createInstance info cbs' inst'
    
    createInstance :: (Vk.Extendss Vk.InstanceCreateInfo a, Vk.PokeChain a)
                   => Vk.InstanceCreateInfo a
                   -> Vk.AllocationCallbacks
                   -> Vk.Instance
                   -> IO Vk.Result
    createInstance a b c = do
      putStrLn "Instance Created"
      return Vk.SUCCESS

    I guess VkLayerInstanceCreateInfo is missing from vulkan, this seems to be provided by vk_layer.h, not vulkan.h, this would need a fix right?

    I can probably create an type class instance for it, but with the way peekChainHead uses pattern matching, it would need a fix in that to fully work.

    Edit: corrected to VkLayerInstanceCreateInfo

  3. dpwiz commented on Mar 21, 2026

    @dpwiz
    Collaborator

    You may want to cast your ptr to BaseInStructure and manually iterate on its sType/next until you find the STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO (or other thing) you need, then use its ptr from next to peek a known type.

  4. dpwiz commented on Mar 21, 2026

    @dpwiz
    Collaborator

    If you manage to get it working, I'm happy to accept a new vulkan-layer package (=

  5. YellowOnion commented on Mar 22, 2026

    @YellowOnion
    Author

    BTW I found another URI for accessing the matrix channel, so if you want to talk there it might be easier for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions