如何通过Win32共享句柄反向获取Vulkan Image元信息
你无法通过Vulkan导出的Win32 opaque共享内存句柄,直接反向查询关联的Vulkan Image元信息,Vulkan和Win32层面都没有提供对应能力。
原因说明
你导出的vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32类型句柄,本质是对底层物理显存块的跨进程引用,本身不携带任何Vulkan Image层面的创建参数:包括图像尺寸、像素格式、mip等级数、内存绑定偏移、tiling模式、usage标志这类信息都不会存储在句柄中。
你贴的两份示例代码本身也能印证这点:不管是Vulkan侧导入共享内存,还是OpenGL侧导入内存创建纹理,所有Image相关参数都是提前已知的,没有任何一步逻辑是从句柄读取参数。
注意:不存在“拿到句柄后调用某个API自动获取所有Image参数”的操作。
vkGetImageMemoryRequirements这类接口必须传入一个已经创建完成的合法VkImage对象才能调用,如果不知道Image的基础创建参数,连这个占位用的VkImage都无法创建,根本走不到查询内存要求的步骤。
可行实现方案
实际开发中直接在跨进程传递句柄时,同步传递对应的Image元数据即可,常用的两种实现方式:
- 通过IPC同步传递元数据:导出句柄的进程把创建Image用到的所有必要参数打包,通过任意进程间通信方式(命名管道、共享内存、窗口消息、自定义RPC都可以)和句柄一起发给目标进程。导入端拿到参数后,按完全一致的参数创建VkImage,再绑定导入的共享显存即可。必须传递的参数包括:
VkImageCreateInfo的全部字段:图像尺寸、像素格式、mip层数、array层数、采样数、tiling模式、usage标志、创建标志- 显存相关参数:显存分配总大小、内存类型索引,如果是从大显存块做的子分配,还要传递Image绑定的显存偏移量
- 如果需要在导入端同步创建OpenGL纹理,还要额外传递对应的GL内部格式、纹理过滤/环绕参数这些GL侧必填值
- 固定参数约定:如果你的共享场景是固定业务逻辑(比如所有共享纹理都是RGBA8_UNORM格式、2D纹理、仅作采样使用、mip数生成规则固定),可以在通信的两个进程中提前约定死所有创建参数,不需要额外做元数据传输,导入时直接用约定参数创建Image绑定显存即可。这种方式实现成本最低,适合内部固定流程的场景。
对你贴出代码的补充说明
你第一段创建GL纹理的代码里,texGl.mipLevels、format、texGl.imgSize、info.offset这些值,全是导出进程本地已经持有的上下文信息,没有一个是从Win32句柄中读取的。跨进程共享时这些值必须随句柄一起传递,否则导入端无法填充glTextureStorageMem2DEXT这类接口的必填参数,自然也没法创建匹配的纹理对象。
你贴的google-image-import示例逻辑也是同理,代码里的num_images、内存类型匹配逻辑、内存对齐大小计算,都是基于提前已知的Image参数完成的,不是从句柄反查得到的。
内容的提问来源于stack exchange,提问作者cfl997

