从Vulkan渲染到OpenGL是可能的吗?
看起来nVidia有相关方案: https://lunarg.com/faqs/mix-opengl-vulkan-rendering/
其他GPU是否也可以实现呢?
从Vulkan渲染到OpenGL是可能的吗?
看起来nVidia有相关方案: https://lunarg.com/faqs/mix-opengl-vulkan-rendering/
其他GPU是否也可以实现呢?
是的,如果Vulkan实现和OpenGL实现都有适当的扩展可用,则可以实现。
这是来自Vulkan示例存储库中示例应用的屏幕截图,该应用使用OpenGL将简单的shadertoy渲染到纹理中,然后在Vulkan渲染窗口中使用该纹理。
尽管您的问题似乎表明您想要执行相反的操作(使用Vulkan渲染并使用OpenGL显示结果),但是相同的概念仍然适用......在一个API中填充纹理,使用同步确保GPU工作完成,然后在另一个API中使用纹理。 您也可以使用缓冲区执行相同的操作,因此例如,您可以在Vulkan中使用计算操作,然后在OpenGL渲染中使用结果。vk::Image image;
... // create the image as normal
vk::MemoryRequirements memReqs = device.getImageMemoryRequirements(image);
vk::MemoryAllocateInfo memAllocInfo;
vk::ExportMemoryAllocateInfo exportAllocInfo{
vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32
};
memAllocInfo.pNext = &exportAllocInfo;
memAllocInfo.allocationSize = memReqs.size;
memAllocInfo.memoryTypeIndex = context.getMemoryType(
memReqs.memoryTypeBits, vk::MemoryPropertyFlagBits::eDeviceLocal);
vk::DeviceMemory memory;
memory = device.allocateMemory(memAllocInfo);
device.bindImageMemory(image, memory, 0);
HANDLE sharedMemoryHandle = device.getMemoryWin32HandleKHR({
texture.memory, vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32
});
sharedMemoryHandle
是您需要传递给OpenGL的值,以及实际分配大小。在GL侧,您可以这样做...// These values should be populated by the vulkan code
HANDLE sharedMemoryHandle;
GLuint64 sharedMemorySize;
// Create a 'memory object' in OpenGL, and associate it with the memory
// allocated in vulkan
GLuint mem;
glCreateMemoryObjectsEXT(1, mem);
glImportMemoryWin32HandleEXT(mem, sharedMemorySize,
GL_HANDLE_TYPE_OPAQUE_WIN32_EXT, sharedMemoryHandle);
// Having created the memory object we can now create a texture and use
// the memory object for backing it
glCreateTextures(GL_TEXTURE_2D, 1, &color);
// The internalFormat here should correspond to the format of
// the Vulkan image. Similarly, the w & h values should correspond to
// the extent of the Vulkan image
glTextureStorageMem2DEXT(color, 1, GL_RGBA8, w, h, mem, 0 );
这里最棘手的是同步问题。Vulkan规范要求在对其进行相应操作之前,图像必须处于某些状态(布局)中。因此,为了正确执行此操作(基于我的理解),您需要执行以下操作:
glWaitSemaphoreEXT
函数使GL驱动程序等待转换完成。
glWaitSync
(而不是glClientWaitSync
)。glSignalSemaphoreEXT
函数在GL端用不同的导出信号量发出信号waitIdle
命令以确保工作完成,执行GL命令,接着使用glFlush
和glFinish
命令以确保GPU完成了该工作,然后继续进行Vulkan命令。这更像是一种蛮力方法,并且很可能会产生比进行适当的同步性能更差的结果。这里有更多信息,来自于2016年SIGGRAPH的幻灯片。第63-65张幻灯片描述了如何将Vulkan图像blit到OpenGL后缓冲区。我的看法是,对于NVIDIA来说,支持这一点可能相当容易,因为Vulkan驱动程序包含在libGL.so中(在Linux上)。因此,将Vulkan图像句柄传递给驱动程序的GL侧并使其有用可能并不那么困难。
正如另一个答案所指出的,仍然没有官方注册的多供应商interop扩展。这种方法只适用于NVIDIA。