Jump to content

Vulkan Nitty-Gritty



I am surprised at how quickly Vulkan development is coming together. The API is ridiculously verbose, but at the same time it eliminates a lot of hidden states and implicit behavior that made OpenGL difficult to work with. I have vertex buffers working now. Vertices in the new engine will always use this layout:

    struct VkVertex
        float position[3];
        float normal[3];
        float texcoords0[2];
        float texcoords1[2];
        float tangent[3];
        unsigned char color[4];
        unsigned char boneweights[4];
        unsigned char boneindices[4];

Note there are no longer vertex binormals, as these are calculated in the vertex shader, with the assumption that the texture coordinates have no shearing. There are two sets of UV coordinates available to use. Up to 256 bones per mesh are supported.

I am creating a few internal classes for Vulkan, out of necessity, and the structure of the new renderer is forming. It's very interesting stuff:

	class VkMesh
		Vk* environment;
		VkBuffer vertexBuffer;
		VmaAllocation allocation;
		VkBuffer indexBuffer;
		VmaAllocation indexallocation;


I have hit the memory management part of Vulkan. Something that used to be neatly done for you is now pushed onto the developer for no apparent reason. I think this is really pointless because we're all going to end up using a bunch of open-source helper libraries anyways. It's like they are partially open-sourcing the driver.


You can't just allocate memory buffers as you wish. From vulkan-tutorial.com:


It should be noted that in a real world application, you're not supposed to actually call vkAllocateMemory for every individual buffer. The maximum number of simultaneous memory allocations is limited by the maxMemoryAllocationCount physical device limit, which may be as low as 4096 even on high end hardware like an NVIDIA GTX 1080. The right way to allocate memory for a large number of objects at the same time is to create a custom allocator that splits up a single allocation among many different objects by using the offset parameters that we've seen in many functions.

You can either implement such an allocator yourself, or use the VulkanMemoryAllocator library provided by the GPUOpen initiative. However, for this tutorial it's okay to use a separate allocation for every resource, because we won't come close to hitting any of these limits for now.

Nvidia explains it visually. It is better to allocate a smaller number of memory blocks and buffers and split them up:


I added the Vulkan Memory Allocator library and it works. I honestly have no idea what it is doing, but I am able to delete the Vulkan instance with no errors so that's good.

Shared contexts are also working so we can have multiple Windows, just like in the OpenGL renderer:

  • Like 4
  • Confused 1


Recommended Comments

The good thing about all this is that to create a simple triangle, you might pass us a function that is "CreateTriangle" with some parameters.  And save us a lot of pain...


Share this comment

Link to comment

That is the biggest goal of an engine, simplifying the end-user's life.  We usually don't have to worry about what's under the hood but it's nice to see details of what Josh is working with.

  • Like 1

Share this comment

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...