* Re: [virtio-dev] [PATCH] Add virtio gpu device specification. [not found] ` <1462879537.8035.53.camel@redhat.com> @ 2018-06-20 3:15 ` Michael S. Tsirkin 2018-06-27 6:15 ` Gerd Hoffmann 0 siblings, 1 reply; 6+ messages in thread From: Michael S. Tsirkin @ 2018-06-20 3:15 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: Stefan Hajnoczi, virtio-dev, qemu-devel On Tue, May 10, 2016 at 01:25:37PM +0200, Gerd Hoffmann wrote: > Hi, > > > > > Rendered versions are available here: > > > > https://www.kraxel.org/virtio/virtio-v1.0-cs03-virtio-gpu.pdf > > > > https://www.kraxel.org/virtio/virtio-v1.0-cs03-virtio-gpu.html#x1-2800007 > > > > I guess a non-fenced command only completes when the operation has > > > finished, too (so that a meaningful success/error value can be > > > produced)? > > > > When stuff is processed asynchronously the command can complete before > > the operation actually completed. Current qemu implementation does that > > only in 3d mode, when offloading stuff to the hardware (and verifies > > stuff beforehand, so if you try to kick 3d rendering with an invalid > > context id qemu will throw an error). > > > > I'll try to make that more clear in the text. > > Updated now. > > cheers, > Gerd Is there a chance you could rebase and post? This is used widely, I think we shoould have it in 1.1 if at all possible. > > --------------------------------------------------------------------- > To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org > For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org --------------------------------------------------------------------- To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [virtio-dev] [PATCH] Add virtio gpu device specification. 2018-06-20 3:15 ` [virtio-dev] [PATCH] Add virtio gpu device specification Michael S. Tsirkin @ 2018-06-27 6:15 ` Gerd Hoffmann 2018-06-27 18:56 ` Michael S. Tsirkin 0 siblings, 1 reply; 6+ messages in thread From: Gerd Hoffmann @ 2018-06-27 6:15 UTC (permalink / raw) To: Michael S. Tsirkin; +Cc: Stefan Hajnoczi, virtio-dev, qemu-devel Hi, > > > > > https://www.kraxel.org/virtio/virtio-v1.0-cs03-virtio-gpu.html#x1-2800007 > Is there a chance you could rebase and post? > This is used widely, I think we shoould have it in 1.1 > if at all possible. https://www.kraxel.org/virtio/virtio-v1.0-cs04-virtio-gpu.html#x1-3150007 Repost will follow in a moment. For virtio-input I don't have the latest version at hand, Ladi worked on it last. cheers, Gerd --------------------------------------------------------------------- To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [virtio-dev] [PATCH] Add virtio gpu device specification. 2018-06-27 6:15 ` Gerd Hoffmann @ 2018-06-27 18:56 ` Michael S. Tsirkin 0 siblings, 0 replies; 6+ messages in thread From: Michael S. Tsirkin @ 2018-06-27 18:56 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: Stefan Hajnoczi, virtio-dev, qemu-devel On Wed, Jun 27, 2018 at 08:15:08AM +0200, Gerd Hoffmann wrote: > Hi, > > > > > > > https://www.kraxel.org/virtio/virtio-v1.0-cs03-virtio-gpu.html#x1-2800007 > > > Is there a chance you could rebase and post? > > This is used widely, I think we shoould have it in 1.1 > > if at all possible. > > https://www.kraxel.org/virtio/virtio-v1.0-cs04-virtio-gpu.html#x1-3150007 > > Repost will follow in a moment. > > For virtio-input I don't have the latest version at hand, > Ladi worked on it last. > > cheers, > Gerd Resent to you in a private mail. > > --------------------------------------------------------------------- > To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org > For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org --------------------------------------------------------------------- To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org ^ permalink raw reply [flat|nested] 6+ messages in thread
* [virtio-dev] [PATCH] Add virtio gpu device specification. @ 2018-06-27 6:15 Gerd Hoffmann 2018-07-03 0:15 ` Michael S. Tsirkin 0 siblings, 1 reply; 6+ messages in thread From: Gerd Hoffmann @ 2018-06-27 6:15 UTC (permalink / raw) To: virtio-dev; +Cc: Michael S. Tsirkin, Gerd Hoffmann Support for 2d mode (3d/virgl mode is not covered by this patch) has been added to the linux kernel version 4.2 and to qemu version 2.4. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- content.tex | 2 + virtio-gpu.tex | 481 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 483 insertions(+) create mode 100644 virtio-gpu.tex diff --git a/content.tex b/content.tex index be1823431d..d41c2f8d76 100644 --- a/content.tex +++ b/content.tex @@ -5325,6 +5325,8 @@ descriptor for the \field{sense_len}, \field{residual}, \field{status_qualifier}, \field{status}, \field{response} and \field{sense} fields. +\input{virtio-gpu.tex} + \chapter{Reserved Feature Bits}\label{sec:Reserved Feature Bits} Currently these device-independent feature bits defined: diff --git a/virtio-gpu.tex b/virtio-gpu.tex new file mode 100644 index 0000000000..34cf493bbc --- /dev/null +++ b/virtio-gpu.tex @@ -0,0 +1,481 @@ +\section{GPU Device}\label{sec:Device Types / GPU Device} + +virtio-gpu is a virtio based graphics adapter. It can operate in 2D +mode and in 3D (virgl) mode. 3D mode will offload rendering ops to +the host gpu and therefore requires a gpu with 3D support on the host +machine. + +3D mode is not covered (yet) in this specification, even though it is +mentioned here and there due to some details of the virtual hardware +being designed with 3D mode in mind. + +In 2D mode the virtio-gpu device provides support for ARGB Hardware +cursors and multiple scanouts (aka heads). + +\subsection{Device ID}\label{sec:Device Types / GPU Device / Device ID} + +16 + +\subsection{Virtqueues}\label{sec:Device Types / GPU Device / Virtqueues} + +\begin{description} +\item[0] controlq - queue for sending control commands +\item[1] cursorq - queue for sending cursor updates +\end{description} + +Both queues have the same format. Each request and each response have +a fixed header, followed by command specific data fields. The +separate cursor queue is the "fast track" for cursor commands +(VIRTIO_GPU_CMD_UPDATE_CURSOR and VIRTIO_GPU_CMD_MOVE_CURSOR), so they +go though without being delayed by time-consuming commands in the +control queue. + +\subsection{Feature bits}\label{sec:Device Types / GPU Device / Feature bits} + +\begin{description} +\item[VIRTIO_GPU_F_VIRGL (0)] virgl 3D mode is supported. +\end{description} + +\subsection{Device configuration layout}\label{sec:Device Types / GPU Device / Device configuration layout} + +\begin{lstlisting} +#define VIRTIO_GPU_EVENT_DISPLAY (1 << 0) + +struct virtio_gpu_config { + le32 events_read; + le32 events_clear; + le32 num_scanouts; + le32 reserved; +} +\end{lstlisting} + +\subsubsection{Device configuration fields} + +\begin{description} +\item[\field{events_read}] signals pending events to the driver. The + driver MUST NOT write to this field. +\item[\field{events_clear}] clears pending events in the device. + Writing a '1' into a bit will clear the corresponding bit in + \field{events_read}, mimicking write-to-clear behavior. +\item[\field{num_scanouts}] specifies the maximum number of scanouts + supported by the device. Minimum value is 1, maximum value is 16. +\end{description} + +\subsubsection{Events} + +\begin{description} +\item[VIRTIO_GPU_EVENT_DISPLAY] Display configuration has changed. + The driver SHOULD use the VIRTIO_GPU_CMD_GET_DISPLAY_INFO command to + fetch the information from the device. +\end{description} + +\devicenormative{\subsection}{Device Initialization}{Device Types / GPU Device / Device Initialization} + +The driver SHOULD query the display information from the device using +the VIRTIO_GPU_CMD_GET_DISPLAY_INFO command and use that information +for the initial scanout setup. In case no information is available or +all displays are disabled the driver MAY choose to use a fallback, +such as 1024x768 at display 0. + +\subsection{Device Operation}\label{sec:Device Types / GPU Device / Device Operation} + +The virtio-gpu is based around the concept of resources private to the +host, the guest must DMA transfer into these resources. This is a +design requirement in order to interface with future 3D rendering. In +the unaccelerated 2D mode there is no support for DMA transfers from +resources, just to them. + +Resources are initially simple 2D resources, consisting of a width, +height and format along with an identifier. The guest must then attach +backing store to the resources in order for DMA transfers to +work. This is like a GART in a real GPU. + +\subsubsection{Device Operation: Create a framebuffer and configure scanout} + +\begin{itemize*} +\item Create a host resource using VIRTIO_GPU_CMD_RESOURCE_CREATE_2D. +\item Allocate a framebuffer from guest ram, and attach it as backing + storage to the resource just created, using + VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING. Scatter lists are + supported, so the framebuffer doesn't need to be contignous in guest + physical memory. +\item Use VIRTIO_GPU_CMD_SET_SCANOUT to link the framebuffer to + a display scanout. +\end{itemize*} + +\subsubsection{Device Operation: Update a framebuffer and scanout} + +\begin{itemize*} +\item Render to your framebuffer memory. +\item Use VIRTIO_GPU_CMD_TRANSFER_SEND_2D to update the host resource + from guest memory. +\item Use VIRTIO_GPU_CMD_RESOURCE_FLUSH to flush the updated resource + to the display. +\end{itemize*} + +\subsubsection{Device Operation: Using pageflip} + +It is possible to create multiple framebuffers, flip between them +using VIRTIO_GPU_CMD_SET_SCANOUT and VIRTIO_GPU_CMD_RESOURCE_FLUSH, +and update the invisible framebuffer using +VIRTIO_GPU_CMD_TRANSFER_SEND_2D. + +\subsubsection{Device Operation: Multihead setup} + +In case two or more displays are present there are different ways to +configure things: + +\begin{itemize*} +\item Create a single framebuffer, link it to all displays + (mirroring). +\item Create an framebuffer for each display. +\item Create one big framebuffer, configure scanouts to display a + different rectangle of that framebuffer each. +\end{itemize*} + +\devicenormative{\subsubsection}{Device Operation: Command lifecycle and fencing}{Device Types / GPU Device / Device Operation / Device Operation: Command lifecycle and fencing} + +The device MAY process controlq commands asyncronously and return them +to the driver before the processing is complete. If the driver needs +to know when the processing is finished it can set the +VIRTIO_GPU_FLAG_FENCE flag in the request. The device MUST finish the +processing before returning the command then. + +Note: current qemu implementation does asyncrounous processing only in +3d mode, when offloading the processing to the host gpu. + +\subsubsection{Device Operation: Configure mouse cursor} + +The mouse cursor image is a normal resource, except that it must be +64x64 in size. The driver MUST create and populate the resource +(using the usual VIRTIO_GPU_CMD_RESOURCE_CREATE_2D, +VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING and +VIRTIO_GPU_CMD_TRANSFER_SEND_2D controlq commands) and make sure they +are completed (using VIRTIO_GPU_FLAG_FENCE). + +Then VIRTIO_GPU_CMD_UPDATE_CURSOR can be sent to the cursorq to set +the pointer shape and position. To move the pointer without updating +the shape use VIRTIO_GPU_CMD_MOVE_CURSOR instead. + +\subsubsection{Device Operation: Request header}\label{sec:Device Types / GPU Device / Device Operation / Device Operation: Request header} + +\begin{lstlisting} +enum virtio_gpu_ctrl_type { + + /* 2d commands */ + VIRTIO_GPU_CMD_GET_DISPLAY_INFO = 0x0100, + VIRTIO_GPU_CMD_RESOURCE_CREATE_2D, + VIRTIO_GPU_CMD_RESOURCE_UNREF, + VIRTIO_GPU_CMD_SET_SCANOUT, + VIRTIO_GPU_CMD_RESOURCE_FLUSH, + VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D, + VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING, + VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING, + + /* cursor commands */ + VIRTIO_GPU_CMD_UPDATE_CURSOR = 0x0300, + VIRTIO_GPU_CMD_MOVE_CURSOR, + + /* success responses */ + VIRTIO_GPU_RESP_OK_NODATA = 0x1100, + VIRTIO_GPU_RESP_OK_DISPLAY_INFO, + + /* error responses */ + VIRTIO_GPU_RESP_ERR_UNSPEC = 0x1200, + VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY, + VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID, + VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID, + VIRTIO_GPU_RESP_ERR_INVALID_CONTEXT_ID, + VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER, +}; + +#define VIRTIO_GPU_FLAG_FENCE (1 << 0) + +struct virtio_gpu_ctrl_hdr { + le32 type; + le32 flags; + le64 fence_id; + le32 ctx_id; + le32 padding; +}; +\end{lstlisting} + +All requests and responses on the virt queues have the fixed header +\field{struct virtio_gpu_ctrl_hdr}. + +\begin{description} +\item[\field{type}] specifies the type of the driver request + (VIRTIO_GPU_CMD_*) or device response (VIRTIO_GPU_RESP_*). +\item[\field{flags}] request / response flags. +\item[\field{fence_id}] If the driver sets the VIRTIO_GPU_FLAG_FENCE + bit in the request \field{flags} field the device MUST: + \begin{itemize*} + \item set VIRTIO_GPU_FLAG_FENCE bit in the response, + \item copy the content of the \field{fence_id} field from the + request to the response, and + \item send the response only after command processing is complete. + \end{itemize*} +\item[\field{ctx_id}] Rendering context (used in 3D mode only). +\end{description} + +On success the device will return VIRTIO_GPU_RESP_OK_NODATA in +case there is no payload. Otherwise the \field{type} field will +indicate the kind of payload. + +On error the device will return one of the +VIRTIO_GPU_RESP_ERR_* error codes. + +\subsubsection{Device Operation: controlq}\label{sec:Device Types / GPU Device / Device Operation / Device Operation: controlq} + +For any coordinates given 0,0 is top left, larger x moves right, +larger y moves down. + +\begin{description} + +\item[VIRTIO_GPU_CMD_GET_DISPLAY_INFO] Retrieve the current output + configuration. No request data (just bare \field{struct + virtio_gpu_ctrl_hdr}). Response type is + VIRTIO_GPU_RESP_OK_DISPLAY_INFO, response data is \field{struct + virtio_gpu_resp_display_info}. + +\begin{lstlisting} +#define VIRTIO_GPU_MAX_SCANOUTS 16 + +struct virtio_gpu_rect { + le32 x; + le32 y; + le32 width; + le32 height; +}; + +struct virtio_gpu_resp_display_info { + struct virtio_gpu_ctrl_hdr hdr; + struct virtio_gpu_display_one { + struct virtio_gpu_rect r; + le32 enabled; + le32 flags; + } pmodes[VIRTIO_GPU_MAX_SCANOUTS]; +}; +\end{lstlisting} + +The response contains a list of per-scanout information. The info +contains whether the scanout is enabled and what its preferred +position and size is. + +The size (fields \field{width} and \field{height}) is similar to the +native panel resolution in EDID display information, except that in +the virtual machine case the size can change when the host window +representing the guest display is gets resized. + +The position (fields \field{x} and \field{y}) describe how the +displays are arranged (i.e. which is -- for example -- the left +display). + +The \field{enabled} field is set when the user enabled the display. +It is roughly the same as the connected state of a phyiscal display +connector. + +\item[VIRTIO_GPU_CMD_RESOURCE_CREATE_2D] Create a 2D resource on the + host. Request data is \field{struct virtio_gpu_resource_create_2d}. + Response type is VIRTIO_GPU_RESP_OK_NODATA. + +\begin{lstlisting} +enum virtio_gpu_formats { + VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM = 1, + VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM = 2, + VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM = 3, + VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM = 4, + + VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM = 67, + VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM = 68, + + VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM = 121, + VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM = 134, +}; + +struct virtio_gpu_resource_create_2d { + struct virtio_gpu_ctrl_hdr hdr; + le32 resource_id; + le32 format; + le32 width; + le32 height; +}; +\end{lstlisting} + +This creates a 2D resource on the host with the specified width, +height and format. The resource ids are generated by the guest. + +\item[VIRTIO_GPU_CMD_RESOURCE_UNREF] Destroy a resource. Request data + is \field{struct virtio_gpu_resource_unref}. Response type is + VIRTIO_GPU_RESP_OK_NODATA. + +\begin{lstlisting} +struct virtio_gpu_resource_unref { + struct virtio_gpu_ctrl_hdr hdr; + le32 resource_id; + le32 padding; +}; +\end{lstlisting} + +This informs the host that a resource is no longer required by the +guest. + +\item[VIRTIO_GPU_CMD_SET_SCANOUT] Set the scanout parameters for a + single output. Request data is \field{struct + virtio_gpu_set_scanout}. Response type is + VIRTIO_GPU_RESP_OK_NODATA. + +\begin{lstlisting} +struct virtio_gpu_set_scanout { + struct virtio_gpu_ctrl_hdr hdr; + struct virtio_gpu_rect r; + le32 scanout_id; + le32 resource_id; +}; +\end{lstlisting} + +This sets the scanout parameters for a single scanout. The resource_id +is the resource to be scanned out from, along with a rectangle. + +Scanout rectangles must be completely covered by the underlying +resource. Overlapping (or identical) scanouts are allowed, typical +use case is screen mirroring. + +The driver can use resource_id = 0 to disable a scanout. + +\item[VIRTIO_GPU_CMD_RESOURCE_FLUSH] Flush a scanout resource Request + data is \field{struct virtio_gpu_resource_flush}. Response type is + VIRTIO_GPU_RESP_OK_NODATA. + +\begin{lstlisting} +struct virtio_gpu_resource_flush { + struct virtio_gpu_ctrl_hdr hdr; + struct virtio_gpu_rect r; + le32 resource_id; + le32 padding; +}; +\end{lstlisting} + +This flushes a resource to screen. It takes a rectangle and a +resource id, and flushes any scanouts the resource is being used on. + +\item[VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D] Transfer from guest memory + to host resource. Request data is \field{struct + virtio_gpu_transfer_to_host_2d}. Response type is + VIRTIO_GPU_RESP_OK_NODATA. + +\begin{lstlisting} +struct virtio_gpu_transfer_to_host_2d { + struct virtio_gpu_ctrl_hdr hdr; + struct virtio_gpu_rect r; + le64 offset; + le32 resource_id; + le32 padding; +}; +\end{lstlisting} + +This takes a resource id along with an destination offset into the +resource, and a box to transfer to the host backing for the resource. + +\item[VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING] Assign backing pages to + a resource. Request data is \field{struct + virtio_gpu_resource_attach_backing}, followed by \field{struct + virtio_gpu_mem_entry} entries. Response type is + VIRTIO_GPU_RESP_OK_NODATA. + +\begin{lstlisting} +struct virtio_gpu_resource_attach_backing { + struct virtio_gpu_ctrl_hdr hdr; + le32 resource_id; + le32 nr_entries; +}; + +struct virtio_gpu_mem_entry { + le64 addr; + le32 length; + le32 padding; +}; +\end{lstlisting} + +This assign an array of guest pages as the backing store for a +resource. These pages are then used for the transfer operations for +that resource from that point on. + +\item[VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING] Detach backing pages + from a resource. Request data is \field{struct + virtio_gpu_resource_detach_backing}. Response type is + VIRTIO_GPU_RESP_OK_NODATA. + +\begin{lstlisting} +struct virtio_gpu_resource_detach_backing { + struct virtio_gpu_ctrl_hdr hdr; + le32 resource_id; + le32 padding; +}; +\end{lstlisting} + +This detaches any backing pages from a resource, to be used in case of +guest swapping or object destruction. + +\end{description} + +\subsubsection{Device Operation: cursorq}\label{sec:Device Types / GPU Device / Device Operation / Device Operation: cursorq} + +Both cursorq commands use the same command struct. + +\begin{lstlisting} +struct virtio_gpu_cursor_pos { + le32 scanout_id; + le32 x; + le32 y; + le32 padding; +}; + +struct virtio_gpu_update_cursor { + struct virtio_gpu_ctrl_hdr hdr; + struct virtio_gpu_cursor_pos pos; + le32 resource_id; + le32 hot_x; + le32 hot_y; + le32 padding; +}; +\end{lstlisting} + +\begin{description} + +\item[VIRTIO_GPU_CMD_UPDATE_CURSOR] +Update cursor. +Request data is \field{struct virtio_gpu_update_cursor}. +Response type is VIRTIO_GPU_RESP_OK_NODATA. + +Full cursor update. Cursor will be loaded from the specified +\field{resource_id} and will be moved to \field{pos}. The driver must +transfer the cursor into the resource beforehand (using control queue +commands) and make sure the commands to fill the resource are actually +processed (using fencing). + +\item[VIRTIO_GPU_CMD_MOVE_CURSOR] +Move cursor. +Request data is \field{struct virtio_gpu_update_cursor}. +Response type is VIRTIO_GPU_RESP_OK_NODATA. + +Move cursor to the place specified in \field{pos}. The other fields +are not used and will be ignored by the device. + +\end{description} + +\subsection{VGA Compatibility}\label{sec:Device Types / GPU Device / VGA Compatibility} + +Applies to Virtio Over PCI only. The GPU device can come with and +without VGA compatibility. The PCI class should be DISPLAY_VGA if VGA +compatibility is present and DISPLAY_OTHER otherwise. + +VGA compatibility: PCI region 0 has the linear framebuffer, standard +vga registers are present. Configuring a scanout +(VIRTIO_GPU_CMD_SET_SCANOUT) switches the device from vga +compatibility mode into native virtio mode. A reset switches it back +into vga compatibility mode. + +Note: qemu implementation also provides bochs dispi interface io ports +and mmio bar at pci region 1 and is therefore fully compatible with +the qemu stdvga (see \href{http://git.qemu-project.org/?p=qemu.git;a=blob;f=docs/specs/standard-vga.txt;hb=HEAD}{docs/specs/standard-vga.txt} in the qemu source tree). -- 2.9.3 --------------------------------------------------------------------- To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [virtio-dev] [PATCH] Add virtio gpu device specification. 2018-06-27 6:15 Gerd Hoffmann @ 2018-07-03 0:15 ` Michael S. Tsirkin 2018-07-03 13:03 ` Laszlo Ersek 0 siblings, 1 reply; 6+ messages in thread From: Michael S. Tsirkin @ 2018-07-03 0:15 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: virtio-dev On Wed, Jun 27, 2018 at 08:15:25AM +0200, Gerd Hoffmann wrote: > Support for 2d mode (3d/virgl mode is not covered by this patch) has > been added to the linux kernel version 4.2 and to qemu version 2.4. > > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> No comments so far, as Gerd seems to be the only one with both understanding the field and willing to contribute to the spec, I will start voting in a couple of days unless there's interest from TC members in working on this. > --- > content.tex | 2 + > virtio-gpu.tex | 481 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 483 insertions(+) > create mode 100644 virtio-gpu.tex > > diff --git a/content.tex b/content.tex > index be1823431d..d41c2f8d76 100644 > --- a/content.tex > +++ b/content.tex > @@ -5325,6 +5325,8 @@ descriptor for the \field{sense_len}, \field{residual}, > \field{status_qualifier}, \field{status}, \field{response} and > \field{sense} fields. > > +\input{virtio-gpu.tex} > + > \chapter{Reserved Feature Bits}\label{sec:Reserved Feature Bits} > > Currently these device-independent feature bits defined: > diff --git a/virtio-gpu.tex b/virtio-gpu.tex > new file mode 100644 > index 0000000000..34cf493bbc > --- /dev/null > +++ b/virtio-gpu.tex > @@ -0,0 +1,481 @@ > +\section{GPU Device}\label{sec:Device Types / GPU Device} > + > +virtio-gpu is a virtio based graphics adapter. It can operate in 2D > +mode and in 3D (virgl) mode. 3D mode will offload rendering ops to > +the host gpu and therefore requires a gpu with 3D support on the host > +machine. > + > +3D mode is not covered (yet) in this specification, even though it is > +mentioned here and there due to some details of the virtual hardware > +being designed with 3D mode in mind. > + > +In 2D mode the virtio-gpu device provides support for ARGB Hardware > +cursors and multiple scanouts (aka heads). > + > +\subsection{Device ID}\label{sec:Device Types / GPU Device / Device ID} > + > +16 > + > +\subsection{Virtqueues}\label{sec:Device Types / GPU Device / Virtqueues} > + > +\begin{description} > +\item[0] controlq - queue for sending control commands > +\item[1] cursorq - queue for sending cursor updates > +\end{description} > + > +Both queues have the same format. Each request and each response have > +a fixed header, followed by command specific data fields. The > +separate cursor queue is the "fast track" for cursor commands > +(VIRTIO_GPU_CMD_UPDATE_CURSOR and VIRTIO_GPU_CMD_MOVE_CURSOR), so they > +go though without being delayed by time-consuming commands in the > +control queue. > + > +\subsection{Feature bits}\label{sec:Device Types / GPU Device / Feature bits} > + > +\begin{description} > +\item[VIRTIO_GPU_F_VIRGL (0)] virgl 3D mode is supported. > +\end{description} > + > +\subsection{Device configuration layout}\label{sec:Device Types / GPU Device / Device configuration layout} > + > +\begin{lstlisting} > +#define VIRTIO_GPU_EVENT_DISPLAY (1 << 0) > + > +struct virtio_gpu_config { > + le32 events_read; > + le32 events_clear; > + le32 num_scanouts; > + le32 reserved; > +} > +\end{lstlisting} > + > +\subsubsection{Device configuration fields} > + > +\begin{description} > +\item[\field{events_read}] signals pending events to the driver. The > + driver MUST NOT write to this field. > +\item[\field{events_clear}] clears pending events in the device. > + Writing a '1' into a bit will clear the corresponding bit in > + \field{events_read}, mimicking write-to-clear behavior. > +\item[\field{num_scanouts}] specifies the maximum number of scanouts > + supported by the device. Minimum value is 1, maximum value is 16. > +\end{description} > + > +\subsubsection{Events} > + > +\begin{description} > +\item[VIRTIO_GPU_EVENT_DISPLAY] Display configuration has changed. > + The driver SHOULD use the VIRTIO_GPU_CMD_GET_DISPLAY_INFO command to > + fetch the information from the device. > +\end{description} > + > +\devicenormative{\subsection}{Device Initialization}{Device Types / GPU Device / Device Initialization} > + > +The driver SHOULD query the display information from the device using > +the VIRTIO_GPU_CMD_GET_DISPLAY_INFO command and use that information > +for the initial scanout setup. In case no information is available or > +all displays are disabled the driver MAY choose to use a fallback, > +such as 1024x768 at display 0. > + > +\subsection{Device Operation}\label{sec:Device Types / GPU Device / Device Operation} > + > +The virtio-gpu is based around the concept of resources private to the > +host, the guest must DMA transfer into these resources. This is a > +design requirement in order to interface with future 3D rendering. In > +the unaccelerated 2D mode there is no support for DMA transfers from > +resources, just to them. > + > +Resources are initially simple 2D resources, consisting of a width, > +height and format along with an identifier. The guest must then attach > +backing store to the resources in order for DMA transfers to > +work. This is like a GART in a real GPU. > + > +\subsubsection{Device Operation: Create a framebuffer and configure scanout} > + > +\begin{itemize*} > +\item Create a host resource using VIRTIO_GPU_CMD_RESOURCE_CREATE_2D. > +\item Allocate a framebuffer from guest ram, and attach it as backing > + storage to the resource just created, using > + VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING. Scatter lists are > + supported, so the framebuffer doesn't need to be contignous in guest > + physical memory. > +\item Use VIRTIO_GPU_CMD_SET_SCANOUT to link the framebuffer to > + a display scanout. > +\end{itemize*} > + > +\subsubsection{Device Operation: Update a framebuffer and scanout} > + > +\begin{itemize*} > +\item Render to your framebuffer memory. > +\item Use VIRTIO_GPU_CMD_TRANSFER_SEND_2D to update the host resource > + from guest memory. > +\item Use VIRTIO_GPU_CMD_RESOURCE_FLUSH to flush the updated resource > + to the display. > +\end{itemize*} > + > +\subsubsection{Device Operation: Using pageflip} > + > +It is possible to create multiple framebuffers, flip between them > +using VIRTIO_GPU_CMD_SET_SCANOUT and VIRTIO_GPU_CMD_RESOURCE_FLUSH, > +and update the invisible framebuffer using > +VIRTIO_GPU_CMD_TRANSFER_SEND_2D. > + > +\subsubsection{Device Operation: Multihead setup} > + > +In case two or more displays are present there are different ways to > +configure things: > + > +\begin{itemize*} > +\item Create a single framebuffer, link it to all displays > + (mirroring). > +\item Create an framebuffer for each display. > +\item Create one big framebuffer, configure scanouts to display a > + different rectangle of that framebuffer each. > +\end{itemize*} > + > +\devicenormative{\subsubsection}{Device Operation: Command lifecycle and fencing}{Device Types / GPU Device / Device Operation / Device Operation: Command lifecycle and fencing} > + > +The device MAY process controlq commands asyncronously and return them > +to the driver before the processing is complete. If the driver needs > +to know when the processing is finished it can set the > +VIRTIO_GPU_FLAG_FENCE flag in the request. The device MUST finish the > +processing before returning the command then. > + > +Note: current qemu implementation does asyncrounous processing only in > +3d mode, when offloading the processing to the host gpu. > + > +\subsubsection{Device Operation: Configure mouse cursor} > + > +The mouse cursor image is a normal resource, except that it must be > +64x64 in size. The driver MUST create and populate the resource > +(using the usual VIRTIO_GPU_CMD_RESOURCE_CREATE_2D, > +VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING and > +VIRTIO_GPU_CMD_TRANSFER_SEND_2D controlq commands) and make sure they > +are completed (using VIRTIO_GPU_FLAG_FENCE). > + > +Then VIRTIO_GPU_CMD_UPDATE_CURSOR can be sent to the cursorq to set > +the pointer shape and position. To move the pointer without updating > +the shape use VIRTIO_GPU_CMD_MOVE_CURSOR instead. > + > +\subsubsection{Device Operation: Request header}\label{sec:Device Types / GPU Device / Device Operation / Device Operation: Request header} > + > +\begin{lstlisting} > +enum virtio_gpu_ctrl_type { > + > + /* 2d commands */ > + VIRTIO_GPU_CMD_GET_DISPLAY_INFO = 0x0100, > + VIRTIO_GPU_CMD_RESOURCE_CREATE_2D, > + VIRTIO_GPU_CMD_RESOURCE_UNREF, > + VIRTIO_GPU_CMD_SET_SCANOUT, > + VIRTIO_GPU_CMD_RESOURCE_FLUSH, > + VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D, > + VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING, > + VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING, > + > + /* cursor commands */ > + VIRTIO_GPU_CMD_UPDATE_CURSOR = 0x0300, > + VIRTIO_GPU_CMD_MOVE_CURSOR, > + > + /* success responses */ > + VIRTIO_GPU_RESP_OK_NODATA = 0x1100, > + VIRTIO_GPU_RESP_OK_DISPLAY_INFO, > + > + /* error responses */ > + VIRTIO_GPU_RESP_ERR_UNSPEC = 0x1200, > + VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY, > + VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID, > + VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID, > + VIRTIO_GPU_RESP_ERR_INVALID_CONTEXT_ID, > + VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER, > +}; > + > +#define VIRTIO_GPU_FLAG_FENCE (1 << 0) > + > +struct virtio_gpu_ctrl_hdr { > + le32 type; > + le32 flags; > + le64 fence_id; > + le32 ctx_id; > + le32 padding; > +}; > +\end{lstlisting} > + > +All requests and responses on the virt queues have the fixed header > +\field{struct virtio_gpu_ctrl_hdr}. > + > +\begin{description} > +\item[\field{type}] specifies the type of the driver request > + (VIRTIO_GPU_CMD_*) or device response (VIRTIO_GPU_RESP_*). > +\item[\field{flags}] request / response flags. > +\item[\field{fence_id}] If the driver sets the VIRTIO_GPU_FLAG_FENCE > + bit in the request \field{flags} field the device MUST: > + \begin{itemize*} > + \item set VIRTIO_GPU_FLAG_FENCE bit in the response, > + \item copy the content of the \field{fence_id} field from the > + request to the response, and > + \item send the response only after command processing is complete. > + \end{itemize*} > +\item[\field{ctx_id}] Rendering context (used in 3D mode only). > +\end{description} > + > +On success the device will return VIRTIO_GPU_RESP_OK_NODATA in > +case there is no payload. Otherwise the \field{type} field will > +indicate the kind of payload. > + > +On error the device will return one of the > +VIRTIO_GPU_RESP_ERR_* error codes. > + > +\subsubsection{Device Operation: controlq}\label{sec:Device Types / GPU Device / Device Operation / Device Operation: controlq} > + > +For any coordinates given 0,0 is top left, larger x moves right, > +larger y moves down. > + > +\begin{description} > + > +\item[VIRTIO_GPU_CMD_GET_DISPLAY_INFO] Retrieve the current output > + configuration. No request data (just bare \field{struct > + virtio_gpu_ctrl_hdr}). Response type is > + VIRTIO_GPU_RESP_OK_DISPLAY_INFO, response data is \field{struct > + virtio_gpu_resp_display_info}. > + > +\begin{lstlisting} > +#define VIRTIO_GPU_MAX_SCANOUTS 16 > + > +struct virtio_gpu_rect { > + le32 x; > + le32 y; > + le32 width; > + le32 height; > +}; > + > +struct virtio_gpu_resp_display_info { > + struct virtio_gpu_ctrl_hdr hdr; > + struct virtio_gpu_display_one { > + struct virtio_gpu_rect r; > + le32 enabled; > + le32 flags; > + } pmodes[VIRTIO_GPU_MAX_SCANOUTS]; > +}; > +\end{lstlisting} > + > +The response contains a list of per-scanout information. The info > +contains whether the scanout is enabled and what its preferred > +position and size is. > + > +The size (fields \field{width} and \field{height}) is similar to the > +native panel resolution in EDID display information, except that in > +the virtual machine case the size can change when the host window > +representing the guest display is gets resized. > + > +The position (fields \field{x} and \field{y}) describe how the > +displays are arranged (i.e. which is -- for example -- the left > +display). > + > +The \field{enabled} field is set when the user enabled the display. > +It is roughly the same as the connected state of a phyiscal display > +connector. > + > +\item[VIRTIO_GPU_CMD_RESOURCE_CREATE_2D] Create a 2D resource on the > + host. Request data is \field{struct virtio_gpu_resource_create_2d}. > + Response type is VIRTIO_GPU_RESP_OK_NODATA. > + > +\begin{lstlisting} > +enum virtio_gpu_formats { > + VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM = 1, > + VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM = 2, > + VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM = 3, > + VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM = 4, > + > + VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM = 67, > + VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM = 68, > + > + VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM = 121, > + VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM = 134, > +}; > + > +struct virtio_gpu_resource_create_2d { > + struct virtio_gpu_ctrl_hdr hdr; > + le32 resource_id; > + le32 format; > + le32 width; > + le32 height; > +}; > +\end{lstlisting} > + > +This creates a 2D resource on the host with the specified width, > +height and format. The resource ids are generated by the guest. > + > +\item[VIRTIO_GPU_CMD_RESOURCE_UNREF] Destroy a resource. Request data > + is \field{struct virtio_gpu_resource_unref}. Response type is > + VIRTIO_GPU_RESP_OK_NODATA. > + > +\begin{lstlisting} > +struct virtio_gpu_resource_unref { > + struct virtio_gpu_ctrl_hdr hdr; > + le32 resource_id; > + le32 padding; > +}; > +\end{lstlisting} > + > +This informs the host that a resource is no longer required by the > +guest. > + > +\item[VIRTIO_GPU_CMD_SET_SCANOUT] Set the scanout parameters for a > + single output. Request data is \field{struct > + virtio_gpu_set_scanout}. Response type is > + VIRTIO_GPU_RESP_OK_NODATA. > + > +\begin{lstlisting} > +struct virtio_gpu_set_scanout { > + struct virtio_gpu_ctrl_hdr hdr; > + struct virtio_gpu_rect r; > + le32 scanout_id; > + le32 resource_id; > +}; > +\end{lstlisting} > + > +This sets the scanout parameters for a single scanout. The resource_id > +is the resource to be scanned out from, along with a rectangle. > + > +Scanout rectangles must be completely covered by the underlying > +resource. Overlapping (or identical) scanouts are allowed, typical > +use case is screen mirroring. > + > +The driver can use resource_id = 0 to disable a scanout. > + > +\item[VIRTIO_GPU_CMD_RESOURCE_FLUSH] Flush a scanout resource Request > + data is \field{struct virtio_gpu_resource_flush}. Response type is > + VIRTIO_GPU_RESP_OK_NODATA. > + > +\begin{lstlisting} > +struct virtio_gpu_resource_flush { > + struct virtio_gpu_ctrl_hdr hdr; > + struct virtio_gpu_rect r; > + le32 resource_id; > + le32 padding; > +}; > +\end{lstlisting} > + > +This flushes a resource to screen. It takes a rectangle and a > +resource id, and flushes any scanouts the resource is being used on. > + > +\item[VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D] Transfer from guest memory > + to host resource. Request data is \field{struct > + virtio_gpu_transfer_to_host_2d}. Response type is > + VIRTIO_GPU_RESP_OK_NODATA. > + > +\begin{lstlisting} > +struct virtio_gpu_transfer_to_host_2d { > + struct virtio_gpu_ctrl_hdr hdr; > + struct virtio_gpu_rect r; > + le64 offset; > + le32 resource_id; > + le32 padding; > +}; > +\end{lstlisting} > + > +This takes a resource id along with an destination offset into the > +resource, and a box to transfer to the host backing for the resource. > + > +\item[VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING] Assign backing pages to > + a resource. Request data is \field{struct > + virtio_gpu_resource_attach_backing}, followed by \field{struct > + virtio_gpu_mem_entry} entries. Response type is > + VIRTIO_GPU_RESP_OK_NODATA. > + > +\begin{lstlisting} > +struct virtio_gpu_resource_attach_backing { > + struct virtio_gpu_ctrl_hdr hdr; > + le32 resource_id; > + le32 nr_entries; > +}; > + > +struct virtio_gpu_mem_entry { > + le64 addr; > + le32 length; > + le32 padding; > +}; > +\end{lstlisting} > + > +This assign an array of guest pages as the backing store for a > +resource. These pages are then used for the transfer operations for > +that resource from that point on. > + > +\item[VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING] Detach backing pages > + from a resource. Request data is \field{struct > + virtio_gpu_resource_detach_backing}. Response type is > + VIRTIO_GPU_RESP_OK_NODATA. > + > +\begin{lstlisting} > +struct virtio_gpu_resource_detach_backing { > + struct virtio_gpu_ctrl_hdr hdr; > + le32 resource_id; > + le32 padding; > +}; > +\end{lstlisting} > + > +This detaches any backing pages from a resource, to be used in case of > +guest swapping or object destruction. > + > +\end{description} > + > +\subsubsection{Device Operation: cursorq}\label{sec:Device Types / GPU Device / Device Operation / Device Operation: cursorq} > + > +Both cursorq commands use the same command struct. > + > +\begin{lstlisting} > +struct virtio_gpu_cursor_pos { > + le32 scanout_id; > + le32 x; > + le32 y; > + le32 padding; > +}; > + > +struct virtio_gpu_update_cursor { > + struct virtio_gpu_ctrl_hdr hdr; > + struct virtio_gpu_cursor_pos pos; > + le32 resource_id; > + le32 hot_x; > + le32 hot_y; > + le32 padding; > +}; > +\end{lstlisting} > + > +\begin{description} > + > +\item[VIRTIO_GPU_CMD_UPDATE_CURSOR] > +Update cursor. > +Request data is \field{struct virtio_gpu_update_cursor}. > +Response type is VIRTIO_GPU_RESP_OK_NODATA. > + > +Full cursor update. Cursor will be loaded from the specified > +\field{resource_id} and will be moved to \field{pos}. The driver must > +transfer the cursor into the resource beforehand (using control queue > +commands) and make sure the commands to fill the resource are actually > +processed (using fencing). > + > +\item[VIRTIO_GPU_CMD_MOVE_CURSOR] > +Move cursor. > +Request data is \field{struct virtio_gpu_update_cursor}. > +Response type is VIRTIO_GPU_RESP_OK_NODATA. > + > +Move cursor to the place specified in \field{pos}. The other fields > +are not used and will be ignored by the device. > + > +\end{description} > + > +\subsection{VGA Compatibility}\label{sec:Device Types / GPU Device / VGA Compatibility} > + > +Applies to Virtio Over PCI only. The GPU device can come with and > +without VGA compatibility. The PCI class should be DISPLAY_VGA if VGA > +compatibility is present and DISPLAY_OTHER otherwise. > + > +VGA compatibility: PCI region 0 has the linear framebuffer, standard > +vga registers are present. Configuring a scanout > +(VIRTIO_GPU_CMD_SET_SCANOUT) switches the device from vga > +compatibility mode into native virtio mode. A reset switches it back > +into vga compatibility mode. > + > +Note: qemu implementation also provides bochs dispi interface io ports > +and mmio bar at pci region 1 and is therefore fully compatible with > +the qemu stdvga (see \href{http://git.qemu-project.org/?p=qemu.git;a=blob;f=docs/specs/standard-vga.txt;hb=HEAD}{docs/specs/standard-vga.txt} in the qemu source tree). > -- > 2.9.3 > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org > For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org --------------------------------------------------------------------- To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [virtio-dev] [PATCH] Add virtio gpu device specification. 2018-07-03 0:15 ` Michael S. Tsirkin @ 2018-07-03 13:03 ` Laszlo Ersek 0 siblings, 0 replies; 6+ messages in thread From: Laszlo Ersek @ 2018-07-03 13:03 UTC (permalink / raw) To: Michael S. Tsirkin, Gerd Hoffmann; +Cc: virtio-dev On 07/03/18 02:15, Michael S. Tsirkin wrote: > On Wed, Jun 27, 2018 at 08:15:25AM +0200, Gerd Hoffmann wrote: >> Support for 2d mode (3d/virgl mode is not covered by this patch) has >> been added to the linux kernel version 4.2 and to qemu version 2.4. >> >> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> > > No comments so far, as Gerd seems to be the only one with both > understanding the field and willing to contribute to the spec, I will > start voting in a couple of days unless there's interest from TC members > in working on this. I remember that, when I was writing the OVMF guest driver against this spec, I found a typo. I don't remember if I notified Gerd at the time. Hmmm. ... Yup, found it: we have an enum constant called VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D, and there is one reference by that name in the text. However, there are three more references to the same thing, but under a (likely obsolete?) name: VIRTIO_GPU_CMD_TRANSFER_SEND_2D. Those should be updated. Gerd, I'm sorry about not raising this earlier. (I'm also sorry about missing the posting on virtio-dev; I've only learned about it today from a different email.) I have no other comments; the spec was sufficient to write the OVMF guest driver against the QEMU device model. Thanks Laszlo >> --- >> content.tex | 2 + >> virtio-gpu.tex | 481 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ >> 2 files changed, 483 insertions(+) >> create mode 100644 virtio-gpu.tex >> >> diff --git a/content.tex b/content.tex >> index be1823431d..d41c2f8d76 100644 >> --- a/content.tex >> +++ b/content.tex >> @@ -5325,6 +5325,8 @@ descriptor for the \field{sense_len}, \field{residual}, >> \field{status_qualifier}, \field{status}, \field{response} and >> \field{sense} fields. >> >> +\input{virtio-gpu.tex} >> + >> \chapter{Reserved Feature Bits}\label{sec:Reserved Feature Bits} >> >> Currently these device-independent feature bits defined: >> diff --git a/virtio-gpu.tex b/virtio-gpu.tex >> new file mode 100644 >> index 0000000000..34cf493bbc >> --- /dev/null >> +++ b/virtio-gpu.tex >> @@ -0,0 +1,481 @@ >> +\section{GPU Device}\label{sec:Device Types / GPU Device} >> + >> +virtio-gpu is a virtio based graphics adapter. It can operate in 2D >> +mode and in 3D (virgl) mode. 3D mode will offload rendering ops to >> +the host gpu and therefore requires a gpu with 3D support on the host >> +machine. >> + >> +3D mode is not covered (yet) in this specification, even though it is >> +mentioned here and there due to some details of the virtual hardware >> +being designed with 3D mode in mind. >> + >> +In 2D mode the virtio-gpu device provides support for ARGB Hardware >> +cursors and multiple scanouts (aka heads). >> + >> +\subsection{Device ID}\label{sec:Device Types / GPU Device / Device ID} >> + >> +16 >> + >> +\subsection{Virtqueues}\label{sec:Device Types / GPU Device / Virtqueues} >> + >> +\begin{description} >> +\item[0] controlq - queue for sending control commands >> +\item[1] cursorq - queue for sending cursor updates >> +\end{description} >> + >> +Both queues have the same format. Each request and each response have >> +a fixed header, followed by command specific data fields. The >> +separate cursor queue is the "fast track" for cursor commands >> +(VIRTIO_GPU_CMD_UPDATE_CURSOR and VIRTIO_GPU_CMD_MOVE_CURSOR), so they >> +go though without being delayed by time-consuming commands in the >> +control queue. >> + >> +\subsection{Feature bits}\label{sec:Device Types / GPU Device / Feature bits} >> + >> +\begin{description} >> +\item[VIRTIO_GPU_F_VIRGL (0)] virgl 3D mode is supported. >> +\end{description} >> + >> +\subsection{Device configuration layout}\label{sec:Device Types / GPU Device / Device configuration layout} >> + >> +\begin{lstlisting} >> +#define VIRTIO_GPU_EVENT_DISPLAY (1 << 0) >> + >> +struct virtio_gpu_config { >> + le32 events_read; >> + le32 events_clear; >> + le32 num_scanouts; >> + le32 reserved; >> +} >> +\end{lstlisting} >> + >> +\subsubsection{Device configuration fields} >> + >> +\begin{description} >> +\item[\field{events_read}] signals pending events to the driver. The >> + driver MUST NOT write to this field. >> +\item[\field{events_clear}] clears pending events in the device. >> + Writing a '1' into a bit will clear the corresponding bit in >> + \field{events_read}, mimicking write-to-clear behavior. >> +\item[\field{num_scanouts}] specifies the maximum number of scanouts >> + supported by the device. Minimum value is 1, maximum value is 16. >> +\end{description} >> + >> +\subsubsection{Events} >> + >> +\begin{description} >> +\item[VIRTIO_GPU_EVENT_DISPLAY] Display configuration has changed. >> + The driver SHOULD use the VIRTIO_GPU_CMD_GET_DISPLAY_INFO command to >> + fetch the information from the device. >> +\end{description} >> + >> +\devicenormative{\subsection}{Device Initialization}{Device Types / GPU Device / Device Initialization} >> + >> +The driver SHOULD query the display information from the device using >> +the VIRTIO_GPU_CMD_GET_DISPLAY_INFO command and use that information >> +for the initial scanout setup. In case no information is available or >> +all displays are disabled the driver MAY choose to use a fallback, >> +such as 1024x768 at display 0. >> + >> +\subsection{Device Operation}\label{sec:Device Types / GPU Device / Device Operation} >> + >> +The virtio-gpu is based around the concept of resources private to the >> +host, the guest must DMA transfer into these resources. This is a >> +design requirement in order to interface with future 3D rendering. In >> +the unaccelerated 2D mode there is no support for DMA transfers from >> +resources, just to them. >> + >> +Resources are initially simple 2D resources, consisting of a width, >> +height and format along with an identifier. The guest must then attach >> +backing store to the resources in order for DMA transfers to >> +work. This is like a GART in a real GPU. >> + >> +\subsubsection{Device Operation: Create a framebuffer and configure scanout} >> + >> +\begin{itemize*} >> +\item Create a host resource using VIRTIO_GPU_CMD_RESOURCE_CREATE_2D. >> +\item Allocate a framebuffer from guest ram, and attach it as backing >> + storage to the resource just created, using >> + VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING. Scatter lists are >> + supported, so the framebuffer doesn't need to be contignous in guest >> + physical memory. >> +\item Use VIRTIO_GPU_CMD_SET_SCANOUT to link the framebuffer to >> + a display scanout. >> +\end{itemize*} >> + >> +\subsubsection{Device Operation: Update a framebuffer and scanout} >> + >> +\begin{itemize*} >> +\item Render to your framebuffer memory. >> +\item Use VIRTIO_GPU_CMD_TRANSFER_SEND_2D to update the host resource >> + from guest memory. >> +\item Use VIRTIO_GPU_CMD_RESOURCE_FLUSH to flush the updated resource >> + to the display. >> +\end{itemize*} >> + >> +\subsubsection{Device Operation: Using pageflip} >> + >> +It is possible to create multiple framebuffers, flip between them >> +using VIRTIO_GPU_CMD_SET_SCANOUT and VIRTIO_GPU_CMD_RESOURCE_FLUSH, >> +and update the invisible framebuffer using >> +VIRTIO_GPU_CMD_TRANSFER_SEND_2D. >> + >> +\subsubsection{Device Operation: Multihead setup} >> + >> +In case two or more displays are present there are different ways to >> +configure things: >> + >> +\begin{itemize*} >> +\item Create a single framebuffer, link it to all displays >> + (mirroring). >> +\item Create an framebuffer for each display. >> +\item Create one big framebuffer, configure scanouts to display a >> + different rectangle of that framebuffer each. >> +\end{itemize*} >> + >> +\devicenormative{\subsubsection}{Device Operation: Command lifecycle and fencing}{Device Types / GPU Device / Device Operation / Device Operation: Command lifecycle and fencing} >> + >> +The device MAY process controlq commands asyncronously and return them >> +to the driver before the processing is complete. If the driver needs >> +to know when the processing is finished it can set the >> +VIRTIO_GPU_FLAG_FENCE flag in the request. The device MUST finish the >> +processing before returning the command then. >> + >> +Note: current qemu implementation does asyncrounous processing only in >> +3d mode, when offloading the processing to the host gpu. >> + >> +\subsubsection{Device Operation: Configure mouse cursor} >> + >> +The mouse cursor image is a normal resource, except that it must be >> +64x64 in size. The driver MUST create and populate the resource >> +(using the usual VIRTIO_GPU_CMD_RESOURCE_CREATE_2D, >> +VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING and >> +VIRTIO_GPU_CMD_TRANSFER_SEND_2D controlq commands) and make sure they >> +are completed (using VIRTIO_GPU_FLAG_FENCE). >> + >> +Then VIRTIO_GPU_CMD_UPDATE_CURSOR can be sent to the cursorq to set >> +the pointer shape and position. To move the pointer without updating >> +the shape use VIRTIO_GPU_CMD_MOVE_CURSOR instead. >> + >> +\subsubsection{Device Operation: Request header}\label{sec:Device Types / GPU Device / Device Operation / Device Operation: Request header} >> + >> +\begin{lstlisting} >> +enum virtio_gpu_ctrl_type { >> + >> + /* 2d commands */ >> + VIRTIO_GPU_CMD_GET_DISPLAY_INFO = 0x0100, >> + VIRTIO_GPU_CMD_RESOURCE_CREATE_2D, >> + VIRTIO_GPU_CMD_RESOURCE_UNREF, >> + VIRTIO_GPU_CMD_SET_SCANOUT, >> + VIRTIO_GPU_CMD_RESOURCE_FLUSH, >> + VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D, >> + VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING, >> + VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING, >> + >> + /* cursor commands */ >> + VIRTIO_GPU_CMD_UPDATE_CURSOR = 0x0300, >> + VIRTIO_GPU_CMD_MOVE_CURSOR, >> + >> + /* success responses */ >> + VIRTIO_GPU_RESP_OK_NODATA = 0x1100, >> + VIRTIO_GPU_RESP_OK_DISPLAY_INFO, >> + >> + /* error responses */ >> + VIRTIO_GPU_RESP_ERR_UNSPEC = 0x1200, >> + VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY, >> + VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID, >> + VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID, >> + VIRTIO_GPU_RESP_ERR_INVALID_CONTEXT_ID, >> + VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER, >> +}; >> + >> +#define VIRTIO_GPU_FLAG_FENCE (1 << 0) >> + >> +struct virtio_gpu_ctrl_hdr { >> + le32 type; >> + le32 flags; >> + le64 fence_id; >> + le32 ctx_id; >> + le32 padding; >> +}; >> +\end{lstlisting} >> + >> +All requests and responses on the virt queues have the fixed header >> +\field{struct virtio_gpu_ctrl_hdr}. >> + >> +\begin{description} >> +\item[\field{type}] specifies the type of the driver request >> + (VIRTIO_GPU_CMD_*) or device response (VIRTIO_GPU_RESP_*). >> +\item[\field{flags}] request / response flags. >> +\item[\field{fence_id}] If the driver sets the VIRTIO_GPU_FLAG_FENCE >> + bit in the request \field{flags} field the device MUST: >> + \begin{itemize*} >> + \item set VIRTIO_GPU_FLAG_FENCE bit in the response, >> + \item copy the content of the \field{fence_id} field from the >> + request to the response, and >> + \item send the response only after command processing is complete. >> + \end{itemize*} >> +\item[\field{ctx_id}] Rendering context (used in 3D mode only). >> +\end{description} >> + >> +On success the device will return VIRTIO_GPU_RESP_OK_NODATA in >> +case there is no payload. Otherwise the \field{type} field will >> +indicate the kind of payload. >> + >> +On error the device will return one of the >> +VIRTIO_GPU_RESP_ERR_* error codes. >> + >> +\subsubsection{Device Operation: controlq}\label{sec:Device Types / GPU Device / Device Operation / Device Operation: controlq} >> + >> +For any coordinates given 0,0 is top left, larger x moves right, >> +larger y moves down. >> + >> +\begin{description} >> + >> +\item[VIRTIO_GPU_CMD_GET_DISPLAY_INFO] Retrieve the current output >> + configuration. No request data (just bare \field{struct >> + virtio_gpu_ctrl_hdr}). Response type is >> + VIRTIO_GPU_RESP_OK_DISPLAY_INFO, response data is \field{struct >> + virtio_gpu_resp_display_info}. >> + >> +\begin{lstlisting} >> +#define VIRTIO_GPU_MAX_SCANOUTS 16 >> + >> +struct virtio_gpu_rect { >> + le32 x; >> + le32 y; >> + le32 width; >> + le32 height; >> +}; >> + >> +struct virtio_gpu_resp_display_info { >> + struct virtio_gpu_ctrl_hdr hdr; >> + struct virtio_gpu_display_one { >> + struct virtio_gpu_rect r; >> + le32 enabled; >> + le32 flags; >> + } pmodes[VIRTIO_GPU_MAX_SCANOUTS]; >> +}; >> +\end{lstlisting} >> + >> +The response contains a list of per-scanout information. The info >> +contains whether the scanout is enabled and what its preferred >> +position and size is. >> + >> +The size (fields \field{width} and \field{height}) is similar to the >> +native panel resolution in EDID display information, except that in >> +the virtual machine case the size can change when the host window >> +representing the guest display is gets resized. >> + >> +The position (fields \field{x} and \field{y}) describe how the >> +displays are arranged (i.e. which is -- for example -- the left >> +display). >> + >> +The \field{enabled} field is set when the user enabled the display. >> +It is roughly the same as the connected state of a phyiscal display >> +connector. >> + >> +\item[VIRTIO_GPU_CMD_RESOURCE_CREATE_2D] Create a 2D resource on the >> + host. Request data is \field{struct virtio_gpu_resource_create_2d}. >> + Response type is VIRTIO_GPU_RESP_OK_NODATA. >> + >> +\begin{lstlisting} >> +enum virtio_gpu_formats { >> + VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM = 1, >> + VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM = 2, >> + VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM = 3, >> + VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM = 4, >> + >> + VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM = 67, >> + VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM = 68, >> + >> + VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM = 121, >> + VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM = 134, >> +}; >> + >> +struct virtio_gpu_resource_create_2d { >> + struct virtio_gpu_ctrl_hdr hdr; >> + le32 resource_id; >> + le32 format; >> + le32 width; >> + le32 height; >> +}; >> +\end{lstlisting} >> + >> +This creates a 2D resource on the host with the specified width, >> +height and format. The resource ids are generated by the guest. >> + >> +\item[VIRTIO_GPU_CMD_RESOURCE_UNREF] Destroy a resource. Request data >> + is \field{struct virtio_gpu_resource_unref}. Response type is >> + VIRTIO_GPU_RESP_OK_NODATA. >> + >> +\begin{lstlisting} >> +struct virtio_gpu_resource_unref { >> + struct virtio_gpu_ctrl_hdr hdr; >> + le32 resource_id; >> + le32 padding; >> +}; >> +\end{lstlisting} >> + >> +This informs the host that a resource is no longer required by the >> +guest. >> + >> +\item[VIRTIO_GPU_CMD_SET_SCANOUT] Set the scanout parameters for a >> + single output. Request data is \field{struct >> + virtio_gpu_set_scanout}. Response type is >> + VIRTIO_GPU_RESP_OK_NODATA. >> + >> +\begin{lstlisting} >> +struct virtio_gpu_set_scanout { >> + struct virtio_gpu_ctrl_hdr hdr; >> + struct virtio_gpu_rect r; >> + le32 scanout_id; >> + le32 resource_id; >> +}; >> +\end{lstlisting} >> + >> +This sets the scanout parameters for a single scanout. The resource_id >> +is the resource to be scanned out from, along with a rectangle. >> + >> +Scanout rectangles must be completely covered by the underlying >> +resource. Overlapping (or identical) scanouts are allowed, typical >> +use case is screen mirroring. >> + >> +The driver can use resource_id = 0 to disable a scanout. >> + >> +\item[VIRTIO_GPU_CMD_RESOURCE_FLUSH] Flush a scanout resource Request >> + data is \field{struct virtio_gpu_resource_flush}. Response type is >> + VIRTIO_GPU_RESP_OK_NODATA. >> + >> +\begin{lstlisting} >> +struct virtio_gpu_resource_flush { >> + struct virtio_gpu_ctrl_hdr hdr; >> + struct virtio_gpu_rect r; >> + le32 resource_id; >> + le32 padding; >> +}; >> +\end{lstlisting} >> + >> +This flushes a resource to screen. It takes a rectangle and a >> +resource id, and flushes any scanouts the resource is being used on. >> + >> +\item[VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D] Transfer from guest memory >> + to host resource. Request data is \field{struct >> + virtio_gpu_transfer_to_host_2d}. Response type is >> + VIRTIO_GPU_RESP_OK_NODATA. >> + >> +\begin{lstlisting} >> +struct virtio_gpu_transfer_to_host_2d { >> + struct virtio_gpu_ctrl_hdr hdr; >> + struct virtio_gpu_rect r; >> + le64 offset; >> + le32 resource_id; >> + le32 padding; >> +}; >> +\end{lstlisting} >> + >> +This takes a resource id along with an destination offset into the >> +resource, and a box to transfer to the host backing for the resource. >> + >> +\item[VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING] Assign backing pages to >> + a resource. Request data is \field{struct >> + virtio_gpu_resource_attach_backing}, followed by \field{struct >> + virtio_gpu_mem_entry} entries. Response type is >> + VIRTIO_GPU_RESP_OK_NODATA. >> + >> +\begin{lstlisting} >> +struct virtio_gpu_resource_attach_backing { >> + struct virtio_gpu_ctrl_hdr hdr; >> + le32 resource_id; >> + le32 nr_entries; >> +}; >> + >> +struct virtio_gpu_mem_entry { >> + le64 addr; >> + le32 length; >> + le32 padding; >> +}; >> +\end{lstlisting} >> + >> +This assign an array of guest pages as the backing store for a >> +resource. These pages are then used for the transfer operations for >> +that resource from that point on. >> + >> +\item[VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING] Detach backing pages >> + from a resource. Request data is \field{struct >> + virtio_gpu_resource_detach_backing}. Response type is >> + VIRTIO_GPU_RESP_OK_NODATA. >> + >> +\begin{lstlisting} >> +struct virtio_gpu_resource_detach_backing { >> + struct virtio_gpu_ctrl_hdr hdr; >> + le32 resource_id; >> + le32 padding; >> +}; >> +\end{lstlisting} >> + >> +This detaches any backing pages from a resource, to be used in case of >> +guest swapping or object destruction. >> + >> +\end{description} >> + >> +\subsubsection{Device Operation: cursorq}\label{sec:Device Types / GPU Device / Device Operation / Device Operation: cursorq} >> + >> +Both cursorq commands use the same command struct. >> + >> +\begin{lstlisting} >> +struct virtio_gpu_cursor_pos { >> + le32 scanout_id; >> + le32 x; >> + le32 y; >> + le32 padding; >> +}; >> + >> +struct virtio_gpu_update_cursor { >> + struct virtio_gpu_ctrl_hdr hdr; >> + struct virtio_gpu_cursor_pos pos; >> + le32 resource_id; >> + le32 hot_x; >> + le32 hot_y; >> + le32 padding; >> +}; >> +\end{lstlisting} >> + >> +\begin{description} >> + >> +\item[VIRTIO_GPU_CMD_UPDATE_CURSOR] >> +Update cursor. >> +Request data is \field{struct virtio_gpu_update_cursor}. >> +Response type is VIRTIO_GPU_RESP_OK_NODATA. >> + >> +Full cursor update. Cursor will be loaded from the specified >> +\field{resource_id} and will be moved to \field{pos}. The driver must >> +transfer the cursor into the resource beforehand (using control queue >> +commands) and make sure the commands to fill the resource are actually >> +processed (using fencing). >> + >> +\item[VIRTIO_GPU_CMD_MOVE_CURSOR] >> +Move cursor. >> +Request data is \field{struct virtio_gpu_update_cursor}. >> +Response type is VIRTIO_GPU_RESP_OK_NODATA. >> + >> +Move cursor to the place specified in \field{pos}. The other fields >> +are not used and will be ignored by the device. >> + >> +\end{description} >> + >> +\subsection{VGA Compatibility}\label{sec:Device Types / GPU Device / VGA Compatibility} >> + >> +Applies to Virtio Over PCI only. The GPU device can come with and >> +without VGA compatibility. The PCI class should be DISPLAY_VGA if VGA >> +compatibility is present and DISPLAY_OTHER otherwise. >> + >> +VGA compatibility: PCI region 0 has the linear framebuffer, standard >> +vga registers are present. Configuring a scanout >> +(VIRTIO_GPU_CMD_SET_SCANOUT) switches the device from vga >> +compatibility mode into native virtio mode. A reset switches it back >> +into vga compatibility mode. >> + >> +Note: qemu implementation also provides bochs dispi interface io ports >> +and mmio bar at pci region 1 and is therefore fully compatible with >> +the qemu stdvga (see \href{http://git.qemu-project.org/?p=qemu.git;a=blob;f=docs/specs/standard-vga.txt;hb=HEAD}{docs/specs/standard-vga.txt} in the qemu source tree). >> -- >> 2.9.3 >> >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org >> For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org > > --------------------------------------------------------------------- > To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org > For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org > --------------------------------------------------------------------- To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2018-07-03 13:03 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1462367134-23894-1-git-send-email-kraxel@redhat.com>
[not found] ` <20160509144316.GI3372@stefanha-x1.localdomain>
[not found] ` <1462874939.8035.52.camel@redhat.com>
[not found] ` <1462879537.8035.53.camel@redhat.com>
2018-06-20 3:15 ` [virtio-dev] [PATCH] Add virtio gpu device specification Michael S. Tsirkin
2018-06-27 6:15 ` Gerd Hoffmann
2018-06-27 18:56 ` Michael S. Tsirkin
2018-06-27 6:15 Gerd Hoffmann
2018-07-03 0:15 ` Michael S. Tsirkin
2018-07-03 13:03 ` Laszlo Ersek
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox