Vulkan 之 Layers

Layers 暴露给api层,不像传统图形API集成在驱动里面,开发者根据自己的需要进行开启,最终目的还是为了提高性能。

The Loader

he loader is the central arbiter in the Vulkan runtime. The application talks directly to the loader and only to the loader, which then deals with enumerating and validating the layers requested, enumerating ICDs and organising them and presenting a unified interface to the application.

ICD是就是不同厂商对图形API所做的驱动文件, Vulkan Loader 何时加载 ICD 驱动文件vulkan initialize 这篇文章详细描述了vulkan是如何初始化,以及为什么需要这么做。

那么这么做的意义是什么呢?直接调用这些函数指针不就完事了吗?恰巧vulkan的一个思想就是,去除掉验证层,那么验证层能放在何处?也就是放在这个SDK里,类似各种Graphic Debugger的实现,Vulkan有很多Validation Layer,可以根据需求载入,在真正的函数调用之前,截取一些信息,获得一些信息,最后再调用真正的接口。也就是说整个SDK不仅仅是一个函数指针获取器,还是一个Graphic Debugger。

 

可以自定义一个layer,然后在layer里面指定自己需要监控的函数。

{
  "file_format_version" : "1.0.0",
  "layer" : {
    "name": "VK_LAYER_SAMPLE_SampleLayer",
    "type": "GLOBAL",
    "library_path": ".\\sample_layer.dll",
    "api_version": "1.0.0",
    "implementation_version": "1",
    "description": "Sample layer - https://renderdoc.org/vulkan-layer-guide.html",
    "functions": {
      "vkGetInstanceProcAddr": "SampleLayer_GetInstanceProcAddr",
      "vkGetDeviceProcAddr": "SampleLayer_GetDeviceProcAddr"
    },
  }
}

When our layer's vkCreateInstance is called, the loader has inserted extra data that we can use for initialisation. In particular, it makes use of Vulkan's sType/pNext extensibility. In the VkInstanceCreateInfo struct, it begins in exactly the same way as many other Vulkan structures with a VkStructureType sType; and const void *pNext. These two elements define a linked list of extra extension information. You can iterate through the list even if you don't recognise all of the entries in the list because they all start with the sType/pNext.

VK_LAYER_EXPORT VkResult VKAPI_CALL SampleLayer_CreateInstance(
    const VkInstanceCreateInfo*                 pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkInstance*                                 pInstance)
{
  VkLayerInstanceCreateInfo *layerCreateInfo = (VkLayerInstanceCreateInfo *)pCreateInfo->pNext;

  // step through the chain of pNext until we get to the link info
  while(layerCreateInfo && (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO ||
                            layerCreateInfo->function != VK_LAYER_LINK_INFO))
  {
    layerCreateInfo = (VkLayerInstanceCreateInfo *)layerCreateInfo->pNext;
  }

  if(layerCreateInfo == NULL)
  {
    // No loader instance create info
    return VK_ERROR_INITIALIZATION_FAILED;
  }

  PFN_vkGetInstanceProcAddr gpa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
  // move chain on for next layer
  layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;

  PFN_vkCreateInstance createFunc = (PFN_vkCreateInstance)gpa(VK_NULL_HANDLE, "vkCreateInstance");

  VkResult ret = createFunc(pCreateInfo, pAllocator, pInstance);

  // fetch our own dispatch table for the functions we need, into the next layer
  VkLayerInstanceDispatchTable dispatchTable;
  dispatchTable.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)gpa(*pInstance, "vkGetInstanceProcAddr");
  dispatchTable.DestroyInstance = (PFN_vkDestroyInstance)gpa(*pInstance, "vkDestroyInstance");
  dispatchTable.EnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties)gpa(*pInstance, "vkEnumerateDeviceExtensionProperties");

  return VK_SUCCESS;
}

Reference:

1、Brief guide to Vulkan layers

猜你喜欢

转载自www.cnblogs.com/khacker/p/12286261.html