# Vulkan How do you go about abstracting Vulkan's verbosity ?

This topic is 408 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi. I'm currently building a small Vulkan engine, I find one of the most challenging things to do is abstracting, simplifying the Vulkan interface, especially the very long structs (ie Vk---CreateInfo). You quickly end up with hundreds of lines of just filling structs.

To simplify that, I thought of wrapping the most important structs in classes with default values and helper functions, as shown in the following example:

class GraphicsPipeline
{
public:
GraphicsPipeline();

void create(const VkDevice* device);
void dealloc(const VkDevice* device);
VkPipeline getPipeline();

void resetToDefault();

...
Some helper functions
...

VkGraphicsPipelineCreateInfo pipelineCreateInfo;
private:
VkPipeline m_pipeline;
...
};


The resetToDefault() function is mainly where the abstraction takes place: it fills the pipelineCreateInfo attribute with default values.

Since the pipelineCreateInfo attribute is public, it allows the programmer to change anything he wants within the structure (in theory) and expand upon the default values.

This all works great in theory. Unfortunately, there are a few problems with this:

-The VkGraphicsPipelineCreateInfo struct contains pointers to constant structs, therefore forbidding any modification.

This means it is impossible to do that:

      GraphicsPipeline pipeline;
pipeline.pipelineCreateInfo.pRasterizationState->polygonMode = VK_POLYGON_MODE_LINE


This is impossible since VkGraphicsPipelineCreateInfo::pRasterizationState is a pointer to a const:

      const VkPipelineRasterizationStateCreateInfo*    pRasterizationState;


-I may be wrong about that but I feel these Vk---CreateInfo structs are made for what I would call a "temporary instanciation". What makes me say that is the fact the structs contain so much pointers; at first it might not seem like a big deal but I realized it was a problem when creating my wrapper class: if the programmer wants to access any of the pipelineCreateInfo's pointers, they have to have been dynamically allocated before they get accessed. This means that in resetToDefault(), I would need to instanciate EVERY pointer and then recursively instanciate every pointer of the ones I just allocated and it quickly gets very complicated, even impossible. This is without thinking about deallocating everything after (though you could use a std::unique_ptr<>). This makes it very complicated to create a VkGraphicsPipelineCreateInfo attribute which can be filled in at different times.

This is why I come to you guys: How do you go about abstracting Vulkan's verbosity ? or Any ideas of how to simplify Vulkan's interface ? or How to implement Vulkan in an Engine ?

##### Share on other sites

This topic is 408 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628766
• Total Posts
2984583
• ### Similar Content

• By L. Spiro
Home: https://www.khronos.org/vulkan/
SDK: http://lunarg.com/vulkan-sdk/

AMD drivers: http://gpuopen.com/gaming-product/vulkan/ (Note that Vulkan support is now part of AMD’s official drivers, so simply getting the latest drivers for your card should give you Vulkan support.)
NVIDIA drivers: https://developer.nvidia.com/vulkan-driver (Note that Vulkan support is now part of NVIDIA’s official drivers, so simply getting the latest drivers for your card should give you Vulkan support.)
Intel drivers: http://blogs.intel.com/evangelists/2016/02/16/intel-open-source-graphics-drivers-now-support-vulkan/

Quick reference: https://www.khronos.org/registry/vulkan/specs/1.0/refguide/Vulkan-1.0-web.pdf
References: https://www.khronos.org/registry/vulkan/specs/1.0/apispec.html
https://matthewwellings.com/blog/the-new-vulkan-coordinate-system/

GLSL-to-SPIR-V: https://github.com/KhronosGroup/glslang

Sample code: https://github.com/LunarG/VulkanSamples
https://github.com/SaschaWillems/Vulkan
https://github.com/nvpro-samples
https://github.com/nvpro-samples/gl_vk_chopper
https://github.com/nvpro-samples/gl_vk_supersampled
https://github.com/McNopper/Vulkan
https://github.com/GPUOpen-LibrariesAndSDKs/HelloVulkan

C++: https://github.com/nvpro-pipeline/vkcpp
https://developer.nvidia.com/open-source-vulkan-c-api

Getting started: https://vulkan-tutorial.com/
https://renderdoc.org/vulkan-in-30-minutes.html
https://www.khronos.org/news/events/vulkan-webinar
https://developer.nvidia.com/engaging-voyage-vulkan
https://developer.nvidia.com/vulkan-memory-management
https://developer.nvidia.com/opengl-vulkan
https://github.com/vinjn/awesome-vulkan

Utilities: https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator (AMD Memory allocator.)
https://github.com/GPUOpen-LibrariesAndSDKs/Anvil (AMD Miniature Vulkan engine/framework.)

L. Spiro
• By hiya83
(Posted this in graphics forum too, which was perhaps the wrong forum for it)
Hey, I was wondering if on mobile development (Android mainly but iOS as well if you know of it), if there is a GPUView equivalent for whole system debugging so we can figure out if the CPU/GPU are being pipelined efficiently, if there are bubbles, etc. Also slightly tangent question, but do mobile GPU's have a DMA engine exposed as a dedicated Transfer Queue for Vulkan?
Thanks!
• By hiya83
Hey, I was wondering if on mobile development (Android mainly but iOS as well if you know of it), if there is a GPUView equivalent for whole system debugging so we can figure out if the CPU/GPU are being pipelined efficiently, if there are bubbles, etc. Also slightly tangent question, but do mobile GPU's have a DMA engine exposed as a dedicated Transfer Queue for Vulkan?

• I am working on a project which needs to share render targets between Vulkan and DirectX12. I have enabled the external memory extension and now allocate the memory for the render targets by adding the VkExportMemoryInfoKHR to the pNext chain of VkMemoryAllocateInfo. Similarly I have added the VkExternalMemoryImageCreateInfo to the pNext chain of VkImageCreateInfo.
After calling the get win32 handle function, I get some handle pointer which is not null (I assume it is valid).
VkExternalMemoryImageCreateInfoKHR externalImageInfo = {}; if (gExternalMemoryExtensionKHR) { externalImageInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR; externalImageInfo.pNext = NULL; externalImageInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KH imageCreateInfo.pNext = &externalImageInfo; } vkCreateImage(...); VkExportMemoryAllocateInfoKHR exportInfo = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR }; exportInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR; memoryAllocateInfo.pNext = &exportInfo; vkAllocateMemory(...); VkMemoryGetWin32HandleInfoKHR info = { VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR, NULL }; info.memory = pTexture->GetMemory(); info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR; VkResult res = vkGetMemoryWin32HandleKHR(vulkanDevice, &info, &pTexture->pSharedHandle); ASSERT(VK_SUCCESS == res); Now when I try to call OpenSharedHandle from a D3D12 device, it crashes inside nvwgf2umx.dll with the integer division by zero error.
I am now lost and have no idea what the other handle types do.
For example: How do we get the D3D12 resource from the VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR handle?
I also found some documentation on this link but it doesn't help much.