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

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