<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jan 17, 2020 at 3:41 PM Chia-I Wu <<a href="mailto:olvaffe@gmail.com">olvaffe@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Thu, Jan 16, 2020 at 11:29 PM Gerd Hoffmann <<a href="mailto:kraxel@redhat.com" target="_blank">kraxel@redhat.com</a>> wrote:<br>
><br>
> On Thu, Jan 16, 2020 at 12:33:25PM -0800, Chia-I Wu wrote:<br>
> > On Thu, Jan 16, 2020 at 4:58 AM Gerd Hoffmann <<a href="mailto:kraxel@redhat.com" target="_blank">kraxel@redhat.com</a>> wrote:<br>
> > ><br>
> > > On Mon, Jan 13, 2020 at 01:03:22PM -0800, Chia-I Wu wrote:<br>
> > > > Sorry I missed this email.<br>
> > > ><br>
> > > > On Thu, Jan 9, 2020 at 12:54 PM Dave Airlie <<a href="mailto:airlied@gmail.com" target="_blank">airlied@gmail.com</a>> wrote:<br>
> > > > ><br>
> > > > > This is just an aside to the issue discussion, but I was wondering<br>
> > > > > before we heavily consider a vulkan multi-process model, could<br>
> > > > > we/should we prove a GL multi-process model first?<br>
> > > ><br>
> > > > I think there will just be the qemu process at first, with many GL<br>
> > > > contexts and one VkInstance for each guest VkInstance.  Then there<br>
> > > > will be a switch to run different VkInstance in different processes<br>
> > > > (unlikely, but I wonder if this can be a vk layer).  I did not plan<br>
> > > > for a multi-process GL model.  Do you have anything you want to prove<br>
> > > > from it?<br>
> > ><br>
> > > Right now we have two models:<br>
> > >   - Everything in qemu.<br>
> > >   - Separate virgl process (see contrib/vhost-user-gpu/ in qemu),<br>
> > >     but still all gl contexts in a single process.<br>
> > ><br>
> > > We could try to switch vhost-user-gpu to a one-process-per-context<br>
> > > model.  I think it makes sense to at least think about the resource<br>
> > > management implications this would have (it would make virgl work<br>
> > > simliar to vulkan):<br>
> > ><br>
> > >  - We would need a master process.  It runs the virtqueues and manages<br>
> > >    the resources.<br>
> ><br>
> > In the distant feature where we will be Vulkan-only, we will not want<br>
> > GL-specific paths.  If we are to do multi-process GL now,<br>
><br>
> [ Note; I don't think it buys us much to actually do that now, we have<br>
>         enough to do even without that.  But we should keep that in mind<br>
>         when designing things ... ]<br>
><br>
> > I think we should follow the multi-process Vulkan model, in the sense<br>
> > that GL resources should also be created in the per-context processes<br>
><br>
> Yep, that would be good, we would not need a dma-buf for each and every<br>
> resource then.  Problem here is backward compatibility.  We simply can't<br>
> do that without changing the virtio protocol.<br>
><br>
> So, I guess the options we have are:<br>
>  (1) keep virgl mostly as-is and live with the downsides (which should<br>
>      not be that much of a problem as long as one process manages all<br>
>      GL contexts), or<br>
>  (2) create virgl_v2, where resource management works very simliar to<br>
>      the vulkan way of doing things, require the guest using that to<br>
>      run gl+vk side-by-side.  Old guests without vk support could<br>
>      continue to use virgl_v1<br>
<br>
(1) still requires defining interop with vk.  (2) seems like a<br>
reasonable requirement given that both drivers will be built from<br>
mesa.  But there are also APIs who like a simple interface like<br>
virgl_v1 to allocate resources yet requires interop with vk.  I guess<br>
both sound fine to me.<br>
<br>
The three resource models currently on the table are<br>
<br>
(A) A resource in the guest is a global driver object in the host.<br>
The global driver object is usable by all contexts and qemu.<br>
(B) A resource in the guest is a local driver object in the main<br>
renderer process in the host.  VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE<br>
creates attachments and each attachment is a local object in a<br>
per-context process.  VIRTIO_GPU_CMD_SET_SCANOUT creates a local<br>
object in qemu process.<br>
(C) A resource in the guest is an fd in the main renderer process in<br>
the host.  The fd may be created locally by the main renderer process<br>
(e.g., udmabuf) or received from a per-context process.<br>
VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE sends the fd to another per-context<br>
process.  VIRTIO_GPU_CMD_SET_SCANOUT works similar to in (B).<br>
<br>
(A) is the current model and does not support VK/GL interop. </blockquote><div><br></div><div>This should be possible as it's pretty much what the Android Emulator has already been doing for quite some time to have interop between GL and Vulkan.</div><div><br></div><div>It separates the concept of a virtio-gpu resource ID versus GL/Vk texture/extmemory ID's. A single virtio-gpu resource ID (aka ColorBuffer handle or hostHandle in Android Emulator parlance)</div><div>can be associated with both an external memory VkImage and a GL texture underneath, and the host uses either the VkImage or the GL texture depending on who's calling, after adding a bit of sync. Thus it achieves VK/GL interop via making the host do the work. In particular, if the host supports GL_EXT_memory_objects, the interop may be in HW.</div><div><br></div><div>Android Emulator's workflow:</div><div><br></div><div>GL -> Vk:</div><div><br></div><div>1. The guest creates a gralloc buffer or an EGL drawable, which creates a GL texture on host:</div><div><a href="https://android.googlesource.com/device/generic/goldfish-opengl/+/refs/heads/master/system/egl/egl.cpp#667">https://android.googlesource.com/device/generic/goldfish-opengl/+/refs/heads/master/system/egl/egl.cpp#667</a></div><div> <a href="https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev/android/android-emugl/host/libs/libOpenglRender/ColorBuffer.cpp#195">https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev/android/android-emugl/host/libs/libOpenglRender/ColorBuffer.cpp#195</a></div><div>Now there is a global ID assoc. with the ColorBuffer (which is 1:1 with virtio-gpu resource IDs: <a href="https://android.googlesource.com/device/generic/goldfish-opengl/+/refs/heads/master/system/OpenglSystemCommon/HostConnection.cpp#227">https://android.googlesource.com/device/generic/goldfish-opengl/+/refs/heads/master/system/OpenglSystemCommon/HostConnection.cpp#227</a> (as evidenced by the minigbm backend for Gralloc))</div><div><br></div><div>2. The guest imports that memory to Vk: <a href="https://android.googlesource.com/device/generic/goldfish-opengl/+/refs/heads/master/system/vulkan_enc/ResourceTracker.cpp#1823">https://android.googlesource.com/device/generic/goldfish-opengl/+/refs/heads/master/system/vulkan_enc/ResourceTracker.cpp#1823</a></div><div>and sends that same ID back to the host:</div><div><a href="https://android.googlesource.com/device/generic/goldfish-opengl/+/refs/heads/master/system/vulkan_enc/AndroidHardwareBuffer.cpp#168">https://android.googlesource.com/device/generic/goldfish-opengl/+/refs/heads/master/system/vulkan_enc/AndroidHardwareBuffer.cpp#168</a><br></div><div><br></div><div>3. The host reads the request to share GL memory with Vk:</div><div><a href="https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev/android/android-emugl/host/libs/libOpenglRender/vulkan/VkDecoderGlobalState.cpp#2429">https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev/android/android-emugl/host/libs/libOpenglRender/vulkan/VkDecoderGlobalState.cpp#2429</a><br></div><div><br></div><div>and creates an external Vk image: <a href="https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev/android/android-emugl/host/libs/libOpenglRender/vulkan/VkCommonOperations.cpp#1200">https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev/android/android-emugl/host/libs/libOpenglRender/vulkan/VkCommonOperations.cpp#1200</a></div><div><br></div><div>and if HW interop is supported, the previous GL texture is nuked and replaced with the Vk image:</div><div><a href="https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev/android/android-emugl/host/libs/libOpenglRender/vulkan/VkCommonOperations.cpp#1328">https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev/android/android-emugl/host/libs/libOpenglRender/vulkan/VkCommonOperations.cpp#1328</a><br></div><div>Via GL_EXT_memory_objects:</div><div><a href="https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev/android/android-emugl/host/libs/libOpenglRender/ColorBuffer.cpp#898">https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev/android/android-emugl/host/libs/libOpenglRender/ColorBuffer.cpp#898</a><br></div><div>and the Vk image is updated with the previous contents if any:</div><div><a href="https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev/android/android-emugl/host/libs/libOpenglRender/ColorBuffer.cpp#961">https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev/android/android-emugl/host/libs/libOpenglRender/ColorBuffer.cpp#961</a><br></div><div><br></div><div>If HW interop is not supported, then appropriate calls are added at particular places to manually copy to/from the VkImage (e.g., on window surface flush: <a href="https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev/android/android-emugl/host/libs/libOpenglRender/RenderControl.cpp#724">https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev/android/android-emugl/host/libs/libOpenglRender/RenderControl.cpp#724</a>)</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> (B) is<br>
designed to be compatible with (A) and the current virtio protocol.<br>
It allows multi-process GL as well as VK/GL interop, but it requires a<br>
dma-buf for each resource even when not really shared.<br>
<br>
(C) is the Vulkan model, but it is unclear how<br>
VIRTIO_GPU_CMD_RESOURCE_CREATE_3D works.  I think we can think of the<br>
main process as a simple allocator as well.<br>
VIRTIO_GPU_CMD_RESOURCE_CREATE_3D makes the main process allocate<br>
(from GBM or GL) and create an fd , just like how the main process can<br>
allocate a udmabuf.  This way this model can work with option (1).<br>
<br>
<br>
<br>
> > >  - We would need a per-context process.<br>
> > >  - VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE would make master dma-buf export a<br>
> > >    resource and the per-context process import it.  Sharing resources<br>
> > >    works by calling VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE multipe times for<br>
> > >    different contexts, and therefore master passing the dma-buf to<br>
> > >    multiple per-context processes.<br>
> ><br>
> > I would like to see the export and import parts to be separated out<br>
> > and executed by other commands, but all three commands can be sent<br>
> > together by the guest kernel when it makes senses.  Especially the<br>
> > import part, the guest vulkan wants to pass some metadata and specify<br>
> > an object id for the imported driver object.<br>
><br>
> I don't want call this import/export, that term is overloaded too much<br>
> already.  Also the "export" is needed for more than just export.  It is<br>
> needed for everything the guest needs a gem bo for (mmap, scanout, ...).<br>
><br>
> I guess something along the lines of OBJECT_TO_RESOURCE (add virtio<br>
> resource for vulkan object, aka "export") and RESOURCE_TO_OBJECT<br>
> ("import") would be better.<br>
><br>
> Does GL have object IDs too?<br>
No.  A resource in the guest is already a global GL object in the<br>
host.  VIRTIO_GPU_CMD_SUBMIT_3D can use the resource ids directly.<br>
<br>
Vulkan wants object ids because there might be no resource ids when<br>
resources are not needed.  When there are resource ids, they might<br>
point to fds  and importing them as objects are not trivial.  Also the<br>
same resource id might be imported multiple times to create multiple<br>
objects.<br>
<br>
><br>
> cheers,<br>
>   Gerd<br>
><br>
_______________________________________________<br>
virglrenderer-devel mailing list<br>
<a href="mailto:virglrenderer-devel@lists.freedesktop.org" target="_blank">virglrenderer-devel@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/virglrenderer-devel" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/virglrenderer-devel</a><br>
</blockquote></div></div>