Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/Makefile.kmk
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/Makefile.kmk	(revision 76790)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/Makefile.kmk	(revision 76884)
@@ -180,4 +180,6 @@
   	wddm/gallium/SvgaFifo.cpp \
   	wddm/gallium/SvgaHw.cpp \
+  	wddm/gallium/VBoxMPGaFence.cpp \
+  	wddm/gallium/VBoxMPGaUtils.cpp \
   	wddm/gallium/VBoxMPGaWddm.cpp
  endif
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaExt.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaExt.h	(revision 76884)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaExt.h	(revision 76884)
@@ -0,0 +1,109 @@
+/* $Id$ */
+/** @file
+ * VirtualBox Windows Guest Mesa3D - Gallium driver miscellaneous helpers and common includes.
+ */
+
+/*
+ * Copyright (C) 2017-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef GA_INCLUDED_SRC_WINNT_Graphics_Video_mp_wddm_gallium_VBoxMPGaExt_h
+#define GA_INCLUDED_SRC_WINNT_Graphics_Video_mp_wddm_gallium_VBoxMPGaExt_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "Svga.h"
+
+#define VBOXWDDM_GA_MAX_FENCE_OBJECTS 4096
+
+/* Gallium related device extension. */
+typedef struct VBOXWDDM_EXT_GA
+{
+    union
+    {
+        /* Pointers to HW specific structs. */
+        PVBOXWDDM_EXT_VMSVGA pSvga;
+        void *pv;
+    } hw;
+
+    volatile uint32_t u32LastSubmittedFenceId; /* Updated in GaDxgkSubmitCommand. */
+    volatile uint32_t u32LastCompletedFenceId; /* Updated in ISR. */
+    volatile uint32_t u32PreemptionFenceId; /* Updated in GaDxgkDdiPreemptCommand. */
+    volatile uint32_t u32LastCompletedSeqNo; /* Updated in DPC routine. */
+
+    struct
+    {
+        /* Generation of SeqNo's. */
+        volatile uint32_t u32SeqNoSource;
+        /* Lock for accessing fence objects. Spin lock because it is used in DPC routine too. */
+        KIRQL OldIrql;
+        KSPIN_LOCK SpinLock;
+        /* List of all fence objects. */
+        RTLISTANCHOR list;
+        /** Bitmap of used fence handles. Bit 0 - fence handle 0, etc. */
+        uint32_t au32HandleBits[(VBOXWDDM_GA_MAX_FENCE_OBJECTS + 31) / 32];
+    } fenceObjects;
+} VBOXWDDM_EXT_GA;
+
+/* Fence object (FO). */
+typedef struct GAFENCEOBJECT
+{
+    volatile uint32_t cRefs;    /* By UM driver, by waiter, during submission. */
+    uint32_t u32FenceHandle;    /* Unique identifier, used for communications with UM driver. */
+    uint32_t u32FenceState;     /* GAFENCE_STATE_* */
+    uint32_t fu32FenceFlags;    /* GAFENCE_F_* */
+    uint32_t u32SubmissionFenceId; /* DXGK fence id. */
+    uint32_t u32SeqNo;          /* Gallium Sequence Number, generated by the miniport. */
+    PVBOXWDDM_DEVICE pDevice;   /* Device the fence is associated with. */
+    KEVENT event;               /* Allows to wait for the fence completion. */
+    RTLISTNODE node;            /* For the per adapter list of fence objects. */
+    uint64_t u64SubmittedTS;    /* Nanoseconds timestamp when the corresponding buffer was submitted. */
+} GAFENCEOBJECT;
+
+#define GAFENCE_STATE_IDLE      0
+#define GAFENCE_STATE_SUBMITTED 1
+#define GAFENCE_STATE_SIGNALED  2
+
+#define GAFENCE_F_WAITED        0x1 /* KEVENT is initialized and there is(are) waiter(s). */
+
+NTSTATUS GaFenceCreate(PVBOXWDDM_EXT_GA pGaDevExt,
+                       PVBOXWDDM_DEVICE pDevice,
+                       uint32_t *pu32FenceHandle);
+NTSTATUS GaFenceQuery(PVBOXWDDM_EXT_GA pGaDevExt,
+                      uint32_t u32FenceHandle,
+                      uint32_t *pu32SubmittedSeqNo,
+                      uint32_t *pu32ProcessedSeqNo,
+                      uint32_t *pu32FenceStatus);
+NTSTATUS GaFenceWait(PVBOXWDDM_EXT_GA pGaDevExt,
+                     uint32_t u32FenceHandle,
+                     uint32_t u32TimeoutUS);
+NTSTATUS GaFenceUnref(PVBOXWDDM_EXT_GA pGaDevExt,
+                      uint32_t u32FenceHandle);
+
+DECLINLINE(void) gaFenceObjectsLock(VBOXWDDM_EXT_GA *pGaDevExt)
+{
+    KeAcquireSpinLock(&pGaDevExt->fenceObjects.SpinLock, &pGaDevExt->fenceObjects.OldIrql);
+}
+
+DECLINLINE(void) gaFenceObjectsUnlock(VBOXWDDM_EXT_GA *pGaDevExt)
+{
+    KeReleaseSpinLock(&pGaDevExt->fenceObjects.SpinLock, pGaDevExt->fenceObjects.OldIrql);
+}
+
+void GaFenceObjectsDestroy(VBOXWDDM_EXT_GA *pGaDevExt,
+                           PVBOXWDDM_DEVICE pDevice);
+GAFENCEOBJECT *GaFenceLookup(VBOXWDDM_EXT_GA *pGaDevExt,
+                             uint32_t u32FenceHandle);
+void GaFenceUnrefLocked(VBOXWDDM_EXT_GA *pGaDevExt,
+                        GAFENCEOBJECT *pFO);
+
+#endif /* !GA_INCLUDED_SRC_WINNT_Graphics_Video_mp_wddm_gallium_VBoxMPGaExt_h */
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaFence.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaFence.cpp	(revision 76884)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaFence.cpp	(revision 76884)
@@ -0,0 +1,275 @@
+/* $Id$ */
+/** @file
+ * VirtualBox Windows Guest Mesa3D - Gallium driver interface for WDDM kernel mode driver.
+ */
+
+/*
+ * Copyright (C) 2016-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "VBoxMPGaWddm.h"
+#include "../VBoxMPVidPn.h"
+#include "VBoxMPGaExt.h"
+
+#include "Svga.h"
+#include "SvgaFifo.h"
+#include "SvgaCmd.h"
+#include "SvgaHw.h"
+
+#include <iprt/time.h>
+
+void GaFenceObjectsDestroy(VBOXWDDM_EXT_GA *pGaDevExt,
+                           PVBOXWDDM_DEVICE pDevice)
+{
+    RTLISTANCHOR list;
+    RTListInit(&list);
+
+    gaFenceObjectsLock(pGaDevExt);
+
+    GAFENCEOBJECT *pIter, *pNext;
+    RTListForEachSafe(&pGaDevExt->fenceObjects.list, pIter, pNext, GAFENCEOBJECT, node)
+    {
+        if (   pDevice == NULL
+            || pIter->pDevice == pDevice)
+        {
+            /* Remove from list, add to the local list. */
+            RTListNodeRemove(&pIter->node);
+            GaIdFree(pGaDevExt->fenceObjects.au32HandleBits, sizeof(pGaDevExt->fenceObjects.au32HandleBits),
+                     VBOXWDDM_GA_MAX_FENCE_OBJECTS, pIter->u32FenceHandle);
+            RTListAppend(&list, &pIter->node);
+        }
+    }
+
+    gaFenceObjectsUnlock(pGaDevExt);
+
+    /* Deallocate list. */
+    RTListForEachSafe(&list, pIter, pNext, GAFENCEOBJECT, node)
+    {
+        GALOG(("Deallocate u32FenceHandle = %d for %p\n", pIter->u32FenceHandle, pDevice));
+        RTListNodeRemove(&pIter->node);
+        GaMemFree(pIter);
+    }
+}
+
+static void gaFenceDelete(VBOXWDDM_EXT_GA *pGaDevExt, GAFENCEOBJECT *pFO)
+{
+    GALOG(("u32FenceHandle = %d, pFO %p\n", pFO->u32FenceHandle, pFO));
+
+    gaFenceObjectsLock(pGaDevExt);
+
+    RTListNodeRemove(&pFO->node);
+    GaIdFree(pGaDevExt->fenceObjects.au32HandleBits, sizeof(pGaDevExt->fenceObjects.au32HandleBits),
+             VBOXWDDM_GA_MAX_FENCE_OBJECTS, pFO->u32FenceHandle);
+
+    gaFenceObjectsUnlock(pGaDevExt);
+
+    /// @todo Pool of fence objects to avoid memory allocations.
+    GaMemFree(pFO);
+}
+
+static void gaFenceDeleteLocked(VBOXWDDM_EXT_GA *pGaDevExt, GAFENCEOBJECT *pFO)
+{
+    GALOG(("u32FenceHandle = %d, pFO %p\n", pFO->u32FenceHandle, pFO));
+
+    RTListNodeRemove(&pFO->node);
+    GaIdFree(pGaDevExt->fenceObjects.au32HandleBits, sizeof(pGaDevExt->fenceObjects.au32HandleBits),
+             VBOXWDDM_GA_MAX_FENCE_OBJECTS, pFO->u32FenceHandle);
+
+    /// @todo Pool of fence objects to avoid memory allocations.
+    GaMemFree(pFO);
+}
+
+DECLINLINE(void) gaFenceRef(GAFENCEOBJECT *pFO)
+{
+    ASMAtomicIncU32(&pFO->cRefs);
+}
+
+DECLINLINE(void) gaFenceUnref(VBOXWDDM_EXT_GA *pGaDevExt, GAFENCEOBJECT *pFO)
+{
+    uint32_t c = ASMAtomicDecU32(&pFO->cRefs);
+    Assert(c < UINT32_MAX / 2);
+    if (c == 0)
+    {
+        gaFenceDelete(pGaDevExt, pFO);
+    }
+}
+
+void GaFenceUnrefLocked(VBOXWDDM_EXT_GA *pGaDevExt, GAFENCEOBJECT *pFO)
+{
+    uint32_t c = ASMAtomicDecU32(&pFO->cRefs);
+    Assert(c < UINT32_MAX / 2);
+    if (c == 0)
+    {
+        gaFenceDeleteLocked(pGaDevExt, pFO);
+    }
+}
+
+GAFENCEOBJECT *GaFenceLookup(VBOXWDDM_EXT_GA *pGaDevExt,
+                             uint32_t u32FenceHandle)
+{
+    /* Must be called under the fence object lock. */
+    GAFENCEOBJECT *pIter;
+    RTListForEach(&pGaDevExt->fenceObjects.list, pIter, GAFENCEOBJECT, node)
+    {
+        if (pIter->u32FenceHandle == u32FenceHandle)
+        {
+            gaFenceRef(pIter);
+            return pIter;
+        }
+    }
+    return NULL;
+}
+
+/*
+ * Fence objects.
+ */
+
+NTSTATUS GaFenceCreate(PVBOXWDDM_EXT_GA pGaDevExt,
+                       PVBOXWDDM_DEVICE pDevice,
+                       uint32_t *pu32FenceHandle)
+{
+    GAFENCEOBJECT *pFO = (GAFENCEOBJECT *)GaMemAllocZero(sizeof(GAFENCEOBJECT));
+    if (!pFO)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    /* pFO->cRefs             = 0; */
+    pFO->u32FenceState      = GAFENCE_STATE_IDLE;
+    /* pFO->fu32FenceFlags    = 0; */
+    /* pFO->u32SubmissionFenceId    = 0; */
+    pFO->u32SeqNo           = ASMAtomicIncU32(&pGaDevExt->fenceObjects.u32SeqNoSource);
+    pFO->pDevice            = pDevice;
+    /* RT_ZERO(pFO->event); */
+
+    gaFenceObjectsLock(pGaDevExt);
+
+    NTSTATUS Status = GaIdAlloc(pGaDevExt->fenceObjects.au32HandleBits, sizeof(pGaDevExt->fenceObjects.au32HandleBits),
+                                VBOXWDDM_GA_MAX_FENCE_OBJECTS, &pFO->u32FenceHandle);
+    if (NT_SUCCESS(Status))
+    {
+        RTListAppend(&pGaDevExt->fenceObjects.list, &pFO->node);
+        gaFenceRef(pFO);
+
+        gaFenceObjectsUnlock(pGaDevExt);
+
+        *pu32FenceHandle = pFO->u32FenceHandle;
+
+        GALOG(("u32FenceHandle = %d\n", pFO->u32FenceHandle));
+        return STATUS_SUCCESS;
+    }
+
+    /* Failure */
+    gaFenceObjectsUnlock(pGaDevExt);
+    GaMemFree(pFO);
+    return Status;
+}
+
+NTSTATUS GaFenceQuery(PVBOXWDDM_EXT_GA pGaDevExt,
+                      uint32_t u32FenceHandle,
+                      uint32_t *pu32SubmittedSeqNo,
+                      uint32_t *pu32ProcessedSeqNo,
+                      uint32_t *pu32FenceStatus)
+{
+    gaFenceObjectsLock(pGaDevExt);
+
+    GAFENCEOBJECT *pFO = GaFenceLookup(pGaDevExt, u32FenceHandle);
+
+    gaFenceObjectsUnlock(pGaDevExt);
+
+    GALOG(("u32FenceHandle = %d, pFO %p\n", u32FenceHandle, pFO));
+    if (pFO)
+    {
+        *pu32SubmittedSeqNo = pFO->u32SeqNo;
+        switch (pFO->u32FenceState)
+        {
+            default:
+                AssertFailed();
+                RT_FALL_THRU();
+            case GAFENCE_STATE_IDLE:      *pu32FenceStatus = GA_FENCE_STATUS_IDLE;      break;
+            case GAFENCE_STATE_SUBMITTED: *pu32FenceStatus = GA_FENCE_STATUS_SUBMITTED; break;
+            case GAFENCE_STATE_SIGNALED:  *pu32FenceStatus = GA_FENCE_STATUS_SIGNALED;  break;
+        }
+
+        gaFenceUnref(pGaDevExt, pFO);
+    }
+    else
+    {
+        *pu32SubmittedSeqNo = 0;
+        *pu32FenceStatus = GA_FENCE_STATUS_NULL;
+    }
+    *pu32ProcessedSeqNo = ASMAtomicReadU32(&pGaDevExt->u32LastCompletedSeqNo);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS GaFenceWait(PVBOXWDDM_EXT_GA pGaDevExt,
+                     uint32_t u32FenceHandle,
+                     uint32_t u32TimeoutUS)
+{
+    gaFenceObjectsLock(pGaDevExt);
+
+    GAFENCEOBJECT *pFO = GaFenceLookup(pGaDevExt, u32FenceHandle);
+    AssertReturnStmt(pFO, gaFenceObjectsUnlock(pGaDevExt), STATUS_INVALID_PARAMETER);
+
+    if (pFO->u32FenceState == GAFENCE_STATE_SIGNALED)
+    {
+        /* Already signaled. */
+        gaFenceObjectsUnlock(pGaDevExt);
+        gaFenceUnref(pGaDevExt, pFO);
+        return STATUS_SUCCESS;
+    }
+
+    /* Wait */
+    if (!RT_BOOL(pFO->fu32FenceFlags & GAFENCE_F_WAITED))
+    {
+        KeInitializeEvent(&pFO->event, NotificationEvent, FALSE);
+        pFO->fu32FenceFlags |= GAFENCE_F_WAITED;
+    }
+
+    gaFenceObjectsUnlock(pGaDevExt);
+
+    GALOG(("u32FenceHandle = %d, pFO %p\n", u32FenceHandle, pFO));
+
+    LARGE_INTEGER Timeout;
+    Timeout.QuadPart = u32TimeoutUS;
+    Timeout.QuadPart *= -10LL; /* Microseconds to relative 100-nanoseconds units. */
+    NTSTATUS Status = KeWaitForSingleObject(&pFO->event, UserRequest, KernelMode, TRUE, &Timeout);
+
+    gaFenceUnref(pGaDevExt, pFO);
+
+    return Status;
+}
+
+NTSTATUS GaFenceUnref(PVBOXWDDM_EXT_GA pGaDevExt,
+                      uint32_t u32FenceHandle)
+{
+    gaFenceObjectsLock(pGaDevExt);
+
+    GAFENCEOBJECT *pFO = GaFenceLookup(pGaDevExt, u32FenceHandle);
+    AssertReturnStmt(pFO, gaFenceObjectsUnlock(pGaDevExt), STATUS_INVALID_PARAMETER);
+
+    if (RT_BOOL(pFO->fu32FenceFlags & GAFENCE_F_WAITED))
+    {
+        KeSetEvent(&pFO->event, 0, FALSE);
+        pFO->fu32FenceFlags &= ~GAFENCE_F_WAITED;
+    }
+
+    gaFenceObjectsUnlock(pGaDevExt);
+
+    GALOG(("u32FenceHandle = %d, pFO %p\n", u32FenceHandle, pFO));
+
+    /* Undo GaFenceLookup ref. */
+    gaFenceUnref(pGaDevExt, pFO);
+
+    /* Undo the GaFenceCreate ref. */
+    gaFenceUnref(pGaDevExt, pFO);
+
+    return STATUS_SUCCESS;
+}
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaUtils.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaUtils.cpp	(revision 76884)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaUtils.cpp	(revision 76884)
@@ -0,0 +1,82 @@
+/* $Id$ */
+/** @file
+ * VirtualBox Windows Guest Mesa3D - Gallium driver interface for WDDM kernel mode driver.
+ */
+
+/*
+ * Copyright (C) 2016-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "VBoxMPGaUtils.h"
+
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+
+volatile uint32_t g_fu32GaLogControl =
+#ifdef DEBUG
+    1 /* Enable LogRels */
+#else
+    0 /* Disable LogRels, but they can be enabled if necessary. */
+#endif
+;
+
+/*
+ * Helpers.
+ */
+
+void *GaMemAlloc(uint32_t cbSize)
+{
+    return ExAllocatePoolWithTag(NonPagedPool, cbSize, 'AGBV');
+}
+
+void *GaMemAllocZero(uint32_t cbSize)
+{
+    void *pvMem = GaMemAlloc(cbSize);
+    if (pvMem)
+        memset(pvMem, 0, cbSize);
+    return pvMem;
+}
+
+void GaMemFree(void *pvMem)
+{
+    ExFreePool(pvMem);
+}
+
+NTSTATUS GaIdAlloc(uint32_t *pu32Bits,
+                   uint32_t cbBits,
+                   uint32_t u32Limit,
+                   uint32_t *pu32Id)
+{
+    /* Find the first zero bit. */
+    const int32_t i32Id = ASMBitFirstClear(pu32Bits, cbBits * 8);
+    if (0 <= i32Id && i32Id < (int32_t)u32Limit)
+    {
+        ASMBitSet(pu32Bits, i32Id);
+        *pu32Id = (uint32_t)i32Id;
+        return STATUS_SUCCESS;
+    }
+
+    return STATUS_INSUFFICIENT_RESOURCES;
+}
+
+NTSTATUS GaIdFree(uint32_t *pu32Bits,
+                  uint32_t cbBits,
+                  uint32_t u32Limit,
+                  uint32_t u32Id)
+{
+    AssertReturn(u32Limit <= cbBits * 8, STATUS_INVALID_PARAMETER);
+    AssertReturn(u32Id < u32Limit, STATUS_INVALID_PARAMETER);
+
+    /* Clear the corresponding bit. */
+    ASMBitClear(pu32Bits, (int32_t)u32Id);
+
+    return STATUS_SUCCESS;
+}
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.cpp	(revision 76790)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.cpp	(revision 76884)
@@ -18,4 +18,5 @@
 #include "VBoxMPGaWddm.h"
 #include "../VBoxMPVidPn.h"
+#include "VBoxMPGaExt.h"
 
 #include "Svga.h"
@@ -26,233 +27,4 @@
 #include <iprt/time.h>
 
-volatile uint32_t g_fu32GaLogControl =
-#ifdef DEBUG
-    1 /* Enable LogRels */
-#else
-    0 /* Disable LogRels, but they can be enabled if necessary. */
-#endif
-;
-
-
-#define VBOXWDDM_GA_MAX_FENCE_OBJECTS 4096
-
-/* Gallium related device extension. */
-typedef struct VBOXWDDM_EXT_GA
-{
-    union
-    {
-        /* Pointers to HW specific structs. */
-        PVBOXWDDM_EXT_VMSVGA pSvga;
-        void *pv;
-    } hw;
-
-    volatile uint32_t u32LastSubmittedFenceId; /* Updated in GaDxgkSubmitCommand. */
-    volatile uint32_t u32LastCompletedFenceId; /* Updated in ISR. */
-    volatile uint32_t u32PreemptionFenceId; /* Updated in GaDxgkDdiPreemptCommand. */
-    volatile uint32_t u32LastCompletedSeqNo; /* Updated in DPC routine. */
-
-    struct
-    {
-        /* Generation of SeqNo's. */
-        volatile uint32_t u32SeqNoSource;
-        /* Lock for accessing fence objects. Spin lock because it is used in DPC routine too. */
-        KIRQL OldIrql;
-        KSPIN_LOCK SpinLock;
-        /* List of all fence objects. */
-        RTLISTANCHOR list;
-        /** Bitmap of used fence handles. Bit 0 - fence handle 0, etc. */
-        uint32_t au32HandleBits[(VBOXWDDM_GA_MAX_FENCE_OBJECTS + 31) / 32];
-    } fenceObjects;
-} VBOXWDDM_EXT_GA;
-
-/* Fence object (FO). */
-typedef struct GAFENCEOBJECT
-{
-    volatile uint32_t cRefs;    /* By UM driver, by waiter, during submission. */
-    uint32_t u32FenceHandle;    /* Unique identifier, used for communications with UM driver. */
-    uint32_t u32FenceState;     /* GAFENCE_STATE_* */
-    uint32_t fu32FenceFlags;    /* GAFENCE_F_* */
-    uint32_t u32SubmissionFenceId; /* DXGK fence id. */
-    uint32_t u32SeqNo;          /* Gallium Sequence Number, generated by the miniport. */
-    PVBOXWDDM_DEVICE pDevice;   /* Device the fence is associated with. */
-    KEVENT event;               /* Allows to wait for the fence completion. */
-    RTLISTNODE node;            /* For the per adapter list of fence objects. */
-    uint64_t u64SubmittedTS;    /* Nanoseconds timestamp when the corresponding buffer was submitted. */
-} GAFENCEOBJECT;
-
-#define GAFENCE_STATE_IDLE      0
-#define GAFENCE_STATE_SUBMITTED 1
-#define GAFENCE_STATE_SIGNALED  2
-
-#define GAFENCE_F_WAITED        0x1 /* KEVENT is initialized and there is(are) waiter(s). */
-
-
-/*
- * Helpers.
- */
-
-void *GaMemAlloc(uint32_t cbSize)
-{
-    return ExAllocatePoolWithTag(NonPagedPool, cbSize, 'AGBV');
-}
-
-void *GaMemAllocZero(uint32_t cbSize)
-{
-    void *pvMem = GaMemAlloc(cbSize);
-    if (pvMem)
-        memset(pvMem, 0, cbSize);
-    return pvMem;
-}
-
-void GaMemFree(void *pvMem)
-{
-    ExFreePool(pvMem);
-}
-
-NTSTATUS GaIdAlloc(uint32_t *pu32Bits,
-                   uint32_t cbBits,
-                   uint32_t u32Limit,
-                   uint32_t *pu32Id)
-{
-    /* Find the first zero bit. */
-    const int32_t i32Id = ASMBitFirstClear(pu32Bits, cbBits * 8);
-    if (0 <= i32Id && i32Id < (int32_t)u32Limit)
-    {
-        ASMBitSet(pu32Bits, i32Id);
-        *pu32Id = (uint32_t)i32Id;
-        return STATUS_SUCCESS;
-    }
-
-    return STATUS_INSUFFICIENT_RESOURCES;
-}
-
-NTSTATUS GaIdFree(uint32_t *pu32Bits,
-                  uint32_t cbBits,
-                  uint32_t u32Limit,
-                  uint32_t u32Id)
-{
-    AssertReturn(u32Limit <= cbBits * 8, STATUS_INVALID_PARAMETER);
-    AssertReturn(u32Id < u32Limit, STATUS_INVALID_PARAMETER);
-
-    /* Clear the corresponding bit. */
-    ASMBitClear(pu32Bits, (int32_t)u32Id);
-
-    return STATUS_SUCCESS;
-}
-
-
-DECLINLINE(void) gaFenceObjectsLock(VBOXWDDM_EXT_GA *pGaDevExt)
-{
-    KeAcquireSpinLock(&pGaDevExt->fenceObjects.SpinLock, &pGaDevExt->fenceObjects.OldIrql);
-}
-
-DECLINLINE(void) gaFenceObjectsUnlock(VBOXWDDM_EXT_GA *pGaDevExt)
-{
-    KeReleaseSpinLock(&pGaDevExt->fenceObjects.SpinLock, pGaDevExt->fenceObjects.OldIrql);
-}
-
-static void gaFenceObjectsDestroy(VBOXWDDM_EXT_GA *pGaDevExt,
-                                  PVBOXWDDM_DEVICE pDevice)
-{
-    RTLISTANCHOR list;
-    RTListInit(&list);
-
-    gaFenceObjectsLock(pGaDevExt);
-
-    GAFENCEOBJECT *pIter, *pNext;
-    RTListForEachSafe(&pGaDevExt->fenceObjects.list, pIter, pNext, GAFENCEOBJECT, node)
-    {
-        if (   pDevice == NULL
-            || pIter->pDevice == pDevice)
-        {
-            /* Remove from list, add to the local list. */
-            RTListNodeRemove(&pIter->node);
-            GaIdFree(pGaDevExt->fenceObjects.au32HandleBits, sizeof(pGaDevExt->fenceObjects.au32HandleBits),
-                     VBOXWDDM_GA_MAX_FENCE_OBJECTS, pIter->u32FenceHandle);
-            RTListAppend(&list, &pIter->node);
-        }
-    }
-
-    gaFenceObjectsUnlock(pGaDevExt);
-
-    /* Deallocate list. */
-    RTListForEachSafe(&list, pIter, pNext, GAFENCEOBJECT, node)
-    {
-        GALOG(("Deallocate u32FenceHandle = %d for %p\n", pIter->u32FenceHandle, pDevice));
-        RTListNodeRemove(&pIter->node);
-        GaMemFree(pIter);
-    }
-}
-
-static void gaFenceDelete(VBOXWDDM_EXT_GA *pGaDevExt, GAFENCEOBJECT *pFO)
-{
-    GALOG(("u32FenceHandle = %d, pFO %p\n", pFO->u32FenceHandle, pFO));
-
-    gaFenceObjectsLock(pGaDevExt);
-
-    RTListNodeRemove(&pFO->node);
-    GaIdFree(pGaDevExt->fenceObjects.au32HandleBits, sizeof(pGaDevExt->fenceObjects.au32HandleBits),
-             VBOXWDDM_GA_MAX_FENCE_OBJECTS, pFO->u32FenceHandle);
-
-    gaFenceObjectsUnlock(pGaDevExt);
-
-    /// @todo Pool of fence objects to avoid memory allocations.
-    GaMemFree(pFO);
-}
-
-static void gaFenceDeleteLocked(VBOXWDDM_EXT_GA *pGaDevExt, GAFENCEOBJECT *pFO)
-{
-    GALOG(("u32FenceHandle = %d, pFO %p\n", pFO->u32FenceHandle, pFO));
-
-    RTListNodeRemove(&pFO->node);
-    GaIdFree(pGaDevExt->fenceObjects.au32HandleBits, sizeof(pGaDevExt->fenceObjects.au32HandleBits),
-             VBOXWDDM_GA_MAX_FENCE_OBJECTS, pFO->u32FenceHandle);
-
-    /// @todo Pool of fence objects to avoid memory allocations.
-    GaMemFree(pFO);
-}
-
-DECLINLINE(void) gaFenceRef(GAFENCEOBJECT *pFO)
-{
-    ASMAtomicIncU32(&pFO->cRefs);
-}
-
-DECLINLINE(void) gaFenceUnref(VBOXWDDM_EXT_GA *pGaDevExt, GAFENCEOBJECT *pFO)
-{
-    uint32_t c = ASMAtomicDecU32(&pFO->cRefs);
-    Assert(c < UINT32_MAX / 2);
-    if (c == 0)
-    {
-        gaFenceDelete(pGaDevExt, pFO);
-    }
-}
-
-DECLINLINE(void) gaFenceUnrefLocked(VBOXWDDM_EXT_GA *pGaDevExt, GAFENCEOBJECT *pFO)
-{
-    uint32_t c = ASMAtomicDecU32(&pFO->cRefs);
-    Assert(c < UINT32_MAX / 2);
-    if (c == 0)
-    {
-        gaFenceDeleteLocked(pGaDevExt, pFO);
-    }
-}
-
-static GAFENCEOBJECT *gaFenceLookup(VBOXWDDM_EXT_GA *pGaDevExt,
-                                    uint32_t u32FenceHandle)
-{
-    /* Must be called under the fence object lock. */
-    GAFENCEOBJECT *pIter;
-    RTListForEach(&pGaDevExt->fenceObjects.list, pIter, GAFENCEOBJECT, node)
-    {
-        if (pIter->u32FenceHandle == u32FenceHandle)
-        {
-            gaFenceRef(pIter);
-            return pIter;
-        }
-    }
-    return NULL;
-}
-
-
 void GaAdapterStop(PVBOXMP_DEVEXT pDevExt)
 {
@@ -263,5 +35,5 @@
     {
         /* Free fence objects. */
-        gaFenceObjectsDestroy(pGaDevExt, NULL);
+        GaFenceObjectsDestroy(pGaDevExt, NULL);
 
         if (pGaDevExt->hw.pSvga)
@@ -366,5 +138,5 @@
 {
     /* Free fence objects and GMRs. This is useful when the application has crashed.. */
-    gaFenceObjectsDestroy(pGaDevExt, pDevice);
+    GaFenceObjectsDestroy(pGaDevExt, pDevice);
     SvgaRegionsDestroy(pGaDevExt->hw.pSvga, pDevice);
 }
@@ -501,151 +273,4 @@
     if (pNode)
         GaMemFree(pNode);
-    return STATUS_SUCCESS;
-}
-
-
-/*
- * Fence objects.
- */
-
-NTSTATUS GaFenceCreate(PVBOXWDDM_EXT_GA pGaDevExt,
-                       PVBOXWDDM_DEVICE pDevice,
-                       uint32_t *pu32FenceHandle)
-{
-    GAFENCEOBJECT *pFO = (GAFENCEOBJECT *)GaMemAllocZero(sizeof(GAFENCEOBJECT));
-    if (!pFO)
-        return STATUS_INSUFFICIENT_RESOURCES;
-
-    /* pFO->cRefs             = 0; */
-    pFO->u32FenceState      = GAFENCE_STATE_IDLE;
-    /* pFO->fu32FenceFlags    = 0; */
-    /* pFO->u32SubmissionFenceId    = 0; */
-    pFO->u32SeqNo           = ASMAtomicIncU32(&pGaDevExt->fenceObjects.u32SeqNoSource);
-    pFO->pDevice            = pDevice;
-    /* RT_ZERO(pFO->event); */
-
-    gaFenceObjectsLock(pGaDevExt);
-
-    NTSTATUS Status = GaIdAlloc(pGaDevExt->fenceObjects.au32HandleBits, sizeof(pGaDevExt->fenceObjects.au32HandleBits),
-                                VBOXWDDM_GA_MAX_FENCE_OBJECTS, &pFO->u32FenceHandle);
-    if (NT_SUCCESS(Status))
-    {
-        RTListAppend(&pGaDevExt->fenceObjects.list, &pFO->node);
-        gaFenceRef(pFO);
-
-        gaFenceObjectsUnlock(pGaDevExt);
-
-        *pu32FenceHandle = pFO->u32FenceHandle;
-
-        GALOG(("u32FenceHandle = %d\n", pFO->u32FenceHandle));
-        return STATUS_SUCCESS;
-    }
-
-    /* Failure */
-    gaFenceObjectsUnlock(pGaDevExt);
-    GaMemFree(pFO);
-    return Status;
-}
-
-NTSTATUS GaFenceQuery(PVBOXWDDM_EXT_GA pGaDevExt,
-                      uint32_t u32FenceHandle,
-                      uint32_t *pu32SubmittedSeqNo,
-                      uint32_t *pu32ProcessedSeqNo,
-                      uint32_t *pu32FenceStatus)
-{
-    gaFenceObjectsLock(pGaDevExt);
-
-    GAFENCEOBJECT *pFO = gaFenceLookup(pGaDevExt, u32FenceHandle);
-
-    gaFenceObjectsUnlock(pGaDevExt);
-
-    GALOG(("u32FenceHandle = %d, pFO %p\n", u32FenceHandle, pFO));
-    if (pFO)
-    {
-        *pu32SubmittedSeqNo = pFO->u32SeqNo;
-        switch (pFO->u32FenceState)
-        {
-            default:
-                AssertFailed();
-                RT_FALL_THRU();
-            case GAFENCE_STATE_IDLE:      *pu32FenceStatus = GA_FENCE_STATUS_IDLE;      break;
-            case GAFENCE_STATE_SUBMITTED: *pu32FenceStatus = GA_FENCE_STATUS_SUBMITTED; break;
-            case GAFENCE_STATE_SIGNALED:  *pu32FenceStatus = GA_FENCE_STATUS_SIGNALED;  break;
-        }
-
-        gaFenceUnref(pGaDevExt, pFO);
-    }
-    else
-    {
-        *pu32SubmittedSeqNo = 0;
-        *pu32FenceStatus = GA_FENCE_STATUS_NULL;
-    }
-    *pu32ProcessedSeqNo = ASMAtomicReadU32(&pGaDevExt->u32LastCompletedSeqNo);
-
-    return STATUS_SUCCESS;
-}
-
-NTSTATUS GaFenceWait(PVBOXWDDM_EXT_GA pGaDevExt,
-                     uint32_t u32FenceHandle,
-                     uint32_t u32TimeoutUS)
-{
-    gaFenceObjectsLock(pGaDevExt);
-
-    GAFENCEOBJECT *pFO = gaFenceLookup(pGaDevExt, u32FenceHandle);
-    AssertReturnStmt(pFO, gaFenceObjectsUnlock(pGaDevExt), STATUS_INVALID_PARAMETER);
-
-    if (pFO->u32FenceState == GAFENCE_STATE_SIGNALED)
-    {
-        /* Already signaled. */
-        gaFenceObjectsUnlock(pGaDevExt);
-        gaFenceUnref(pGaDevExt, pFO);
-        return STATUS_SUCCESS;
-    }
-
-    /* Wait */
-    if (!RT_BOOL(pFO->fu32FenceFlags & GAFENCE_F_WAITED))
-    {
-        KeInitializeEvent(&pFO->event, NotificationEvent, FALSE);
-        pFO->fu32FenceFlags |= GAFENCE_F_WAITED;
-    }
-
-    gaFenceObjectsUnlock(pGaDevExt);
-
-    GALOG(("u32FenceHandle = %d, pFO %p\n", u32FenceHandle, pFO));
-
-    LARGE_INTEGER Timeout;
-    Timeout.QuadPart = u32TimeoutUS;
-    Timeout.QuadPart *= -10LL; /* Microseconds to relative 100-nanoseconds units. */
-    NTSTATUS Status = KeWaitForSingleObject(&pFO->event, UserRequest, KernelMode, TRUE, &Timeout);
-
-    gaFenceUnref(pGaDevExt, pFO);
-
-    return Status;
-}
-
-NTSTATUS GaFenceUnref(PVBOXWDDM_EXT_GA pGaDevExt,
-                      uint32_t u32FenceHandle)
-{
-    gaFenceObjectsLock(pGaDevExt);
-
-    GAFENCEOBJECT *pFO = gaFenceLookup(pGaDevExt, u32FenceHandle);
-    AssertReturnStmt(pFO, gaFenceObjectsUnlock(pGaDevExt), STATUS_INVALID_PARAMETER);
-
-    if (RT_BOOL(pFO->fu32FenceFlags & GAFENCE_F_WAITED))
-    {
-        KeSetEvent(&pFO->event, 0, FALSE);
-        pFO->fu32FenceFlags &= ~GAFENCE_F_WAITED;
-    }
-
-    gaFenceObjectsUnlock(pGaDevExt);
-
-    GALOG(("u32FenceHandle = %d, pFO %p\n", u32FenceHandle, pFO));
-
-    /* Undo gaFenceLookup ref. */
-    gaFenceUnref(pGaDevExt, pFO);
-
-    /* Undo the GaFenceCreate ref. */
-    gaFenceUnref(pGaDevExt, pFO);
-
     return STATUS_SUCCESS;
 }
@@ -1296,5 +921,5 @@
                     /* Verify that the buffer handle is valid. */
                     gaFenceObjectsLock(pGaDevExt);
-                    pFO = gaFenceLookup(pGaDevExt, u32FenceHandle);
+                    pFO = GaFenceLookup(pGaDevExt, u32FenceHandle);
                     gaFenceObjectsUnlock(pGaDevExt);
 
@@ -1772,5 +1397,5 @@
                 }
 
-                gaFenceUnrefLocked(pGaDevExt, pIter);
+                GaFenceUnrefLocked(pGaDevExt, pIter);
             }
         }
