Vulkan的VkImage和OpenGL的Texture2D互转的3种方法

Vulkan的纹理和OpenGL的纹理之间共享的解决方案,

因为项目的功能需要同时引入OpenGL和Vulkan,又因为效率的影响必须想办法优化,两者之间需要互相访问互相转换的高效方案。

Vulkan的纹理图像类型是:VkImage,OpenGL的纹理类型是:Texture2D

此文原创,收集和编写不易,望能珍惜。

1. NVIDIA GPU Only的方案

在OpenGL 4.5 规范(简介)第 1 章的补充中新增了一个扩展GL_NV_draw_vulkan_image

有提供如下函数

glDrawVkImageNV
glGetVkProcAddrNV
glSignalVkFenceNV
glSignalVkSemaphoreNV
glWaitVkSemaphoreNV

对应Vulkan这边也有NVIDIA CPU Only的方案新增(已在Vulkan1.0之后的版本弃用)

VK_NV_external_memory
VK_NV_external_memory_capabilities

 

2. Windows Only的方案

OpenGL新增了扩展

GL_EXT_memory_object_win32
---------------------------
  glImportMemoryWin32HandleEXT
  glImportMemoryWin32NameEXT

GL_EXT_memory_object
---------------------
  glBufferStorageMemEXT
  glCreateMemoryObjectsEXT
  glDeleteMemoryObjectsEXT
  glGetMemoryObjectParameterivEXT
  glGetUnsignedBytei_vEXT
  glGetUnsignedBytevEXT
  glIsMemoryObjectEXT
  glMemoryObjectParameterivEXT
  glNamedBufferStorageMemEXT
  glTexStorageMem1DEXT
  glTexStorageMem2DEXT
  glTexStorageMem2DMultisampleEXT
  glTexStorageMem3DEXT
  glTexStorageMem3DMultisampleEXT
  glTextureStorageMem1DEXT
  glTextureStorageMem2DEXT
  glTextureStorageMem2DMultisampleEXT
  glTextureStorageMem3DEXT
  glTextureStorageMem3DMultisampleEXT

对应Vulkan也有与之对应的函数:

#ifdef VK_KHR_external_memory_win32
//获取内存对象的 Windows句柄
VkResult vkGetMemoryWin32HandleKHR(
    VkDevice                                    device,
    const VkMemoryGetWin32HandleInfoKHR*        pGetWin32HandleInfo,
    HANDLE*                                     pHandle);

//获取外部内存Win32句柄的属性
//与Vulkan兼容的Windows内存句柄也可以由使用超出本规范范围的方法的非Vulkan API,如OpenGL。
VkResult vkGetMemoryWin32HandlePropertiesKHR(
    VkDevice                                    device,
    VkExternalMemoryHandleTypeFlagBits          handleType,
    HANDLE                                      handle,
    VkMemoryWin32HandlePropertiesKHR*           pMemoryWin32HandleProperties);
#endif

3. 其他操作系统的方案

OpenGL的扩展函数:

GL_EXT_memory_object_fd
------------------------
  glImportMemoryFdEXT

GL_EXT_memory_object
---------------------
  glBufferStorageMemEXT
  glCreateMemoryObjectsEXT
  glDeleteMemoryObjectsEXT
  glGetMemoryObjectParameterivEXT
  glGetUnsignedBytei_vEXT
  glGetUnsignedBytevEXT
  glIsMemoryObjectEXT
  glMemoryObjectParameterivEXT
  glNamedBufferStorageMemEXT
  glTexStorageMem1DEXT
  glTexStorageMem2DEXT
  glTexStorageMem2DMultisampleEXT
  glTexStorageMem3DEXT
  glTexStorageMem3DMultisampleEXT
  glTextureStorageMem1DEXT
  glTextureStorageMem2DEXT
  glTextureStorageMem2DMultisampleEXT
  glTextureStorageMem3DEXT
  glTextureStorageMem3DMultisampleEXT

Vulkan的与之对应的扩展函数:

#ifdef VK_KHR_external_memory

#endif

#ifdef VK_KHR_external_memory_capabilities
//需要支持Vulkan 1.0,需要启用VK_KHR_get_physical_device_properties2

void vkGetPhysicalDeviceExternalBufferProperties(
    VkPhysicalDevice                            physicalDevice,
    const VkPhysicalDeviceExternalBufferInfo*   pExternalBufferInfo,
    VkExternalBufferProperties*                 pExternalBufferProperties);

typedef struct VkExternalMemoryProperties {
    //externalMemoryFeatures是 VkExternalMemoryFeatureFlagBits 的位掩码,指定的功能。
    VkExternalMemoryFeatureFlags       externalMemoryFeatures;
    //exportFromImportedHandleTypes是 VkExternalMemoryHandleTypeFlagBits 的位掩码,指定哪些类型的可以从中导出导入的手柄。
    VkExternalMemoryHandleTypeFlags    exportFromImportedHandleTypes;
    //compatibleHandleTypes是 VkExternalMemoryHandleTypeFlagBits 的位掩码,指定可以在创建与外部存储器兼容的图像。
    VkExternalMemoryHandleTypeFlags    compatibleHandleTypes;
} VkExternalMemoryProperties;

#endif

 

posted @ 2023-02-10 13:36  重庆Debug  阅读(962)  评论(0编辑  收藏  举报