[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]
Subject: [PATCH] Add virtio gpu specification.
Signed-off-by: Dave Airlie <airlied@redhat.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- content.tex | 2 + virtio-gpu.tex | 406 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 408 insertions(+) create mode 100644 virtio-gpu.tex diff --git a/content.tex b/content.tex index 5bfb082..00ce4dc 100644 --- a/content.tex +++ b/content.tex @@ -5138,6 +5138,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 there are three device-independent feature bits defined: diff --git a/virtio-gpu.tex b/virtio-gpu.tex new file mode 100644 index 0000000..e62021d --- /dev/null +++ b/virtio-gpu.tex @@ -0,0 +1,406 @@ +\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 still work-in-progress and 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 position and resource 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-related commands, +so they go though without being possibly delayed by other commands in +the control queue. + +\subsection{Feature bits}\label{sec:Device Types / GPU Device / Feature bits} + +There are no feature bits (yet). +There will be one in the future for 3D mode support. + +\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 { + uint32_t events_read; + uint32_t events_clear; + uint32_t num_scanouts; + uint32_t 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 number of scanouts supported + by the device +\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} + +\subsection{Device Initialization}\label{sec:Device Types / GPU Device / Device Initialization} + +TODO. + +\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. + +A typical guest user would create a 2D resource using +VIRTIO_GPU_CMD_RESOURCE_CREATE_2D, attach backing store using +VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING, then attach the resource to a +scanout using VIRTIO_GPU_CMD_SET_SCANOUT, then use +VIRTIO_GPU_CMD_TRANSFER_SEND_2D to send updates to the resource, and +finally VIRTIO_GPU_CMD_RESOURCE_FLUSH to flush the scanout buffers to +screen. + +\subsubsection{Device Operation: header}\label{sec:Device Types / GPU Device / Device Operation / Device Operation: 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 { + uint32_t type; + uint32_t flags; + uint64_t fence_id; + uint32_t ctx_id; + uint32_t 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 will (a) set + VIRTIO_GPU_FLAG_FENCE bit in the response, (b) copy the content of + the \field{fence_id} field from the request to the response and (c) + send the response only after command processing is complete. +\item[\field{ctx_id}] Not used in 2D mode. +\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_resp_display_info { + struct virtio_gpu_ctrl_hdr hdr; + struct virtio_gpu_display_one { + uint32_t enabled; + uint32_t width; + uint32_t height; + uint32_t x; + uint32_t y; + uint32_t 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). + +\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_B5G5R5A1_UNORM = 5, + VIRTIO_GPU_FORMAT_B5G6R5_UNORM = 7, + + VIRTIO_GPU_FORMAT_R8_UNORM = 64, +}; + +struct virtio_gpu_resource_create_2d { + struct virtio_gpu_ctrl_hdr hdr; + uint32_t resource_id; + uint32_t format; + uint32_t width; + uint32_t 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; + uint32_t resource_id; + uint32_t 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; + uint32_t scanout_id; + uint32_t resource_id; + uint32_t width; + uint32_t height; + uint32_t x; + uint32_t y; +}; +\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 +specified by x, y, width and height. + +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; + uint32_t resource_id; + uint32_t width; + uint32_t height; + uint32_t x; + uint32_t y; + uint32_t 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; + uint32_t resource_id; + uint32_t offset; + uint32_t width; + uint32_t height; + uint32_t x; + uint32_t y; +}; +\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; + uint32_t resource_id; + uint32_t nr_entries; +}; + +struct virtio_gpu_mem_entry { + uint64_t addr; + uint32_t length; + uint32_t 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; + uint32_t resource_id; + uint32_t 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 { + uint32_t scanout_id; + uint32_t x; + uint32_t y; + uint32_t padding; +}; + +struct virtio_gpu_update_cursor { + struct virtio_gpu_ctrl_hdr hdr; + struct virtio_gpu_cursor_pos pos; + uint32_t resource_id; + uint32_t hot_x; + uint32_t hot_y; + uint32_t 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. Ciesor 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). + +\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 2 has a linear framebuffer, standard vga +and bochs dispi interface registers are present. Enabling virtio +switches the device from vga compat into native virtio mode. + -- 1.8.3.1
[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]