99cbc7
From a701d9ee0f3e5cd939356191f25d0ec378dbb5c4 Mon Sep 17 00:00:00 2001
99cbc7
Message-Id: <a701d9ee0f3e5cd939356191f25d0ec378dbb5c4@dist-git>
99cbc7
From: Erik Skultety <eskultet@redhat.com>
99cbc7
Date: Tue, 9 Apr 2019 08:34:31 +0200
99cbc7
Subject: [PATCH] conf: gfx: egl-headless: Introduce a new <gl> subelement
99cbc7
MIME-Version: 1.0
99cbc7
Content-Type: text/plain; charset=UTF-8
99cbc7
Content-Transfer-Encoding: 8bit
99cbc7
99cbc7
Unlike with SPICE and SDL which use the <gl> subelement to enable OpenGL
99cbc7
acceleration, specifying egl-headless graphics in the XML has
99cbc7
essentially the same meaning, thus in case of egl-headless we don't have
99cbc7
a need for the 'enable' element attribute and we'll only be interested
99cbc7
in the 'rendernode' one further down the road.
99cbc7
99cbc7
Signed-off-by: Erik Skultety <eskultet@redhat.com>
99cbc7
Reviewed-by: Ján Tomko <jtomko@redhat.com>
99cbc7
(cherry picked from commit 5f931fe39112129efb1204a1aac60b180ef31b42)
99cbc7
99cbc7
https: //bugzilla.redhat.com/show_bug.cgi?id=1628892
99cbc7
Signed-off-by: Erik Skultety <eskultet@redhat.com>
99cbc7
Message-Id: <a52b7103d576f2713b6d1839e2bc7e2381b80519.1554791287.git.eskultet@redhat.com>
99cbc7
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
99cbc7
---
99cbc7
 docs/formatdomain.html.in                     | 11 +++--
99cbc7
 docs/schemas/domaincommon.rng                 | 17 +++++--
99cbc7
 src/conf/domain_conf.c                        | 45 ++++++++++++++++++-
99cbc7
 src/qemu/qemu_process.c                       | 17 +++++--
99cbc7
 .../graphics-egl-headless-rendernode.xml      | 33 ++++++++++++++
99cbc7
 .../graphics-egl-headless-rendernode.xml      | 41 +++++++++++++++++
99cbc7
 tests/qemuxml2xmltest.c                       |  2 +
99cbc7
 7 files changed, 156 insertions(+), 10 deletions(-)
99cbc7
 create mode 100644 tests/qemuxml2argvdata/graphics-egl-headless-rendernode.xml
99cbc7
 create mode 100644 tests/qemuxml2xmloutdata/graphics-egl-headless-rendernode.xml
99cbc7
99cbc7
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
99cbc7
index 8cf2c12524..e848dc1e0d 100644
99cbc7
--- a/docs/formatdomain.html.in
99cbc7
+++ b/docs/formatdomain.html.in
99cbc7
@@ -6573,12 +6573,17 @@ qemu-kvm -net nic,model=? /dev/null
99cbc7
               the other types, for practical reasons it should be paired with
99cbc7
               either vnc or spice graphics types.
99cbc7
               This display type is only supported by QEMU domains
99cbc7
-              (needs QEMU 2.10 or newer) and doesn't
99cbc7
-              accept any attributes.
99cbc7
+              (needs QEMU 2.10 or newer).
99cbc7
+              5.0.0 this element accepts a
99cbc7
+              <gl/> sub-element with an optional attribute
99cbc7
+              rendernode which can be used to specify an absolute
99cbc7
+              path to a host's DRI device to be used for OpenGL rendering.
99cbc7
             

99cbc7
             
99cbc7
 <graphics type='spice' autoport='yes'/>
99cbc7
-<graphics type='egl-headless'/>
99cbc7
+<graphics type='egl-headless'>
99cbc7
+  <gl rendernode='/dev/dri/renderD128'/>
99cbc7
+</graphics>
99cbc7
             
99cbc7
           
99cbc7
         
99cbc7
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
99cbc7
index 48f0637cad..f37ee4d354 100644
99cbc7
--- a/docs/schemas/domaincommon.rng
99cbc7
+++ b/docs/schemas/domaincommon.rng
99cbc7
@@ -3383,9 +3383,20 @@
99cbc7
             </attribute>
99cbc7
           </optional>
99cbc7
         </group>
99cbc7
-        <attribute name="type">
99cbc7
-          <value>egl-headless</value>
99cbc7
-        </attribute>
99cbc7
+        <group>
99cbc7
+          <attribute name="type">
99cbc7
+            <value>egl-headless</value>
99cbc7
+          </attribute>
99cbc7
+          <optional>
99cbc7
+            <element name="gl">
99cbc7
+              <optional>
99cbc7
+                <attribute name="rendernode">
99cbc7
+                  <ref name="absFilePath"/>
99cbc7
+                </attribute>
99cbc7
+              </optional>
99cbc7
+            </element>
99cbc7
+          </optional>
99cbc7
+        </group>
99cbc7
       </choice>
99cbc7
     </element>
99cbc7
   </define>
99cbc7
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
99cbc7
index d079be2bb5..1aef0c76f8 100644
99cbc7
--- a/src/conf/domain_conf.c
99cbc7
+++ b/src/conf/domain_conf.c
99cbc7
@@ -14274,6 +14274,24 @@ virDomainGraphicsDefParseXMLSpice(virDomainGraphicsDefPtr def,
99cbc7
 }
99cbc7
 
99cbc7
 
99cbc7
+static int
99cbc7
+virDomainGraphicsDefParseXMLEGLHeadless(virDomainGraphicsDefPtr def,
99cbc7
+                                        xmlNodePtr node,
99cbc7
+                                        xmlXPathContextPtr ctxt)
99cbc7
+{
99cbc7
+    xmlNodePtr save = ctxt->node;
99cbc7
+    xmlNodePtr glNode;
99cbc7
+
99cbc7
+    ctxt->node = node;
99cbc7
+
99cbc7
+    if ((glNode = virXPathNode("./gl", ctxt)))
99cbc7
+        def->data.egl_headless.rendernode = virXMLPropString(glNode,
99cbc7
+                                                             "rendernode");
99cbc7
+    ctxt->node = save;
99cbc7
+    return 0;
99cbc7
+}
99cbc7
+
99cbc7
+
99cbc7
 /* Parse the XML definition for a graphics device */
99cbc7
 static virDomainGraphicsDefPtr
99cbc7
 virDomainGraphicsDefParseXML(xmlNodePtr node,
99cbc7
@@ -14323,6 +14341,9 @@ virDomainGraphicsDefParseXML(xmlNodePtr node,
99cbc7
             goto error;
99cbc7
         break;
99cbc7
     case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
99cbc7
+        if (virDomainGraphicsDefParseXMLEGLHeadless(def, node, ctxt) < 0)
99cbc7
+            goto error;
99cbc7
+        break;
99cbc7
     case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
99cbc7
         break;
99cbc7
     }
99cbc7
@@ -26724,6 +26745,20 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
99cbc7
         break;
99cbc7
 
99cbc7
     case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
99cbc7
+        if (!def->data.egl_headless.rendernode)
99cbc7
+            break;
99cbc7
+
99cbc7
+        if (!children) {
99cbc7
+            virBufferAddLit(buf, ">\n");
99cbc7
+            virBufferAdjustIndent(buf, 2);
99cbc7
+            children = true;
99cbc7
+        }
99cbc7
+
99cbc7
+        virBufferAddLit(buf, "
99cbc7
+        virBufferEscapeString(buf, " rendernode='%s'",
99cbc7
+                              def->data.egl_headless.rendernode);
99cbc7
+        virBufferAddLit(buf, "/>\n");
99cbc7
+        break;
99cbc7
     case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
99cbc7
         break;
99cbc7
     }
99cbc7
@@ -30718,7 +30753,13 @@ virDomainGraphicsDefHasOpenGL(const virDomainDef *def)
99cbc7
 bool
99cbc7
 virDomainGraphicsSupportsRenderNode(const virDomainGraphicsDef *graphics)
99cbc7
 {
99cbc7
-    return graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE;
99cbc7
+    bool ret = false;
99cbc7
+
99cbc7
+    if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE ||
99cbc7
+        graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS)
99cbc7
+        ret = true;
99cbc7
+
99cbc7
+    return ret;
99cbc7
 }
99cbc7
 
99cbc7
 
99cbc7
@@ -30733,6 +30774,8 @@ virDomainGraphicsGetRenderNode(const virDomainGraphicsDef *graphics)
99cbc7
             ret = graphics->data.spice.rendernode;
99cbc7
         break;
99cbc7
     case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
99cbc7
+        ret = graphics->data.egl_headless.rendernode;
99cbc7
+        break;
99cbc7
     case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
99cbc7
     case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
99cbc7
     case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
99cbc7
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
99cbc7
index 465dabd8e3..8811aefb95 100644
99cbc7
--- a/src/qemu/qemu_process.c
99cbc7
+++ b/src/qemu/qemu_process.c
99cbc7
@@ -4755,14 +4755,25 @@ static int
99cbc7
 qemuProcessGraphicsSetupRenderNode(virDomainGraphicsDefPtr graphics,
99cbc7
                                    virQEMUCapsPtr qemuCaps)
99cbc7
 {
99cbc7
+    char **rendernode = NULL;
99cbc7
+
99cbc7
     if (!virDomainGraphicsNeedsAutoRenderNode(graphics))
99cbc7
         return 0;
99cbc7
 
99cbc7
     /* Don't bother picking a DRM node if QEMU doesn't support it. */
99cbc7
-    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_RENDERNODE))
99cbc7
-        return 0;
99cbc7
+    if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
99cbc7
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_RENDERNODE))
99cbc7
+            return 0;
99cbc7
 
99cbc7
-    if (!(graphics->data.spice.rendernode = virHostGetDRMRenderNode()))
99cbc7
+        rendernode = &graphics->data.spice.rendernode;
99cbc7
+    } else {
99cbc7
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_EGL_HEADLESS_RENDERNODE))
99cbc7
+            return 0;
99cbc7
+
99cbc7
+        rendernode = &graphics->data.egl_headless.rendernode;
99cbc7
+    }
99cbc7
+
99cbc7
+    if (!(*rendernode = virHostGetDRMRenderNode()))
99cbc7
         return -1;
99cbc7
 
99cbc7
     return 0;
99cbc7
diff --git a/tests/qemuxml2argvdata/graphics-egl-headless-rendernode.xml b/tests/qemuxml2argvdata/graphics-egl-headless-rendernode.xml
99cbc7
new file mode 100644
99cbc7
index 0000000000..a8d54e75da
99cbc7
--- /dev/null
99cbc7
+++ b/tests/qemuxml2argvdata/graphics-egl-headless-rendernode.xml
99cbc7
@@ -0,0 +1,33 @@
99cbc7
+<domain type='qemu'>
99cbc7
+  <name>QEMUGuest1</name>
99cbc7
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
99cbc7
+  <memory unit='KiB'>219100</memory>
99cbc7
+  <currentMemory unit='KiB'>219100</currentMemory>
99cbc7
+  <vcpu placement='static'>1</vcpu>
99cbc7
+  <os>
99cbc7
+    <type arch='i686' machine='pc'>hvm</type>
99cbc7
+    <boot dev='hd'/>
99cbc7
+  </os>
99cbc7
+  <clock offset='utc'/>
99cbc7
+  <on_poweroff>destroy</on_poweroff>
99cbc7
+  <on_reboot>restart</on_reboot>
99cbc7
+  <on_crash>destroy</on_crash>
99cbc7
+  <devices>
99cbc7
+    <emulator>/usr/bin/qemu-system-i686</emulator>
99cbc7
+    <disk type='block' device='disk'>
99cbc7
+      <driver name='qemu' type='raw'/>
99cbc7
+      <source dev='/dev/HostVG/QEMUGuest1'/>
99cbc7
+      <target dev='hda' bus='ide'/>
99cbc7
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
99cbc7
+    </disk>
99cbc7
+    <controller type='usb' index='0'/>
99cbc7
+    <controller type='ide' index='0'/>
99cbc7
+    <controller type='pci' index='0' model='pci-root'/>
99cbc7
+    <input type='mouse' bus='ps2'/>
99cbc7
+    <input type='keyboard' bus='ps2'/>
99cbc7
+    <graphics type='egl-headless'>
99cbc7
+      <gl rendernode='/dev/dri/foo'/>
99cbc7
+    </graphics>
99cbc7
+    <memballoon model='none'/>
99cbc7
+  </devices>
99cbc7
+</domain>
99cbc7
diff --git a/tests/qemuxml2xmloutdata/graphics-egl-headless-rendernode.xml b/tests/qemuxml2xmloutdata/graphics-egl-headless-rendernode.xml
99cbc7
new file mode 100644
99cbc7
index 0000000000..9b7ac89928
99cbc7
--- /dev/null
99cbc7
+++ b/tests/qemuxml2xmloutdata/graphics-egl-headless-rendernode.xml
99cbc7
@@ -0,0 +1,41 @@
99cbc7
+<domain type='qemu'>
99cbc7
+  <name>QEMUGuest1</name>
99cbc7
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
99cbc7
+  <memory unit='KiB'>219100</memory>
99cbc7
+  <currentMemory unit='KiB'>219100</currentMemory>
99cbc7
+  <vcpu placement='static'>1</vcpu>
99cbc7
+  <os>
99cbc7
+    <type arch='i686' machine='pc'>hvm</type>
99cbc7
+    <boot dev='hd'/>
99cbc7
+  </os>
99cbc7
+  <clock offset='utc'/>
99cbc7
+  <on_poweroff>destroy</on_poweroff>
99cbc7
+  <on_reboot>restart</on_reboot>
99cbc7
+  <on_crash>destroy</on_crash>
99cbc7
+  <devices>
99cbc7
+    <emulator>/usr/bin/qemu-system-i686</emulator>
99cbc7
+    <disk type='block' device='disk'>
99cbc7
+      <driver name='qemu' type='raw'/>
99cbc7
+      <source dev='/dev/HostVG/QEMUGuest1'/>
99cbc7
+      <target dev='hda' bus='ide'/>
99cbc7
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
99cbc7
+    </disk>
99cbc7
+    <controller type='usb' index='0'>
99cbc7
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
99cbc7
+    </controller>
99cbc7
+    <controller type='ide' index='0'>
99cbc7
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
99cbc7
+    </controller>
99cbc7
+    <controller type='pci' index='0' model='pci-root'/>
99cbc7
+    <input type='mouse' bus='ps2'/>
99cbc7
+    <input type='keyboard' bus='ps2'/>
99cbc7
+    <graphics type='egl-headless'>
99cbc7
+      <gl rendernode='/dev/dri/foo'/>
99cbc7
+    </graphics>
99cbc7
+    <video>
99cbc7
+      <model type='cirrus' vram='16384' heads='1' primary='yes'/>
99cbc7
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
99cbc7
+    </video>
99cbc7
+    <memballoon model='none'/>
99cbc7
+  </devices>
99cbc7
+</domain>
99cbc7
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
99cbc7
index 5bd522e765..1f67d74797 100644
99cbc7
--- a/tests/qemuxml2xmltest.c
99cbc7
+++ b/tests/qemuxml2xmltest.c
99cbc7
@@ -434,6 +434,8 @@ mymain(void)
99cbc7
     cfg->spiceAutoUnixSocket = false;
99cbc7
     DO_TEST("graphics-spice-egl-headless", NONE);
99cbc7
 
99cbc7
+    DO_TEST("graphics-egl-headless-rendernode", NONE);
99cbc7
+
99cbc7
     DO_TEST("input-usbmouse", NONE);
99cbc7
     DO_TEST("input-usbtablet", NONE);
99cbc7
     DO_TEST("misc-acpi", NONE);
99cbc7
-- 
99cbc7
2.21.0
99cbc7