#5 Backport patch to support NVIDIA PRIME Render Offload
Opened 2 months ago by scorpionit. Modified 2 months ago
rpms/ scorpionit/xorg-x11-server master  into  master

@@ -0,0 +1,87 @@ 

+ diff --git a/glx/vndext.c b/glx/vndext.c

+ index 20c0648ccfc9fc592a552725c0d0fef609db7362..582e60b6e7412148903f3f19aacc1e3ff3478a96 100644

+ --- a/glx/vndext.c

+ +++ b/glx/vndext.c

+ @@ -324,6 +324,7 @@ _X_EXPORT const GlxServerExports glxServer = {

+      .getContextTagPrivate = GlxGetContextTagPrivate,

+      .getVendorForScreen = GlxGetVendorForScreen,

+      .forwardRequest =  GlxForwardRequest,

+ +    .setClientScreenVendor = GlxSetClientScreenVendor,

+  };

+  

+  const GlxServerExports *

+ diff --git a/glx/vndserver.h b/glx/vndserver.h

+ index 613fef0fe221b5a1fbc8d35b562edb167b772196..772b458a1c8d27b96ae6f00933ec78cf607fdb22 100644

+ --- a/glx/vndserver.h

+ +++ b/glx/vndserver.h

+ @@ -107,6 +107,7 @@ GlxContextTagInfo *GlxLookupContextTag(ClientPtr client, GLXContextTag tag);

+  void GlxFreeContextTag(GlxContextTagInfo *tagInfo);

+  

+  Bool GlxSetScreenVendor(ScreenPtr screen, GlxServerVendor *vendor);

+ +Bool GlxSetClientScreenVendor(ClientPtr client, ScreenPtr screen, GlxServerVendor *vendor);

+  GlxScreenPriv *GlxGetScreen(ScreenPtr pScreen);

+  GlxServerVendor *GlxGetVendorForScreen(ClientPtr client, ScreenPtr screen);

+  

+ diff --git a/glx/vndservermapping.c b/glx/vndservermapping.c

+ index 4efab8b81d1eadd84ada3de078e17d7ad51661d6..04788ffbdd78fb2c4812c13de55f7c39e3765ff3 100644

+ --- a/glx/vndservermapping.c

+ +++ b/glx/vndservermapping.c

+ @@ -189,6 +189,27 @@ Bool GlxSetScreenVendor(ScreenPtr screen, GlxServerVendor *vendor)

+      return TRUE;

+  }

+  

+ +Bool GlxSetClientScreenVendor(ClientPtr client, ScreenPtr screen, GlxServerVendor *vendor)

+ +{

+ +    GlxClientPriv *cl;

+ +

+ +    if (screen == NULL || screen->isGPU) {

+ +        return FALSE;

+ +    }

+ +

+ +    cl = GlxGetClientData(client);

+ +    if (cl == NULL) {

+ +        return FALSE;

+ +    }

+ +

+ +    if (vendor != NULL) {

+ +        cl->vendors[screen->myNum] = vendor;

+ +    } else {

+ +        cl->vendors[screen->myNum] = GlxGetVendorForScreen(NULL, screen);

+ +    }

+ +    return TRUE;

+ +}

+ +

+  GlxServerVendor *GlxGetVendorForScreen(ClientPtr client, ScreenPtr screen)

+  {

+      // Note that the client won't be sending GPU screen numbers, so we don't

+ diff --git a/include/glxvndabi.h b/include/glxvndabi.h

+ index b78306d235aa88843cf2b38e049371c2195e7555..71f36e7222ced5f0e6ebd6932bbb215242c6ba72 100644

+ --- a/include/glxvndabi.h

+ +++ b/include/glxvndabi.h

+ @@ -75,7 +75,7 @@

+   * will still work.

+   */

+  #define GLXSERVER_VENDOR_ABI_MAJOR_VERSION 0

+ -#define GLXSERVER_VENDOR_ABI_MINOR_VERSION 0

+ +#define GLXSERVER_VENDOR_ABI_MINOR_VERSION 1

+  

+  #if defined(__cplusplus)

+  extern "C" {

+ @@ -236,6 +236,17 @@ typedef struct GlxServerExportsRec {

+       * \param client The client.

+       */

+      int (* forwardRequest) (GlxServerVendor *vendor, ClientPtr client);

+ +

+ +    /**

+ +     * Sets the vendor library to use for a screen for a specific client.

+ +     *

+ +     * This function changes which vendor should handle GLX requests for a

+ +     * screen. Unlike \c setScreenVendor, this function can be called at any

+ +     * time, and only applies to requests from a single client.

+ +     *

+ +     * This function is available in GLXVND version 0.1 or later.

+ +     */

+ +    Bool (* setClientScreenVendor) (ClientPtr client, ScreenPtr screen, GlxServerVendor *vendor);

+  } GlxServerExports;

+  

+  extern _X_EXPORT const GlxServerExports glxServer;

@@ -0,0 +1,69 @@ 

+ diff --git a/glx/vndext.c b/glx/vndext.c

+ index d7936467be5858f1c63d8d5cd4e4fec2a91fd4cc..20c0648ccfc9fc592a552725c0d0fef609db7362 100644

+ --- a/glx/vndext.c

+ +++ b/glx/vndext.c

+ @@ -139,8 +139,17 @@ GlxGetClientData(ClientPtr client)

+  {

+      GlxClientPriv *cl = xglvGetClientPrivate(client);

+      if (cl == NULL) {

+ -        cl = calloc(1, sizeof(GlxClientPriv));

+ +        cl = calloc(1, sizeof(GlxClientPriv)

+ +                + screenInfo.numScreens * sizeof(GlxServerVendor *));

+          if (cl != NULL) {

+ +            int i;

+ +

+ +            cl->vendors = (GlxServerVendor **) (cl + 1);

+ +            for (i=0; i<screenInfo.numScreens; i++)

+ +            {

+ +                cl->vendors[i] = GlxGetVendorForScreen(NULL, screenInfo.screens[i]);

+ +            }

+ +

+              xglvSetClientPrivate(client, cl);

+          }

+      }

+ diff --git a/glx/vndserver.h b/glx/vndserver.h

+ index a175656ae7c22fcc0e4bf74bb9067312fb5ec14a..78246d212cea42f923808852159c973e3b64318d 100644

+ --- a/glx/vndserver.h

+ +++ b/glx/vndserver.h

+ @@ -57,6 +57,11 @@ typedef struct GlxContextTagInfoRec {

+  typedef struct GlxClientPrivRec {

+      GlxContextTagInfo *contextTags;

+      unsigned int contextTagCount;

+ +

+ +    /**

+ +     * The vendor handles for each screen.

+ +     */

+ +    GlxServerVendor **vendors;

+  } GlxClientPriv;

+  

+  extern int GlxErrorBase;

+ diff --git a/glx/vndservermapping.c b/glx/vndservermapping.c

+ index fd3be92d95c28969291ca0c50a77d49a29007a8e..778656bb6eadcad43afe0e985c14a67eb44402a4 100644

+ --- a/glx/vndservermapping.c

+ +++ b/glx/vndservermapping.c

+ @@ -187,10 +187,21 @@ Bool GlxSetScreenVendor(ScreenPtr screen, GlxServerVendor *vendor)

+  

+  GlxServerVendor *GlxGetVendorForScreen(ClientPtr client, ScreenPtr screen)

+  {

+ -    GlxScreenPriv *priv = GlxGetScreen(screen);

+ -    if (priv != NULL) {

+ -        return priv->vendor;

+ +    // Note that the client won't be sending GPU screen numbers, so we don't

+ +    // need per-client mappings for them.

+ +    if (client != NULL && !screen->isGPU) {

+ +        GlxClientPriv *cl = GlxGetClientData(client);

+ +        if (cl != NULL) {

+ +            return cl->vendors[screen->myNum];

+ +        } else {

+ +            return NULL;

+ +        }

+      } else {

+ -        return NULL;

+ +        GlxScreenPriv *priv = GlxGetScreen(screen);

+ +        if (priv != NULL) {

+ +            return priv->vendor;

+ +        } else {

+ +            return NULL;

+ +        }

+      }

+  }

@@ -0,0 +1,15 @@ 

+ diff --git a/glx/vndext.c b/glx/vndext.c

+ index 582e60b6e7412148903f3f19aacc1e3ff3478a96..0513733b65c37c030001015ee0cac3d5715fc52c 100644

+ --- a/glx/vndext.c

+ +++ b/glx/vndext.c

+ @@ -304,8 +304,8 @@ GlxFreeServerImports(GlxServerImports *imports)

+  }

+  

+  _X_EXPORT const GlxServerExports glxServer = {

+ -    .majorVersion = 0,

+ -    .minorVersion = 0,

+ +    .majorVersion = GLXSERVER_VENDOR_ABI_MAJOR_VERSION,

+ +    .minorVersion = GLXSERVER_VENDOR_ABI_MINOR_VERSION,

+  

+      .extensionInitCallback = &vndInitCallbackListPtr,

+  

@@ -0,0 +1,79 @@ 

+ diff --git a/glx/vndcmds.c b/glx/vndcmds.c

+ index f0779d14a26161abef41a6fc782a077ee60d2051..21c6fef9ea57e7e4f40d182e1ea2881fce18aacd 100644

+ --- a/glx/vndcmds.c

+ +++ b/glx/vndcmds.c

+ @@ -468,15 +468,24 @@ void GlxDispatchReset(void)

+  int GlxDispatchRequest(ClientPtr client)

+  {

+      REQUEST(xReq);

+ +    int result;

+ +

+      if (GlxExtensionEntry->base == 0)

+          return BadRequest;

+ +

+ +    GlxSetRequestClient(client);

+ +

+      if (stuff->data < OPCODE_ARRAY_LEN) {

+          if (dispatchFuncs[stuff->data] == NULL) {

+              // Try to find a dispatch stub.

+              dispatchFuncs[stuff->data] = GetVendorDispatchFunc(stuff->data, 0);

+          }

+ -        return dispatchFuncs[stuff->data](client);

+ +        result = dispatchFuncs[stuff->data](client);

+      } else {

+ -        return dispatch_GLXSingle(client);

+ +        result = dispatch_GLXSingle(client);

+      }

+ +

+ +    GlxSetRequestClient(NULL);

+ +

+ +    return result;

+  }

+ diff --git a/glx/vndserver.h b/glx/vndserver.h

+ index 78246d212cea42f923808852159c973e3b64318d..613fef0fe221b5a1fbc8d35b562edb167b772196 100644

+ --- a/glx/vndserver.h

+ +++ b/glx/vndserver.h

+ @@ -95,6 +95,13 @@ Bool GlxAddXIDMap(XID id, GlxServerVendor *vendor);

+  GlxServerVendor * GlxGetXIDMap(XID id);

+  void GlxRemoveXIDMap(XID id);

+  

+ +/**

+ + * Records the client that sent the current request. This is needed in

+ + * GlxGetXIDMap to know which client's (screen -> vendor) mapping to use for a

+ + * regular X window.

+ + */

+ +void GlxSetRequestClient(ClientPtr client);

+ +

+  GlxContextTagInfo *GlxAllocContextTag(ClientPtr client, GlxServerVendor *vendor);

+  GlxContextTagInfo *GlxLookupContextTag(ClientPtr client, GLXContextTag tag);

+  void GlxFreeContextTag(GlxContextTagInfo *tagInfo);

+ diff --git a/glx/vndservermapping.c b/glx/vndservermapping.c

+ index 778656bb6eadcad43afe0e985c14a67eb44402a4..4efab8b81d1eadd84ada3de078e17d7ad51661d6 100644

+ --- a/glx/vndservermapping.c

+ +++ b/glx/vndservermapping.c

+ @@ -33,6 +33,13 @@

+  

+  #include "vndservervendor.h"

+  

+ +static ClientPtr requestClient = NULL;

+ +

+ +void GlxSetRequestClient(ClientPtr client)

+ +{

+ +    requestClient = client;

+ +}

+ +

+  static GlxServerVendor *LookupXIDMapResource(XID id)

+  {

+      void *ptr = NULL;

+ @@ -59,10 +66,7 @@ GlxServerVendor *GlxGetXIDMap(XID id)

+                                           DixGetAttrAccess);

+          if (rv == Success && ptr != NULL) {

+              DrawablePtr draw = (DrawablePtr) ptr;

+ -            GlxScreenPriv *screenPriv = GlxGetScreen(draw->pScreen);

+ -            if (screenPriv != NULL) {

+ -                vendor = screenPriv->vendor;

+ -            }

+ +            vendor = GlxGetVendorForScreen(requestClient, draw->pScreen);

+          }

+      }

+      return vendor;

file modified
+17 -1

@@ -46,7 +46,7 @@ 

  Summary:   X.Org X11 X server

  Name:      xorg-x11-server

  Version:   1.20.5

- Release:   6%{?gitdate:.%{gitdate}}%{?dist}

+ Release:   7%{?gitdate:.%{gitdate}}%{?dist}

  URL:       http://www.x.org

  License:   MIT

  

@@ -120,6 +120,19 @@ 

  # https://gitlab.freedesktop.org/xorg/xserver/issues/840

  Patch31: 0001-compiler.h-Do-not-include-sys-io.h-on-ARM-with-glibc.patch

  

+ # NVIDIA PRIME Render Offload

+ # https://download.nvidia.com/XFree86/Linux-x86_64/435.17/README/primerenderoffload.html

+ # https://gitlab.freedesktop.org/xorg/xserver/commit/7f962c70

+ Patch32: xsync_Add_resource_inside_of_SyncCreate_export_SyncCreate.diff

+ # https://gitlab.freedesktop.org/xorg/xserver/commit/37a36a6b

+ Patch33: GLX_Add_a_per-client_vendor_mapping.diff

+ # https://gitlab.freedesktop.org/xorg/xserver/commit/8b67ec7c

+ Patch34: GLX_Use_the_sending_client_for_looking_up_XIDs.diff

+ # https://gitlab.freedesktop.org/xorg/xserver/commit/56c0a71f

+ Patch35: GLX_Add_a_function_to_change_a_clients_vendor_list.diff

+ # https://gitlab.freedesktop.org/xorg/xserver/commit/b4231d69

+ Patch36: GLX_Set_GlxServerExports_major_minor_Version.diff

+ 

  BuildRequires: systemtap-sdt-devel

  BuildRequires: git

  BuildRequires: automake autoconf libtool pkgconfig

@@ -544,6 +557,9 @@ 

  

  

  %changelog

+ * Thu Aug 22 2019 Elia Devito <eliadevito@gmail.com> - 1.20.5-7

+ - Backport patch to support NVIDIA PRIME Render Offload

+ 

  * Sat Jul 27 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.20.5-6

  - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild

  

@@ -0,0 +1,205 @@ 

+ diff --git a/Xext/sync.c b/Xext/sync.c

+ index 8f22a865bb35067104c73838950e7a5bd696803a..fd2ceb0423ec4c25a0341f2f570383329f6a96e4 100644

+ --- a/Xext/sync.c

+ +++ b/Xext/sync.c

+ @@ -881,18 +881,21 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm * pAlarm, Mask mask,

+      return Success;

+  }

+  

+ -static SyncObject *

+ +SyncObject *

+  SyncCreate(ClientPtr client, XID id, unsigned char type)

+  {

+      SyncObject *pSync;

+ +    RESTYPE resType;

+  

+      switch (type) {

+      case SYNC_COUNTER:

+          pSync = malloc(sizeof(SyncCounter));

+ +        resType = RTCounter;

+          break;

+      case SYNC_FENCE:

+          pSync = (SyncObject *) dixAllocateObjectWithPrivates(SyncFence,

+                                                               PRIVATE_SYNC_FENCE);

+ +        resType = RTFence;

+          break;

+      default:

+          return NULL;

+ @@ -901,6 +904,11 @@ SyncCreate(ClientPtr client, XID id, unsigned char type)

+      if (!pSync)

+          return NULL;

+  

+ +    pSync->initialized = FALSE;

+ +

+ +    if (!AddResource(id, resType, (void *) pSync))

+ +        return NULL;

+ +

+      pSync->client = client;

+      pSync->id = id;

+      pSync->pTriglist = NULL;

+ @@ -923,13 +931,10 @@ SyncCreateFenceFromFD(ClientPtr client, DrawablePtr pDraw, XID id, int fd, BOOL

+  

+      status = miSyncInitFenceFromFD(pDraw, pFence, fd, initially_triggered);

+      if (status != Success) {

+ -        dixFreeObjectWithPrivates(pFence, PRIVATE_SYNC_FENCE);

+ +        FreeResource(pFence->sync.id, RT_NONE);

+          return status;

+      }

+  

+ -    if (!AddResource(id, RTFence, (void *) pFence))

+ -        return BadAlloc;

+ -

+      return Success;

+  #else

+      return BadImplementation;

+ @@ -957,8 +962,7 @@ SyncCreateCounter(ClientPtr client, XSyncCounter id, int64_t initialvalue)

+      pCounter->value = initialvalue;

+      pCounter->pSysCounterInfo = NULL;

+  

+ -    if (!AddResource(id, RTCounter, (void *) pCounter))

+ -        return NULL;

+ +    pCounter->sync.initialized = TRUE;

+  

+      return pCounter;

+  }

+ @@ -1137,21 +1141,26 @@ static int

+  FreeCounter(void *env, XID id)

+  {

+      SyncCounter *pCounter = (SyncCounter *) env;

+ -    SyncTriggerList *ptl, *pnext;

+  

+      pCounter->sync.beingDestroyed = TRUE;

+ -    /* tell all the counter's triggers that the counter has been destroyed */

+ -    for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) {

+ -        (*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger);

+ -        pnext = ptl->next;

+ -        free(ptl);              /* destroy the trigger list as we go */

+ -    }

+ -    if (IsSystemCounter(pCounter)) {

+ -        xorg_list_del(&pCounter->pSysCounterInfo->entry);

+ -        free(pCounter->pSysCounterInfo->name);

+ -        free(pCounter->pSysCounterInfo->private);

+ -        free(pCounter->pSysCounterInfo);

+ +

+ +    if (pCounter->sync.initialized) {

+ +        SyncTriggerList *ptl, *pnext;

+ +

+ +        /* tell all the counter's triggers that counter has been destroyed */

+ +        for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) {

+ +            (*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger);

+ +            pnext = ptl->next;

+ +            free(ptl); /* destroy the trigger list as we go */

+ +        }

+ +        if (IsSystemCounter(pCounter)) {

+ +            xorg_list_del(&pCounter->pSysCounterInfo->entry);

+ +            free(pCounter->pSysCounterInfo->name);

+ +            free(pCounter->pSysCounterInfo->private);

+ +            free(pCounter->pSysCounterInfo);

+ +        }

+      }

+ +

+      free(pCounter);

+      return Success;

+  }

+ @@ -1889,9 +1898,6 @@ ProcSyncCreateFence(ClientPtr client)

+  

+      miSyncInitFence(pDraw->pScreen, pFence, stuff->initially_triggered);

+  

+ -    if (!AddResource(stuff->fid, RTFence, (void *) pFence))

+ -        return BadAlloc;

+ -

+      return Success;

+  }

+  

+ diff --git a/Xext/syncsdk.h b/Xext/syncsdk.h

+ index f1b99d010b1ac82ecd654716494c9bb4f8bcba05..c88285cb130759d3d8b420083346baecb7155871 100644

+ --- a/Xext/syncsdk.h

+ +++ b/Xext/syncsdk.h

+ @@ -29,6 +29,9 @@

+  extern _X_EXPORT int

+   SyncVerifyFence(SyncFence ** ppFence, XID fid, ClientPtr client, Mask mode);

+  

+ +extern _X_EXPORT SyncObject*

+ + SyncCreate(ClientPtr client, XID id, unsigned char type);

+ +

+  #define VERIFY_SYNC_FENCE(pFence, fid, client, mode)			\

+      do {								\

+  	int rc;								\

+ diff --git a/miext/sync/misync.c b/miext/sync/misync.c

+ index 490fa0b1723a5892d631a8415cb82c0f3dc7f7af..0931803f6c94f1c5266494e86868fe06d2538a0e 100644

+ --- a/miext/sync/misync.c

+ +++ b/miext/sync/misync.c

+ @@ -101,24 +101,29 @@ miSyncInitFence(ScreenPtr pScreen, SyncFence * pFence, Bool initially_triggered)

+      pFence->funcs = miSyncFenceFuncs;

+  

+      pScreenPriv->funcs.CreateFence(pScreen, pFence, initially_triggered);

+ +

+ +    pFence->sync.initialized = TRUE;

+  }

+  

+  void

+  miSyncDestroyFence(SyncFence * pFence)

+  {

+ -    ScreenPtr pScreen = pFence->pScreen;

+ -    SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen);

+ -    SyncTriggerList *ptl, *pNext;

+ -

+      pFence->sync.beingDestroyed = TRUE;

+ -    /* tell all the fence's triggers that the counter has been destroyed */

+ -    for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext) {

+ -        (*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger);

+ -        pNext = ptl->next;

+ -        free(ptl);              /* destroy the trigger list as we go */

+ -    }

+  

+ -    pScreenPriv->funcs.DestroyFence(pScreen, pFence);

+ +    if (pFence->sync.initialized) {

+ +        ScreenPtr pScreen = pFence->pScreen;

+ +        SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen);

+ +        SyncTriggerList *ptl, *pNext;

+ +

+ +        /* tell all the fence's triggers that the counter has been destroyed */

+ +        for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext) {

+ +            (*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger);

+ +            pNext = ptl->next;

+ +            free(ptl); /* destroy the trigger list as we go */

+ +        }

+ +

+ +        pScreenPriv->funcs.DestroyFence(pScreen, pFence);

+ +    }

+  

+      dixFreeObjectWithPrivates(pFence, PRIVATE_SYNC_FENCE);

+  }

+ diff --git a/miext/sync/misync.h b/miext/sync/misync.h

+ index dc78c5fdb3b2b93e8e316e1e5f19185c369512b9..f7082d5ea400c28d39de2752055d43bbd5584b23 100644

+ --- a/miext/sync/misync.h

+ +++ b/miext/sync/misync.h

+ @@ -28,6 +28,7 @@

+  #ifndef _MISYNC_H_

+  #define _MISYNC_H_

+  

+ +typedef struct _SyncObject SyncObject;

+  typedef struct _SyncFence SyncFence;

+  typedef struct _SyncTrigger SyncTrigger;

+  

+ diff --git a/miext/sync/misyncstr.h b/miext/sync/misyncstr.h

+ index 2eab2aa576b4b99860104e7faeea13db9c628834..2a6e84a9649d014ffab41cc22f4b96ad10a3e9fb 100644

+ --- a/miext/sync/misyncstr.h

+ +++ b/miext/sync/misyncstr.h

+ @@ -38,13 +38,14 @@

+  #define SYNC_COUNTER		0

+  #define SYNC_FENCE		1

+  

+ -typedef struct _SyncObject {

+ +struct _SyncObject {

+      ClientPtr client;           /* Owning client. 0 for system counters */

+      struct _SyncTriggerList *pTriglist; /* list of triggers */

+      XID id;                     /* resource ID */

+      unsigned char type;         /* SYNC_* */

+ +    Bool initialized;           /* FALSE if created but not initialized */

+      Bool beingDestroyed;        /* in process of going away */

+ -} SyncObject;

+ +};

+  

+  typedef struct _SyncCounter {

+      SyncObject sync;            /* Common sync object data */