Index: /trunk/include/VBox/HGSMI/HGSMI.h
===================================================================
--- /trunk/include/VBox/HGSMI/HGSMI.h	(revision 26555)
+++ /trunk/include/VBox/HGSMI/HGSMI.h	(revision 26556)
@@ -258,4 +258,9 @@
 void HGSMIAreaClear (HGSMIAREA *pArea);
 
+DECLINLINE(bool) HGSMIAreaContainsOffset(HGSMIAREA *pArea, HGSMIOFFSET offSet)
+{
+    return pArea->offBase <= offSet && pArea->offBase + pArea->cbArea < offSet;
+}
+
 HGSMIOFFSET HGSMIBufferInitializeSingle (const HGSMIAREA *pArea,
                                          HGSMIBUFFERHEADER *pHeader,
Index: /trunk/include/VBox/HGSMI/HGSMIChSetup.h
===================================================================
--- /trunk/include/VBox/HGSMI/HGSMIChSetup.h	(revision 26555)
+++ /trunk/include/VBox/HGSMI/HGSMIChSetup.h	(revision 26556)
@@ -50,4 +50,8 @@
 #define HGSMIHOSTFLAGS_COMMANDS_PENDING 0x1
 #define HGSMIHOSTFLAGS_IRQ              0x2
+#ifdef VBOXVDMA
+/* one or more guest commands is completed */
+# define HGSMIHOSTFLAGS_GCOMMAND_COMPLETED 0x4
+#endif
 
 typedef struct _HGSMIHOSTFLAGS
Index: /trunk/include/VBox/VBoxVideo.h
===================================================================
--- /trunk/include/VBox/VBoxVideo.h	(revision 26555)
+++ /trunk/include/VBox/VBoxVideo.h	(revision 26556)
@@ -797,8 +797,15 @@
 # define VBVA_VHWA_CMD    9
 #endif /* # ifdef VBOX_WITH_VIDEOHWACCEL */
+#ifdef VBOXVDMA
+# define VBVA_VDMA_CTL   10 /* setup G<->H DMA channel info */
+# define VBVA_VDMA_CMD    11 /* G->H DMA command             */
+#endif
 
 /* host->guest commands */
-# define VBVAHG_EVENT 1
-# define VBVAHG_DISPLAY_CUSTOM 2
+# define VBVAHG_EVENT              1
+# define VBVAHG_DISPLAY_CUSTOM     2
+#ifdef VBOXVDMA
+# define VBVAHG_SHGSMI_COMPLETION  3
+#endif
 
 # ifdef VBOX_WITH_VIDEOHWACCEL
@@ -988,3 +995,162 @@
 #endif /* VBOX_WITH_HGSMI */
 
+#ifdef VBOXVDMA
+# pragma pack(1)
+
+/*
+ * VBOXSHGSMI made on top HGSMI and allows receiving notifications
+ * about G->H command completion
+ */
+/* SHGSMI command header */
+typedef struct VBOXSHGSMIHEADER
+{
+    uint64_t pvNext;    /*<- completion processing queue */
+    uint32_t fFlags;    /*<- see VBOXSHGSMI_FLAG_XXX Flags */
+    uint32_t cRefs;     /*<- command referece count */
+    uint64_t u64Info1;  /*<- contents depends on the fFlags value */
+    uint64_t u64Info2;  /*<- contents depends on the fFlags value */
+} VBOXSHGSMIHEADER, *PVBOXSHGSMIHEADER;
+
+/* the command processing was asynch, set by the host to indicate asynch command completion
+ * must not be cleared once set, the command completion is performed by issuing a host->guest completion command
+ * while keeping this flag unchanged */
+#define VBOXSHGSMI_FLAG_HG_ASYNCH               0x00010000
+///* if set     - asynch completion is performed by issuing the event,
+// * if cleared - asynch completion is performed by calling a callback */
+//#define VBOXSHGSMI_FLAG_GH_ASYNCH_EVENT         0x00000001
+/* issue interrupt on asynch completion, used for critical G->H commands,
+ * i.e. for completion of which guest is waiting. */
+#define VBOXSHGSMI_FLAG_GH_ASYNCH_IRQ           0x00000002
+/* guest does not do any op on completion of this command,
+ * the host may copy the command and indicate that it does not need the command anymore
+ * by not setting VBOXSHGSMI_FLAG_HG_ASYNCH */
+#define VBOXSHGSMI_FLAG_GH_ASYNCH_NOCOMPLETION  0x00000004
+/* guest requires the command to be processed asynchronously,
+ * not setting VBOXSHGSMI_FLAG_HG_ASYNCH by the host in this case is treated as command failure */
+#define VBOXSHGSMI_FLAG_GH_ASYNCH_FORCE         0x00000008
+/* force IRQ on cmd completion */
+#define VBOXSHGSMI_FLAG_GH_ASYNCH_IRQ_FORCE     0x00000010
+/* an IRQ-level callback is associated with the command */
+#define VBOXSHGSMI_FLAG_GH_ASYNCH_CALLBACK_IRQ  0x00000020
+/* guest expects this command to be completed synchronously */
+#define VBOXSHGSMI_FLAG_GH_SYNCH                0x00000040
+
+/* VDMA - Video DMA */
+
+/* VDMA Control API */
+/* VBOXVDMA_CTL::u32Flags */
+#define VBOXVDMA_CTL_NONE    0x00000000
+#define VBOXVDMA_CTL_ENABLE  0x00000001
+#define VBOXVDMA_CTL_DISABLE 0x00000002
+#define VBOXVDMA_CTL_FLUSH   0x00000004
+
+typedef struct VBOXVDMA_CTL
+{
+    uint32_t u32Flags;
+    uint32_t u32Offset;
+    int32_t  i32Result;
+} VBOXVDMA_CTL, *PVBOXVDMA_CTL;
+
+typedef struct VBOXVDMA_RECTL
+{
+    int16_t left;
+    int16_t top;
+    uint16_t width;
+    uint16_t height;
+} VBOXVDMA_RECTL, *PVBOXVDMA_RECTL;
+
+//typedef uint64_t VBOXVDMAPHADDRESS;
+typedef uint64_t VBOXVDMASURFHANDLE;
+
+typedef enum
+{
+    VBOXVDMACMD_TYPE_UNDEFINED        = 0,
+    VBOXVDMACMD_TYPE_DMATRANSFER      = 1
+} VBOXVDMACMD_TYPE;
+
+/* region specified as a rectangle, otherwize it is a size of memory pointed to by phys address */
+#define VBOXVDMAOPERAND_FLAGS_RECTL       0x1
+/* Surface handle is valid */
+#define VBOXVDMAOPERAND_FLAGS_PRIMARY        0x2
+/* address is offset in VRAM */
+#define VBOXVDMAOPERAND_FLAGS_VRAMOFFSET  0x4
+
+typedef struct VBOXVDMA_RANGE_RECTL
+{
+    VBOXVDMA_RECTL RangeRectl;
+    VBOXVDMA_RECTL SurfSize;
+}VBOXVDMA_RANGE_RECTL, *PVBOXVDMA_RANGE_RECTL;
+
+typedef struct VBOXVDMA_RANGE_SIZE
+{
+    uint32_t cbSize;
+    uint32_t u32Reserved;
+}VBOXVDMA_RANGE_SIZE, *PVBOXVDMA_RANGE_SIZE;
+
+typedef struct VBOXVDMAOPERAND
+{
+    uint32_t fFlags;
+    union
+    {
+        /* for Src specifies num of Dsts */
+        uint32_t cDsts;
+        /* for Dst specifies Screen ID in case VBOXVDMAOPERAND_FLAGS_PRIMARY flag is present in fFlags */
+        uint32_t iScreen;
+    } Info;
+    RTGCPHYS phAddress;
+    union
+    {
+        VBOXVDMA_RANGE_RECTL Rectl;
+        VBOXVDMA_RANGE_SIZE  Size;
+    } Range;
+} VBOXVDMAOPERAND, *PVBOXVDMAOPERAND;
+
+/* VBOXVDMACBUF_DR::phBuf specifies offset in VRAM */
+#define VBOXVDMACBUF_FLAG_BUF_VRAM_OFFSET 0x00000001
+/* command buffer follows the VBOXVDMACBUF_DR in VRAM, VBOXVDMACBUF_DR::phBuf is ignored */
+#define VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR  0x00000002
+
+/*
+ * We can not submit the DMA command via VRAM since we do not have control over
+ * DMA command buffer [de]allocation, i.e. we only control the buffer contents.
+ * In other words the system may call one of our callbacks to fill a command buffer
+ * with the necessary commands and then discard the buffer w/o any notification.
+ *
+ * We have only DMA command buffer physical address at submission time.
+ *
+ * so the only way is to */
+typedef struct VBOXVDMACBUF_DR
+{
+    uint32_t fFlags;
+    uint32_t cbBuf;
+    uint32_t u32FenceId;
+    /* RT_SUCCESS()     - on success
+     * VERR_INTERRUPTED - on preemption
+     * VERR_xxx         - on error */
+    int32_t  rc;
+    uint64_t phBuf;
+} VBOXVDMACBUF_DR, *PVBOXVDMACBUF_DR;
+
+#define VBOXVDMACBUF_DR_TAIL(_pCmd, _t) ( (_t)(((uint8_t*)(_pCmd)) + sizeof (VBOXVDMACBUF_DR)) )
+
+typedef struct VBOXVDMACMD
+{
+    VBOXVDMACMD_TYPE enmType;
+    uint32_t cbCmd;
+} VBOXVDMACMD, *PVBOXVDMACMD;
+
+#define VBOXVDMACMD_HEADER_SIZE() sizeof (VBOXVDMACMD)
+#define VBOXVDMACMD_BODY_SIZE(_pCmd) ((_pCmd)->cbBody)
+#define VBOXVDMACMD_SIZE(_pCmd) (VBOXVDMACMD_HEADER_SIZE() + VBOXVDMACMD_BODY_SIZE(_pCmd))
+#define VBOXVDMACMD_BODY(_pCmd, _t) ( (_t)(((uint8_t*)(_pCmd)) + VBOXVDMACMD_HEADER_SIZE()) )
+
+typedef struct VBOXVDMACMD_DMATRANSFER
+{
+    VBOXVDMAOPERAND Src;
+    /* the size of aDst is specified in Src::u32CmdSpecific*/
+    VBOXVDMAOPERAND aDst[1];
+} VBOXVDMACMD_DMATRANSFER, *PVBOXVDMACMD_DMATRANSFER;
+# pragma pack()
+#endif /* #ifdef VBOXVDMA */
+
 #endif
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/Makefile.kmk	(revision 26555)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/Makefile.kmk	(revision 26556)
@@ -82,7 +82,8 @@
   VBoxVideoWddm_NOINST     = true
  endif
+ 
  VBoxVideoWddm_SDKS=WINDDKWLH
  VBoxVideoWddm_DEFS       += LOG_TO_BACKDOOR VBOX_WITH_8BPP_MODES
- VBoxVideoWddm_DEFS       += VBOX_WITH_HGSMI VBOXWDDM
+ VBoxVideoWddm_DEFS       += VBOX_WITH_HGSMI VBOXWDDM VBOXVDMA
  ifdef VBOX_WITH_VIDEOHWACCEL
   VBoxVideoWddm_DEFS      += VBOX_WITH_VIDEOHWACCEL
@@ -98,4 +99,6 @@
  	wddm/VBoxVideoWddm.cpp \
 	wddm/VBoxVideoVidPn.cpp \
+	wddm/VBoxVideoVdma.cpp \
+	wddm/VBoxVideoShgsmi.cpp \
  	wddm/VBoxVideoWddm.def \
  	wddm/VBoxVideoWddm.rc
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp	(revision 26555)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp	(revision 26556)
@@ -263,10 +263,14 @@
 
     /* size of the VRAM in bytes */
+
+#ifndef VBOXWDDM
     ULONG vramSize = DeviceExtension->pPrimary->u.primary.ulMaxFrameBufferSize;
-
-    gNumVideoModes = 0;
-#ifdef VBOXWDDM
+#else
+    ULONG vramSize = vboxWddmVramReportedSize(DeviceExtension);
+
     gPreferredVideoMode = 0;
 #endif
+
+    gNumVideoModes = 0;
 
     size_t numModesCurrentColorDepth;
@@ -751,7 +755,11 @@
         || (gCustomXRes || gCustomYRes || gCustomBPP))
     {
+#ifndef VBOXWDDM
         dprintf(("VBoxVideo: adding custom video mode as #%d, current mode: %d \n", gNumVideoModes + 1, DeviceExtension->CurrentMode));
         /* handle the startup case */
         if (DeviceExtension->CurrentMode == 0)
+#else
+        if (!DeviceExtension->cSources || !DeviceExtension->aSources[0].ulFrameBufferSize)
+#endif
         {
             /* Use the stored custom resolution values only if nothing was read from host.
@@ -771,4 +779,5 @@
         xres &= 0xfff8;
         /* take the current values for the fields that are not set */
+#ifndef VBOXWDDM
         if (DeviceExtension->CurrentMode != 0)
         {
@@ -780,4 +789,15 @@
                 bpp  = DeviceExtension->CurrentModeBPP;
         }
+#else
+        if (DeviceExtension->cSources && DeviceExtension->aSources[0].ulFrameBufferSize)
+        {
+            if (!xres)
+                xres = DeviceExtension->aSources[0].VisScreenWidth;
+            if (!yres)
+                yres = DeviceExtension->aSources[0].VisScreenHeight;
+            if (!bpp)
+                bpp  = DeviceExtension->aSources[0].BitsPerPlane;
+        }
+#endif
 
         /* Use a default value. */
@@ -801,5 +821,9 @@
             {
                 /* we need an alternating index */
+#ifndef VBOXWDDM
                 if (DeviceExtension->CurrentMode != 0)
+#else
+                if (DeviceExtension->cSources && DeviceExtension->aSources[0].ulFrameBufferSize)
+#endif
                 {
                     if (gInvocationCounter % 2)
@@ -877,5 +901,9 @@
 
                 /* for the startup case, we need this mode twice due to the alternating mode number */
+#ifndef VBOXWDDM
                 if (DeviceExtension->CurrentMode == 0)
+#else
+                if (!DeviceExtension->cSources || !DeviceExtension->aSources[0].ulFrameBufferSize)
+#endif
                 {
                     dprintf(("VBoxVideo: making a copy of the custom mode as #%d\n", gNumVideoModes + 1));
@@ -918,5 +946,7 @@
     {
         int i;
+#ifndef VBOXWDDM
         dprintf(("VBoxVideo: VideoModes (CurrentMode = %d)\n", DeviceExtension->CurrentMode));
+#endif
         for (i=0; i<MAX_VIDEO_MODES + 2; i++)
         {
@@ -965,5 +995,5 @@
 }
 
-#endif
+#else
 
 /* Computes the size of a framebuffer. DualView has a few framebuffers of the computed size. */
@@ -1033,4 +1063,6 @@
     }
 }
+
+#endif
 
 int VBoxMapAdapterMemory (PDEVICE_EXTENSION PrimaryExtension, void **ppv, ULONG ulOffset, ULONG ulSize)
@@ -1087,5 +1119,7 @@
         VideoPortUnmapMemory(PrimaryExtension, *ppv, NULL);
 #else
-        MmUnmapIoSpace(*ppv, ulSize);
+        NTSTATUS ntStatus = PrimaryExtension->u.primary.DxgkInterface.DxgkCbUnmapMemory(PrimaryExtension->u.primary.DxgkInterface.DeviceHandle,
+                *ppv);
+        Assert(ntStatus == STATUS_SUCCESS);
 #endif
     }
@@ -2430,6 +2464,4 @@
 }
 
-#ifndef VBOXWDDM
-
 /**
  * VBoxVideoSetCurrentMode
@@ -2438,6 +2470,13 @@
  */
 BOOLEAN FASTCALL VBoxVideoSetCurrentMode(PDEVICE_EXTENSION DeviceExtension,
-                                         PVIDEO_MODE RequestedMode, PSTATUS_BLOCK StatusBlock)
-{
+#ifndef VBOXWDDM
+                                         PVIDEO_MODE RequestedMode, PSTATUS_BLOCK StatusBlock
+#else
+                                         D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId,
+                                         PVBOXWDDM_SOURCE ModeInfo
+#endif
+                                         )
+{
+#ifndef VBOXWDDM
     PVIDEO_MODE_INFORMATION ModeInfo;
 
@@ -2459,4 +2498,14 @@
         return TRUE;
     }
+#else
+    Assert(!srcId);
+
+    if (srcId)
+    {
+        dprintf(("VBoxVideo::VBoxVideoSetCurrentMode: Skipping for ? non-primary ? source ? %d\n",
+                srcId));
+        return TRUE;
+    }
+#endif
 
     /* set the mode characteristics */
@@ -2481,4 +2530,6 @@
 }
 
+#ifndef VBOXWDDM
+
 /*
  * VBoxVideoResetDevice
@@ -2677,4 +2728,6 @@
    return TRUE;
 }
+
+#ifndef VBOXWDDM
 
 VP_STATUS VBoxVideoGetChildDescriptor(
@@ -2870,2 +2923,3 @@
     return rc;
 }
+#endif
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h	(revision 26555)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h	(revision 26556)
@@ -117,4 +117,6 @@
 #else
 #include <VBox/VBoxVideo.h>
+#include "wddm/VBoxVideoShgsmi.h"
+#include "wddm/VBoxVideoVdma.h"
 
 typedef KSPIN_LOCK VBOXVCMNSPIN_LOCK, *PVBOXVCMNSPIN_LOCK;
@@ -125,14 +127,12 @@
 typedef HANDLE VBOXCMNREG;
 
-typedef enum
-{
-    VBOXWDDM_CMD_UNEFINED = 0,
-    VBOXWDDM_CMD_DMA_TRANSFER
-} VBOXWDDM_CMD_TYPE;
-
 typedef struct VBOXWDDM_SOURCE
 {
-    HGSMIHEAP hgsmiDisplayHeap;
-//    VBVABUFFER *pVBVA; /* Pointer to the pjScreen + layout->offVBVABuffer. NULL if VBVA is not enabled. */
+    ULONG VisScreenWidth;
+    ULONG VisScreenHeight;
+    ULONG BitsPerPlane;
+
+    ULONG ulFrameBufferOffset;                  /* The framebuffer position in the VRAM. */
+    ULONG ulFrameBufferSize;                    /* The size of the current framebuffer. */
 } VBOXWDDM_SOURCE, *PVBOXWDDM_SOURCE;
 
@@ -211,5 +211,4 @@
     DXGK_DEVICEINFO DeviceInfo;
 } VBOXWDDM_DEVICE, *PVBOXWDDM_DEVICE;
-
 #endif
 
@@ -219,9 +218,8 @@
                                                 * The primary extension is the first one.
                                                 */
-
+#ifndef VBOXWDDM
    struct _DEVICE_EXTENSION *pPrimary;         /* Pointer to the primary device extension. */
 
    ULONG iDevice;                              /* Device index: 0 for primary, otherwise a secondary device. */
-
 
    ULONG CurrentMode;                          /* Saved information about video modes */
@@ -232,5 +230,5 @@
    ULONG ulFrameBufferOffset;                  /* The framebuffer position in the VRAM. */
    ULONG ulFrameBufferSize;                    /* The size of the current framebuffer. */
-
+#endif
    union {
        /* Information that is only relevant to the primary device or is the same for all devices. */
@@ -258,4 +256,8 @@
                                                 * This is mapped by miniport separately.
                                                 */
+#ifdef VBOXWDDM
+           VBOXVDMAINFO Vdma;
+#endif
+
 #ifdef VBOX_WITH_HGSMI
            volatile HGSMIHOSTFLAGS * pHostFlags; /* HGSMI host flags */
@@ -315,4 +317,9 @@
    PDEVICE_OBJECT pPDO;
 
+   VBOXSHGSMILIST CtlList;
+   VBOXSHGSMILIST DmaCmdList;
+   BOOL bSetNotifyDxDpc;
+   BOOL bNotifyDxDpc;
+
    ULONG cSources;
    /* currently we define the array for the max possible size since we do not know
@@ -326,4 +333,5 @@
 } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
 
+#ifndef VBOXWDDM
 #define DEV_MOUSE_HIDDEN(dev) ((dev)->pPrimary->u.primary.fMouseHidden)
 #define DEV_SET_MOUSE_HIDDEN(dev)   \
@@ -335,5 +343,15 @@
     (dev)->pPrimary->u.primary.fMouseHidden = FALSE; \
 } while (0)
-
+#else
+#define DEV_MOUSE_HIDDEN(dev) ((dev)->u.primary.fMouseHidden)
+#define DEV_SET_MOUSE_HIDDEN(dev)   \
+do { \
+    (dev)->u.primary.fMouseHidden = TRUE; \
+} while (0)
+#define DEV_SET_MOUSE_SHOWN(dev)   \
+do { \
+    (dev)->u.primary.fMouseHidden = FALSE; \
+} while (0)
+#endif
 extern "C"
 {
@@ -626,8 +644,13 @@
 VOID VBoxWddmGetModesTable(PDEVICE_EXTENSION DeviceExtension, bool bRebuildTable,
         VIDEO_MODE_INFORMATION ** ppModes, uint32_t * pcModes, uint32_t * pPreferrableMode,
-        D3DKMDT_2DREGION **pResolutions, uint32_t * pcResolutions);
+        D3DKMDT_2DREGION **ppResolutions, uint32_t * pcResolutions);
 
 D3DDDIFORMAT vboxWddmCalcPixelFormat(VIDEO_MODE_INFORMATION *pInfo);
 UINT vboxWddmCalcBitsPerPixel(D3DDDIFORMAT format);
+
+DECLINLINE(ULONG) vboxWddmVramReportedSize(PDEVICE_EXTENSION pDevExt)
+{
+    return pDevExt->u.primary.Vdma.CmdHeap.area.offBase;
+}
 
 NTSTATUS vboxVidPnCheckTopology(const D3DKMDT_HVIDPN hDesiredVidPn,
@@ -764,20 +787,36 @@
 DECLINLINE(void) VBoxHGSMIHostWrite(PDEVICE_EXTENSION PrimaryExtension, ULONG data)
 {
+#ifndef VBOXWDDM
     VBoxVideoCmnPortWriteUlong((PULONG)PrimaryExtension->pPrimary->u.primary.IOPortHost, data);
+#else
+    VBoxVideoCmnPortWriteUlong((PULONG)PrimaryExtension->u.primary.IOPortHost, data);
+#endif
 }
 
 DECLINLINE(ULONG) VBoxHGSMIHostRead(PDEVICE_EXTENSION PrimaryExtension)
 {
+#ifndef VBOXWDDM
     return VBoxVideoCmnPortReadUlong((PULONG)PrimaryExtension->pPrimary->u.primary.IOPortHost);
+#else
+    return VBoxVideoCmnPortReadUlong((PULONG)PrimaryExtension->u.primary.IOPortHost);
+#endif
 }
 
 DECLINLINE(void) VBoxHGSMIGuestWrite(PDEVICE_EXTENSION PrimaryExtension, ULONG data)
 {
+#ifndef VBOXWDDM
     VBoxVideoCmnPortWriteUlong((PULONG)PrimaryExtension->pPrimary->u.primary.IOPortGuest, data);
+#else
+    VBoxVideoCmnPortWriteUlong((PULONG)PrimaryExtension->u.primary.IOPortGuest, data);
+#endif
 }
 
 DECLINLINE(ULONG) VBoxHGSMIGuestRead(PDEVICE_EXTENSION PrimaryExtension)
 {
+#ifndef VBOXWDDM
     return VBoxVideoCmnPortReadUlong((PULONG)PrimaryExtension->pPrimary->u.primary.IOPortGuest);
+#else
+    return VBoxVideoCmnPortReadUlong((PULONG)PrimaryExtension->u.primary.IOPortGuest);
+#endif
 }
 
@@ -792,6 +831,8 @@
                                 PVIDEO_POINTER_ATTRIBUTES pointerAttr,
                                 uint32_t cbLength);
+#ifndef VBOXWDDM
 DECLCALLBACK(void) hgsmiHostCmdComplete (HVBOXVIDEOHGSMI hHGSMI, struct _VBVAHOSTCMD * pCmd);
 DECLCALLBACK(int) hgsmiHostCmdRequest (HVBOXVIDEOHGSMI hHGSMI, uint8_t u8Channel, struct _VBVAHOSTCMD ** ppCmd);
+#endif
 
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideoHGSMI.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideoHGSMI.cpp	(revision 26555)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideoHGSMI.cpp	(revision 26556)
@@ -186,4 +186,50 @@
 typedef FNHGSMICALLFINALIZE *PFNHGSMICALLFINALIZE;
 
+void* VBoxHGSMIBufferAlloc (PDEVICE_EXTENSION PrimaryExtension,
+                         HGSMISIZE cbData,
+                         uint8_t u8Ch,
+                         uint16_t u16Op)
+{
+#ifdef VBOXWDDM
+    /* @todo: add synchronization */
+#endif
+    return HGSMIHeapAlloc (&PrimaryExtension->u.primary.hgsmiAdapterHeap, cbData, u8Ch, u16Op);
+}
+
+void* VBoxHGSMIBufferAlloc (PDEVICE_EXTENSION PrimaryExtension,
+                         uint8_t u8Ch,
+                         uint16_t u16Op,
+                         HGSMISIZE cbData)
+{
+#ifdef VBOXWDDM
+    /* @todo: add synchronization */
+#endif
+    return HGSMIHeapAlloc (&PrimaryExtension->u.primary.hgsmiAdapterHeap, cbData, u8Ch, u16Op);
+}
+
+void VBoxHGSMIBufferFree (PDEVICE_EXTENSION PrimaryExtension, void *pvBuffer)
+{
+#ifdef VBOXWDDM
+    /* @todo: add synchronization */
+#endif
+    HGSMIHeapFree (&PrimaryExtension->u.primary.hgsmiAdapterHeap, pvBuffer);
+}
+
+int VBoxHGSMIBufferSubmit (PDEVICE_EXTENSION PrimaryExtension, void *pvBuffer)
+{
+    /* Initialize the buffer and get the offset for port IO. */
+    HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (&PrimaryExtension->u.primary.hgsmiAdapterHeap, pvBuffer);
+
+    Assert(offBuffer != HGSMIOFFSET_VOID);
+    if (offBuffer != HGSMIOFFSET_VOID)
+    {
+        /* Submit the buffer to the host. */
+        VBoxHGSMIGuestWrite(PrimaryExtension, offBuffer);
+        return VINF_SUCCESS;
+    }
+
+    return VERR_INVALID_PARAMETER;
+}
+
 static int vboxCallChannel (PDEVICE_EXTENSION PrimaryExtension,
                          uint8_t u8Ch,
@@ -197,4 +243,5 @@
 
     /* Allocate the IO buffer. */
+#ifndef VBOXWDDM
     if (PrimaryExtension->pPrimary != PrimaryExtension)
     {
@@ -202,4 +249,5 @@
         return VERR_INVALID_PARAMETER;
     }
+#endif
 
     void *p = HGSMIHeapAlloc (&PrimaryExtension->u.primary.hgsmiAdapterHeap, cbData, u8Ch, u16Op);
@@ -315,5 +363,5 @@
     return rc;
 }
-
+#ifndef VBOXWDDM
 static int vbvaInitInfoDisplay (PDEVICE_EXTENSION PrimaryExtension, void *pvContext, void *pvData)
 {
@@ -348,4 +396,5 @@
     return VERR_INTERNAL_ERROR;
 }
+#endif
 
 static int vbvaInitInfoHeap (PDEVICE_EXTENSION PrimaryExtension, void *pvContext, void *pvData)
@@ -389,4 +438,5 @@
     if(RT_SUCCESS (rc))
     {
+#ifndef VBOXWDDM
         rc = vboxCallVBVA (PrimaryExtension,
                                VBVA_INFO_VIEW,
@@ -397,4 +447,9 @@
         AssertRC(rc);
         if (RT_SUCCESS (rc))
+#else
+        /* in case of WDDM we do not control the framebuffer location,
+         * i.e. it is assigned by Video Memory Manager,
+         * The FB information should be passed to guest from our DxgkDdiSetVidPnSourceAddress callback */
+#endif
         {
             /* Report the host heap location. */
@@ -660,8 +715,10 @@
      */
     PrimaryExtension->pNext                              = NULL;
+#ifndef VBOXWDDM
     PrimaryExtension->pPrimary                           = PrimaryExtension;
     PrimaryExtension->iDevice                            = 0;
     PrimaryExtension->ulFrameBufferOffset                = 0;
     PrimaryExtension->ulFrameBufferSize                  = 0;
+#endif
     PrimaryExtension->u.primary.ulVbvaEnabled            = 0;
     PrimaryExtension->u.primary.bVBoxVideoSupported      = FALSE;
@@ -861,8 +918,10 @@
     }
 
+#ifndef VBOXWDDM
     /* Now when the number of monitors is known and extensions are created,
      * calculate the layout of framebuffers.
      */
     VBoxComputeFrameBufferSizes (PrimaryExtension);
+#endif
 
     if (PrimaryExtension->u.primary.bHGSMI)
@@ -876,4 +935,38 @@
         }
     }
+
+#ifdef VBOXWDDM
+    if (PrimaryExtension->u.primary.bHGSMI)
+    {
+        ULONG ulAvailable = PrimaryExtension->u.primary.cbVRAM
+                            - PrimaryExtension->u.primary.cbMiniportHeap
+                            - VBVA_ADAPTER_INFORMATION_SIZE;
+
+        /* use 25% od VRAM for DMA command buffer
+         * @todo: ^^^? */
+        ULONG ulSize = ulAvailable / 4;
+
+        /* Align down to 4096 bytes. */
+        ulSize &= ~0xFFF;
+        ULONG offset = ulAvailable - ulSize;
+
+        Assert(!(offset & 0xFFF));
+
+        rc = vboxVdmaCreate (PrimaryExtension, &PrimaryExtension->u.primary.Vdma, offset, ulSize);
+        AssertRC(rc);
+        if (RT_SUCCESS(rc))
+        {
+            /* can enable it right away since the host does not need any screen/FB info
+             * for basic DMA functionality */
+            rc = vboxVdmaEnable(PrimaryExtension, &PrimaryExtension->u.primary.Vdma);
+            AssertRC(rc);
+            if (RT_FAILURE(rc))
+                vboxVdmaDestroy(PrimaryExtension, &PrimaryExtension->u.primary.Vdma);
+        }
+
+        if (RT_FAILURE(rc))
+            PrimaryExtension->u.primary.bHGSMI = FALSE;
+    }
+#endif
 
     if (!PrimaryExtension->u.primary.bHGSMI)
@@ -953,4 +1046,5 @@
                                 uint32_t cbLength)
 {
+#ifndef VBOXWDDM
     PDEVICE_EXTENSION PrimaryExtension = DeviceExtension->pPrimary;
 
@@ -977,4 +1071,7 @@
         return TRUE;
     }
+#else
+    PDEVICE_EXTENSION PrimaryExtension = DeviceExtension;
+#endif
 
     uint32_t cbData = 0;
@@ -1116,4 +1213,5 @@
 }
 
+#ifndef VBOXWDDM
 DECLCALLBACK(void) hgsmiHostCmdComplete (HVBOXVIDEOHGSMI hHGSMI, struct _VBVAHOSTCMD * pCmd)
 {
@@ -1164,4 +1262,5 @@
     return VERR_INVALID_PARAMETER;
 }
+#endif
 
 static DECLCALLBACK(int) vboxVBVAChannelGenericHandler(void *pvHandler, uint16_t u16ChannelInfo, void *pvBuffer, HGSMISIZE cbBuffer)
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoShgsmi.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoShgsmi.cpp	(revision 26556)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoShgsmi.cpp	(revision 26556)
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * 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.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#include "../VBoxVideo.h"
+#include "../Helper.h"
+
+#include <VBox/VBoxGuestLib.h>
+#include <VBox/VBoxVideo.h>
+
+#include <iprt/asm.h>
+#include <iprt/semaphore.h>
+
+#include "VBoxVideoShgsmi.h"
+
+
+/* SHGSMI */
+
+DECLINLINE(uint8_t *) vboxSHGSMIBufferData (const PVBOXSHGSMIHEADER pHeader)
+{
+    return (uint8_t *)pHeader + sizeof (VBOXSHGSMIHEADER);
+}
+
+DECLINLINE(PVBOXSHGSMIHEADER) vboxSHGSMIBufferHeader (const void *pvData)
+{
+    return (PVBOXSHGSMIHEADER)((uint8_t *)pvData - sizeof (VBOXSHGSMIHEADER));
+}
+
+DECLINLINE(void) vboxSHGSMICommandRetain (PVBOXSHGSMIHEADER pCmd)
+{
+    ASMAtomicIncU32(&pCmd->cRefs);
+}
+
+void vboxSHGSMICommandFree (struct _HGSMIHEAP * pHeap, PVBOXSHGSMIHEADER pCmd)
+{
+    HGSMIHeapFree (pHeap, pCmd);
+}
+
+DECLINLINE(void) vboxSHGSMICommandRelease (struct _HGSMIHEAP * pHeap, PVBOXSHGSMIHEADER pCmd)
+{
+    uint32_t cRefs = ASMAtomicDecU32(&pCmd->cRefs);
+    Assert(cRefs < UINT32_MAX / 2);
+    if(!cRefs)
+        vboxSHGSMICommandFree (pHeap, pCmd);
+}
+
+DECLCALLBACK(void) vboxSHGSMICompletionSetEvent(struct _HGSMIHEAP * pHeap, void *pvCmd, void *pvContext)
+{
+    RTSemEventSignal((RTSEMEVENT)pvContext);
+}
+
+DECLCALLBACK(void) vboxSHGSMICompletionCommandRelease(struct _HGSMIHEAP * pHeap, void *pvCmd, void *pvContext)
+{
+    vboxSHGSMICommandRelease (pHeap, vboxSHGSMIBufferHeader(pvCmd));
+}
+
+
+DECLINLINE(void) vboxSHGSMICommandDoSubmit(struct _HGSMIHEAP * pHeap, PVBOXSHGSMIHEADER pHeader)
+{
+    /* Initialize the buffer and get the offset for port IO. */
+    HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (pHeap, pHeader);
+
+    /* Submit the buffer to the host. */
+    vboxSHGSMICbCommandWrite(pHeap, offBuffer);
+}
+
+/* do not wait for completion */
+DECLINLINE(void) vboxSHGSMICommandSubmitAsynch (struct _HGSMIHEAP * pHeap, PVBOXSHGSMIHEADER pHeader)
+{
+    /* ensure the command is not removed until we're processing it */
+    vboxSHGSMICommandRetain(pHeader);
+
+    vboxSHGSMICommandDoSubmit(pHeap, pHeader);
+
+    if(!(ASMAtomicReadU32((volatile uint32_t *)&pHeader->fFlags) & VBOXSHGSMI_FLAG_HG_ASYNCH))
+    {
+        PFNVBOXSHGSMICMDCOMPLETION pfnCompletion = (PFNVBOXSHGSMICMDCOMPLETION)pHeader->u64Info1;
+        pfnCompletion(pHeap, vboxSHGSMIBufferData (pHeader), (PVOID)pHeader->u64Info1);
+    }
+
+    vboxSHGSMICommandRelease(pHeap, pHeader);
+
+}
+
+void VBoxSHGSMICommandSubmitAsynchEvent (struct _HGSMIHEAP * pHeap, PVOID pvBuff, RTSEMEVENT hEventSem)
+{
+    PVBOXSHGSMIHEADER pHeader = vboxSHGSMIBufferHeader (pvBuff);
+    pHeader->u64Info1 = (uint64_t)vboxSHGSMICompletionSetEvent;
+    pHeader->u64Info2 = (uint64_t)hEventSem;
+    pHeader->fFlags   = VBOXSHGSMI_FLAG_GH_ASYNCH_IRQ;
+
+    vboxSHGSMICommandSubmitAsynch (pHeap, pHeader);
+}
+
+int VBoxSHGSMICommandSubmitSynch (struct _HGSMIHEAP * pHeap, PVOID pCmd)
+{
+    RTSEMEVENT hEventSem;
+    int rc = RTSemEventCreate(&hEventSem);
+    Assert(RT_SUCCESS(rc));
+    if (RT_SUCCESS(rc))
+    {
+        VBoxSHGSMICommandSubmitAsynchEvent (pHeap, pCmd, hEventSem);
+
+        rc = RTSemEventWait(hEventSem, RT_INDEFINITE_WAIT);
+        Assert(RT_SUCCESS(rc));
+        if (RT_SUCCESS(rc))
+            RTSemEventDestroy(hEventSem);
+    }
+    return rc;
+}
+
+void VBoxSHGSMICommandSubmitAsynch (struct _HGSMIHEAP * pHeap, PVOID pvBuff, PFNVBOXSHGSMICMDCOMPLETION pfnCompletion, PVOID pvCompletion, uint32_t fFlags)
+{
+    fFlags &= ~VBOXSHGSMI_FLAG_GH_ASYNCH_CALLBACK_IRQ;
+    PVBOXSHGSMIHEADER pHeader = vboxSHGSMIBufferHeader (pvBuff);
+    pHeader->u64Info1 = (uint64_t)pfnCompletion;
+    pHeader->u64Info2 = (uint64_t)pvCompletion;
+    pHeader->fFlags = fFlags;
+
+    vboxSHGSMICommandSubmitAsynch (pHeap, pHeader);
+}
+
+void VBoxSHGSMICommandSubmitAsynchIrq (struct _HGSMIHEAP * pHeap, PVOID pvBuff, PFNVBOXSHGSMICMDCOMPLETION_IRQ pfnCompletion, PVOID pvCompletion, uint32_t fFlags)
+{
+    fFlags |= VBOXSHGSMI_FLAG_GH_ASYNCH_CALLBACK_IRQ | VBOXSHGSMI_FLAG_GH_ASYNCH_IRQ;
+    PVBOXSHGSMIHEADER pHeader = vboxSHGSMIBufferHeader (pvBuff);
+    pHeader->u64Info1 = (uint64_t)pfnCompletion;
+    pHeader->u64Info2 = (uint64_t)pvCompletion;
+    pHeader->fFlags = fFlags;
+
+    vboxSHGSMICommandSubmitAsynch (pHeap, pHeader);
+}
+
+void* VBoxSHGSMICommandAlloc (struct _HGSMIHEAP * pHeap, HGSMISIZE cbData, uint8_t u8Channel, uint16_t u16ChannelInfo)
+{
+    /* Issue the flush command. */
+    PVBOXSHGSMIHEADER pHeader = (PVBOXSHGSMIHEADER)HGSMIHeapAlloc (pHeap, cbData + sizeof (VBOXSHGSMIHEADER), u8Channel, u16ChannelInfo);
+    Assert(pHeader);
+    if (pHeader)
+        return vboxSHGSMIBufferData(pHeader);
+    return NULL;
+}
+
+void VBoxSHGSMICommandFree (struct _HGSMIHEAP * pHeap, void *pvBuffer)
+{
+    PVBOXSHGSMIHEADER pHeader = vboxSHGSMIBufferHeader(pvBuffer);
+    vboxSHGSMICommandRelease (pHeap, pHeader);
+}
+
+//int VBoxSHGSMISetup (PVBOXSHGSMIHEAP pHeap,
+//                void *pvBase,
+//                HGSMISIZE cbArea,
+//                HGSMIOFFSET offBase,
+//                bool fOffsetBased,
+//                PFNVBOXSHGSMINOTIFYHOST pfnNotifyHost,
+//                PFNVBOXSHGSMINOTIFYHOST pvNotifyHost)
+//{
+//    /* Setup a HGSMI heap within the adapter information area. */
+//    return HGSMIHeapSetup (&pHeap->Heap,
+//                         pvBuffer,
+//                         cbBuffer,
+//                         offBuffer,
+//                         false /*fOffsetBased*/);
+//}
+//
+//int VBoxSHGSMIDestroy (PVBOXSHGSMIHEAP pHeap)
+//{
+//    HGSMIHeapDestroy (pHeap);
+//    return VINF_SUCCESS;
+//}
+
+#define VBOXSHGSMI_CMD2LISTENTRY(_pCmd) ((PVBOXSHGSMILIST_ENTRY)&(_pCmd)->pvNext)
+#define VBOXSHGSMI_LISTENTRY2CMD(_pEntry) ( (PVBOXSHGSMIHEADER)((uint8_t *)(_pEntry) - RT_OFFSETOF(VBOXSHGSMIHEADER, pvNext)) )
+
+int VBoxSHGSMICommandProcessCompletion (struct _HGSMIHEAP * pHeap, HGSMIOFFSET offCmd, bool bIrq, PVBOXSHGSMILIST pPostProcessList)
+{
+    int rc = VINF_SUCCESS;
+
+    PVBOXSHGSMIHEADER pCur = (PVBOXSHGSMIHEADER)HGSMIOffsetToPointer (&pHeap->area, offCmd);
+    Assert(pCur);
+    if (pCur)
+    {
+        do
+        {
+            if (pCur->fFlags & VBOXSHGSMI_FLAG_GH_ASYNCH_CALLBACK_IRQ)
+            {
+                Assert(bIrq);
+
+                PFNVBOXSHGSMICMDCOMPLETION pfnCompletion = NULL;
+                void *pvCompletion;
+                PFNVBOXSHGSMICMDCOMPLETION_IRQ pfnCallback = (PFNVBOXSHGSMICMDCOMPLETION_IRQ)pCur->u64Info1;
+                void *pvCallback = (void*)pCur->u64Info2;
+
+                pfnCallback(pHeap, vboxSHGSMIBufferData(pCur), pvCallback, &pfnCompletion, &pvCompletion);
+                if (pfnCompletion)
+                {
+                    pCur->u64Info1 = (uint64_t)pfnCompletion;
+                    pCur->u64Info2 = (uint64_t)pvCompletion;
+                    pCur->fFlags &= ~VBOXSHGSMI_FLAG_GH_ASYNCH_CALLBACK_IRQ;
+                }
+                else
+                {
+                    /* nothing to do with this command */
+                    break;
+                }
+            }
+
+            if (!bIrq)
+            {
+                PFNVBOXSHGSMICMDCOMPLETION pfnCallback = (PFNVBOXSHGSMICMDCOMPLETION)pCur->u64Info1;
+                void *pvCallback = (void*)pCur->u64Info2;
+                pfnCallback(pHeap, vboxSHGSMIBufferData(pCur), pvCallback);
+            }
+            else
+                vboxSHGSMIListPut(pPostProcessList, VBOXSHGSMI_CMD2LISTENTRY(pCur), VBOXSHGSMI_CMD2LISTENTRY(pCur));
+        } while (0);
+    }
+    else
+    {
+        rc = VERR_INVALID_PARAMETER;
+    }
+
+    return rc;
+}
+
+int VBoxSHGSMICommandPostprocessCompletion (struct _HGSMIHEAP * pHeap, PVBOXSHGSMILIST pPostProcessList)
+{
+    PVBOXSHGSMILIST_ENTRY pNext, pCur;
+    for (pCur = pPostProcessList->pFirst; pCur; pCur = pNext)
+    {
+        /* need to save next since the command may be released in a pfnCallback and thus its data might be invalid */
+        pNext = pCur->pNext;
+        PVBOXSHGSMIHEADER pCmd = VBOXSHGSMI_LISTENTRY2CMD(pCur);
+        PFNVBOXSHGSMICMDCOMPLETION pfnCallback = (PFNVBOXSHGSMICMDCOMPLETION)pCmd->u64Info1;
+        void *pvCallback = (void*)pCmd->u64Info2;
+        pfnCallback(pHeap, pCmd, pvCallback);
+    }
+
+    return VINF_SUCCESS;
+}
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoShgsmi.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoShgsmi.h	(revision 26556)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoShgsmi.h	(revision 26556)
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * 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.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+#ifndef ___VBoxVideoShgsmi_h___
+#define ___VBoxVideoShgsmi_h___
+
+#include <iprt/cdefs.h>
+#include <VBox/VBoxVideo.h>
+
+typedef DECLCALLBACK(void) FNVBOXSHGSMICMDCOMPLETION(struct _HGSMIHEAP * pHeap, void *pvCmd, void *pvContext);
+typedef FNVBOXSHGSMICMDCOMPLETION *PFNVBOXSHGSMICMDCOMPLETION;
+
+typedef DECLCALLBACK(void) FNVBOXSHGSMICMDCOMPLETION_IRQ(struct _HGSMIHEAP * pHeap, void *pvCmd, void *pvContext,
+                                        PFNVBOXSHGSMICMDCOMPLETION *ppfnCompletion, void **ppvCompletion);
+typedef FNVBOXSHGSMICMDCOMPLETION_IRQ *PFNVBOXSHGSMICMDCOMPLETION_IRQ;
+
+typedef struct VBOXSHGSMILIST_ENTRY
+{
+    struct VBOXSHGSMILIST_ENTRY *pNext;
+} VBOXSHGSMILIST_ENTRY, *PVBOXSHGSMILIST_ENTRY;
+
+typedef struct VBOXSHGSMILIST
+{
+    PVBOXSHGSMILIST_ENTRY pFirst;
+    PVBOXSHGSMILIST_ENTRY pLast;
+} VBOXSHGSMILIST, *PVBOXSHGSMILIST;
+
+DECLINLINE(bool) vboxSHGSMIListIsEmpty(PVBOXSHGSMILIST pList)
+{
+    return !pList->pFirst;
+}
+
+DECLINLINE(void) vboxSHGSMIListInit(PVBOXSHGSMILIST pList)
+{
+    pList->pFirst = pList->pLast = NULL;
+}
+
+DECLINLINE(void) vboxSHGSMIListPut(PVBOXSHGSMILIST pList, PVBOXSHGSMILIST_ENTRY pFirst, PVBOXSHGSMILIST_ENTRY pLast)
+{
+    Assert(pFirst);
+    Assert(pLast);
+    if (pList->pLast)
+    {
+        Assert(pList->pFirst);
+        pList->pLast->pNext = pFirst;
+        pList->pLast = pLast;
+        pLast->pNext = NULL;
+    }
+    else
+    {
+        Assert(!pList->pFirst);
+        pList->pFirst = pFirst;
+        pList->pLast = pLast;
+    }
+}
+
+DECLINLINE(void) vboxSHGSMIListCat(PVBOXSHGSMILIST pList1, PVBOXSHGSMILIST pList2)
+{
+    vboxSHGSMIListPut(pList1, pList2->pFirst, pList2->pLast);
+    pList2->pFirst = pList2->pLast = NULL;
+}
+
+DECLINLINE(void) vboxSHGSMICmdListDetach(PVBOXSHGSMILIST pList, PVBOXSHGSMILIST_ENTRY *ppFirst, PVBOXSHGSMILIST_ENTRY *ppLast)
+{
+    *ppFirst = pList->pFirst;
+    if (ppLast)
+        *ppLast = pList->pLast;
+    pList->pFirst = NULL;
+    pList->pLast = NULL;
+}
+
+DECLINLINE(void) vboxSHGSMICmdListDetach2List(PVBOXSHGSMILIST pList, PVBOXSHGSMILIST pDstList)
+{
+    vboxSHGSMICmdListDetach(pList, &pDstList->pFirst, &pDstList->pLast);
+}
+
+void VBoxSHGSMICommandSubmitAsynch (struct _HGSMIHEAP *pHeap, PVOID pvBuff, FNVBOXSHGSMICMDCOMPLETION pfnCompletion, PVOID pvCompletion, uint32_t fFlags);
+void VBoxSHGSMICommandSubmitAsynchIrq (struct _HGSMIHEAP * pHeap, PVOID pvBuff, PFNVBOXSHGSMICMDCOMPLETION_IRQ pfnCompletion, PVOID pvCompletion, uint32_t fFlags);
+void VBoxSHGSMICommandSubmitAsynchEvent (struct _HGSMIHEAP * pHeap, PVOID pvBuff, RTSEMEVENT hEventSem);
+int VBoxSHGSMICommandSubmitSynch (struct _HGSMIHEAP * pHeap, PVOID pCmd);
+int VBoxSHGSMICommandSubmitSynchCompletion (struct _HGSMIHEAP * pHeap, PVOID pCmd);
+void* VBoxSHGSMICommandAlloc (struct _HGSMIHEAP * pHeap, HGSMISIZE cbData, uint8_t u8Channel, uint16_t u16ChannelInfo);
+void VBoxSHGSMICommandFree (struct _HGSMIHEAP * pHeap, void *pvBuffer);
+int VBoxSHGSMICommandProcessCompletion (struct _HGSMIHEAP * pHeap, HGSMIOFFSET offCmd, bool bIrq, PVBOXSHGSMILIST pPostProcessList);
+int VBoxSHGSMICommandPostprocessCompletion (struct _HGSMIHEAP * pHeap, PVBOXSHGSMILIST pPostProcessList);
+
+void vboxSHGSMICbCommandWrite(struct _HGSMIHEAP * pHeap, HGSMIOFFSET data);
+
+#endif /* #ifndef ___VBoxVideoShgsmi_h___ */
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVdma.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVdma.cpp	(revision 26556)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVdma.cpp	(revision 26556)
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * 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.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#include "../VBoxVideo.h"
+#include "../Helper.h"
+
+#include <VBox/VBoxGuestLib.h>
+#include <VBox/VBoxVideo.h>
+#include "VBoxVideoVdma.h"
+#include "../VBoxVideo.h"
+
+/*
+ * This is currently used by VDMA. It is invisible for Vdma API clients since
+ * Vdma transport may change if we choose to use another (e.g. more light-weight)
+ * transport for DMA commands submission
+ */
+
+
+static int vboxVdmaInformHost (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo, uint32_t fFlags)
+{
+    int rc = VINF_SUCCESS;
+
+    PVBOXVDMA_CTL pCmd = (PVBOXVDMA_CTL)VBoxSHGSMICommandAlloc (&pDevExt->u.primary.hgsmiAdapterHeap, sizeof (VBOXVDMA_CTL), HGSMI_CH_VBVA, VBVA_VDMA_CTL);
+    if (pCmd)
+    {
+        pCmd->u32Flags = fFlags;
+        pCmd->u32Offset = pInfo->CmdHeap.area.offBase;
+        pCmd->i32Result = VERR_NOT_SUPPORTED;
+
+        VBoxSHGSMICommandSubmitSynch (&pDevExt->u.primary.hgsmiAdapterHeap, pCmd);
+
+        rc = pCmd->i32Result;
+        AssertRC(rc);
+
+        VBoxSHGSMICommandFree (&pDevExt->u.primary.hgsmiAdapterHeap, pCmd);
+    }
+    else
+    {
+        drprintf((__FUNCTION__": HGSMIHeapAlloc failed\n"));
+        rc = VERR_GENERAL_FAILURE;
+    }
+
+    return rc;
+}
+
+/* create a DMACommand buffer */
+int vboxVdmaCreate (PDEVICE_EXTENSION pDevExt, VBOXVDMAINFO *pInfo, ULONG offBuffer, ULONG cbBuffer)
+{
+    Assert((offBuffer & 0xfff) == 0);
+    Assert((cbBuffer & 0xfff) == 0);
+    Assert(offBuffer);
+    Assert(cbBuffer);
+
+    if((offBuffer & 0xfff)
+            || (cbBuffer & 0xfff)
+            || !offBuffer
+            || !cbBuffer)
+    {
+        drprintf((__FUNCTION__": invalid parameters: offBuffer(0x%x), cbBuffer(0x%x)", offBuffer, cbBuffer));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    pInfo->fEnabled           = FALSE;
+    PVOID pvBuffer;
+
+    int rc = VBoxMapAdapterMemory (pDevExt,
+                                   &pvBuffer,
+                                   offBuffer,
+                                   cbBuffer);
+    Assert(RT_SUCCESS(rc));
+    if (RT_SUCCESS(rc))
+    {
+        /* Setup a HGSMI heap within the adapter information area. */
+        rc = HGSMIHeapSetup (&pInfo->CmdHeap,
+                             pvBuffer,
+                             cbBuffer,
+                             offBuffer,
+                             false /*fOffsetBased*/);
+        Assert(RT_SUCCESS(rc));
+        if(RT_SUCCESS(rc))
+            return rc;
+        else
+            drprintf((__FUNCTION__": HGSMIHeapSetup failed rc = 0x%x\n", rc));
+
+        VBoxUnmapAdapterMemory(pDevExt, &pvBuffer, cbBuffer);
+    }
+    else
+        drprintf((__FUNCTION__": VBoxMapAdapterMemory failed rc = 0x%x\n", rc));
+
+    return rc;
+}
+
+int vboxVdmaDisable (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo)
+{
+    dfprintf((__FUNCTION__"\n"));
+
+    Assert(pInfo->fEnabled);
+    if (!pInfo->fEnabled)
+        return VINF_ALREADY_INITIALIZED;
+
+    /* ensure nothing else is submitted */
+    pInfo->fEnabled        = FALSE;
+
+    int rc = vboxVdmaInformHost (pDevExt, pInfo, VBOXVDMA_CTL_DISABLE);
+    AssertRC(rc);
+    return rc;
+}
+
+int vboxVdmaEnable (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo)
+{
+    dfprintf((__FUNCTION__"\n"));
+
+    Assert(!pInfo->fEnabled);
+    if (pInfo->fEnabled)
+        return VINF_ALREADY_INITIALIZED;
+
+    int rc = vboxVdmaInformHost (pDevExt, pInfo, VBOXVDMA_CTL_ENABLE);
+    Assert(RT_SUCCESS(rc));
+    if (RT_SUCCESS(rc))
+        pInfo->fEnabled        = TRUE;
+
+    return rc;
+}
+
+int vboxVdmaFlush (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo)
+{
+    dfprintf((__FUNCTION__"\n"));
+
+    Assert(pInfo->fEnabled);
+    if (!pInfo->fEnabled)
+        return VINF_ALREADY_INITIALIZED;
+
+    int rc = vboxVdmaInformHost (pDevExt, pInfo, VBOXVDMA_CTL_FLUSH);
+    Assert(RT_SUCCESS(rc));
+
+    return rc;
+}
+
+int vboxVdmaDestroy (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo)
+{
+    int rc = VINF_SUCCESS;
+    Assert(!pInfo->fEnabled);
+    if (pInfo->fEnabled)
+        rc = vboxVdmaDisable (pDevExt, pInfo);
+    VBoxUnmapAdapterMemory (pDevExt, (void**)&pInfo->CmdHeap.area.pu8Base, pInfo->CmdHeap.area.cbArea);
+    return rc;
+}
+
+void vboxVdmaCBufDrFree (PVBOXVDMAINFO pInfo, PVBOXVDMACBUF_DR pDr)
+{
+    VBoxSHGSMICommandFree (&pInfo->CmdHeap, pDr);
+}
+
+PVBOXVDMACBUF_DR vboxVdmaCBufDrCreate (PVBOXVDMAINFO pInfo, PVBOXVDMACMDBUF_INFO pBufInfo, uint32_t u32FenceId)
+{
+    PVBOXVDMACBUF_DR pCmdDr;
+
+    if (pBufInfo->fFlags & VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR)
+    {
+        /* data info is a pointer to the buffer to be coppied and included in the command */
+        pCmdDr = (PVBOXVDMACBUF_DR)VBoxSHGSMICommandAlloc (&pInfo->CmdHeap, sizeof (VBOXVDMACBUF_DR) + pBufInfo->cbBuf, HGSMI_CH_VBVA, VBVA_VDMA_CMD);
+        Assert(pCmdDr);
+        if (!pCmdDr)
+            return NULL;
+
+        void * pvData = VBOXVDMACBUF_DR_TAIL(pCmdDr, void*);
+        memcpy(pvData, (void*)pBufInfo->Location.pvBuf, pBufInfo->cbBuf);
+    }
+    else
+    {
+        pCmdDr = (PVBOXVDMACBUF_DR)VBoxSHGSMICommandAlloc (&pInfo->CmdHeap, sizeof (VBOXVDMACBUF_DR), HGSMI_CH_VBVA, VBVA_VDMA_CMD);
+        Assert(pCmdDr);
+        if (!pCmdDr)
+            return NULL;
+
+        if (!(pBufInfo->fFlags & VBOXVDMACBUF_FLAG_BUF_VRAM_OFFSET))
+            pCmdDr->phBuf = pBufInfo->Location.phBuf;
+        else
+            pCmdDr->phBuf = pBufInfo->Location.offVramBuf;
+    }
+
+    pCmdDr->fFlags = pBufInfo->fFlags;
+    pCmdDr->cbBuf = pBufInfo->cbBuf;
+    pCmdDr->u32FenceId = u32FenceId;
+
+    return pCmdDr;
+}
+
+static DECLCALLBACK(void) vboxVdmaCBufDrCompletion(struct _HGSMIHEAP * pHeap, void *pvCmd, void *pvContext)
+{
+    PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pvContext;
+    PVBOXVDMAINFO pInfo = &pDevExt->u.primary.Vdma;
+
+    vboxVdmaCBufDrFree (pInfo, (PVBOXVDMACBUF_DR)pvCmd);
+}
+
+static DECLCALLBACK(void) vboxVdmaCBufDrCompletionIrq(struct _HGSMIHEAP * pHeap, void *pvCmd, void *pvContext,
+                                        PFNVBOXSHGSMICMDCOMPLETION *ppfnCompletion, void **ppvCompletion)
+{
+    PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pvContext;
+    PVBOXVDMAINFO pVdma = &pDevExt->u.primary.Vdma;
+    DXGKARGCB_NOTIFY_INTERRUPT_DATA notify;
+    PVBOXVDMACBUF_DR pDr = (PVBOXVDMACBUF_DR)pvCmd;
+
+    memset(&notify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
+
+    if (RT_SUCCESS(pDr->rc))
+    {
+        notify.InterruptType = DXGK_INTERRUPT_DMA_COMPLETED;
+        notify.DmaCompleted.SubmissionFenceId = pDr->u32FenceId;
+        notify.DmaCompleted.NodeOrdinal = 0; /* @todo: ? */
+        notify.DmaCompleted.EngineOrdinal = 0; /* @todo: ? */
+        pVdma->uLastCompletedCmdFenceId = pDr->u32FenceId;
+        pDevExt->bSetNotifyDxDpc = TRUE;
+    }
+    else if (pDr->rc == VERR_INTERRUPTED)
+    {
+        notify.InterruptType = DXGK_INTERRUPT_DMA_PREEMPTED;
+        notify.DmaPreempted.PreemptionFenceId = pDr->u32FenceId;
+        notify.DmaPreempted.LastCompletedFenceId = pVdma->uLastCompletedCmdFenceId;
+        notify.DmaPreempted.NodeOrdinal = 0; /* @todo: ? */
+        notify.DmaPreempted.EngineOrdinal = 0; /* @todo: ? */
+        pDevExt->bSetNotifyDxDpc = TRUE;
+    }
+    else
+    {
+        AssertBreakpoint();
+        notify.InterruptType = DXGK_INTERRUPT_DMA_FAULTED;
+        notify.DmaFaulted.FaultedFenceId = pDr->u32FenceId;
+        notify.DmaFaulted.Status = STATUS_UNSUCCESSFUL; /* @todo: better status ? */
+        notify.DmaFaulted.NodeOrdinal = 0; /* @todo: ? */
+        notify.DmaFaulted.EngineOrdinal = 0; /* @todo: ? */
+        pDevExt->bSetNotifyDxDpc = TRUE;
+    }
+
+    pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, &notify);
+
+    /* inform SHGSMI we want to be called at DPC later */
+    *ppfnCompletion = vboxVdmaCBufDrCompletion;
+    *ppvCompletion = pvContext;
+}
+
+void vboxVdmaCBufDrSubmit (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo, PVBOXVDMACBUF_DR pDr)
+{
+    VBoxSHGSMICommandSubmitAsynchIrq (&pInfo->CmdHeap, pDr, vboxVdmaCBufDrCompletionIrq, pDevExt, 0);
+}
+
+int vboxVdmaCBufSubmit (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo, PVBOXVDMACMDBUF_INFO pBufInfo, uint32_t u32FenceId)
+{
+    dfprintf((__FUNCTION__"\n"));
+
+    PVBOXVDMACBUF_DR pdr = vboxVdmaCBufDrCreate (pInfo, pBufInfo, u32FenceId);
+    if (!pdr)
+        return VERR_OUT_OF_RESOURCES;
+
+    vboxVdmaCBufDrSubmit (pDevExt, pInfo, pdr);
+
+    return VINF_SUCCESS;
+}
+
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVdma.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVdma.h	(revision 26556)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVdma.h	(revision 26556)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * 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.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+#ifndef ___VBoxVideoVdma_h___
+#define ___VBoxVideoVdma_h___
+
+#include <iprt/cdefs.h>
+#include <VBox/VBoxVideo.h>
+
+/* DMA commands are currently submitted over HGSMI */
+typedef struct VBOXVDMAINFO
+{
+    HGSMIHEAP CmdHeap;
+    UINT      uLastCompletedCmdFenceId;
+    BOOL      fEnabled;
+} VBOXVDMAINFO, *PVBOXVDMAINFO;
+
+typedef struct VBOXVDMACMDBUF_INFO
+{
+    uint32_t fFlags;
+    uint32_t cbBuf;
+    union
+    {
+        RTGCPHYS phBuf;
+        ULONG offVramBuf;
+        void *pvBuf;
+    } Location;
+} VBOXVDMACMDBUF_INFO, *PVBOXVDMACMDBUF_INFO;
+
+int vboxVdmaCreate (struct _DEVICE_EXTENSION* pDevExt, VBOXVDMAINFO *pInfo, ULONG offBuffer, ULONG cbBuffer);
+int vboxVdmaDisable (struct _DEVICE_EXTENSION* pDevExt, PVBOXVDMAINFO pInfo);
+int vboxVdmaEnable (struct _DEVICE_EXTENSION* pDevExt, PVBOXVDMAINFO pInfo);
+int vboxVdmaFlush (struct _DEVICE_EXTENSION* pDevExt, PVBOXVDMAINFO pInfo);
+int vboxVdmaDestroy (struct _DEVICE_EXTENSION* pDevExt, PVBOXVDMAINFO pInfo);
+int vboxVdmaCBufSubmit (struct _DEVICE_EXTENSION* pDevExt, PVBOXVDMAINFO pInfo, PVBOXVDMACMDBUF_INFO pBufInfo, uint32_t u32FenceId);
+
+#endif /* #ifndef ___VBoxVideoVdma_h___ */
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVidPn.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVidPn.cpp	(revision 26555)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVidPn.cpp	(revision 26556)
@@ -508,5 +508,5 @@
     pNewVidPnTargetModeInfo->VideoSignalInfo.VSyncFreq.Numerator = 60000;
     pNewVidPnTargetModeInfo->VideoSignalInfo.VSyncFreq.Denominator = 1000;
-    pNewVidPnTargetModeInfo->VideoSignalInfo.HSyncFreq.Numerator = pNewVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cy * 60 * 1.05;
+    pNewVidPnTargetModeInfo->VideoSignalInfo.HSyncFreq.Numerator = pNewVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cy * 63; /* 63 is (60 * 1.05)*/
     pNewVidPnTargetModeInfo->VideoSignalInfo.HSyncFreq.Denominator = 1;
     pNewVidPnTargetModeInfo->VideoSignalInfo.PixelRate = 165000; /* @todo: ? */
@@ -543,5 +543,5 @@
                 if (Status == STATUS_SUCCESS)
                 {
-                    if (iPreferredMomde == i)
+                    if (bPreferred)
                     {
                         Status = pNewVidPnTargetModeSetInterface->pfnPinMode(hNewVidPnTargetModeSet, modeId);
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp	(revision 26555)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp	(revision 26556)
@@ -39,4 +39,266 @@
     ExFreePool(pvMem);
 }
+
+void vboxSHGSMICbCommandWrite(struct _HGSMIHEAP * pHeap, HGSMIOFFSET data)
+{
+    /* @todo: this should be taken from PDEVICE_EXTENSION */
+    //VBoxHGSMIGuestWrite(pDevExt, data);
+    VBoxVideoCmnPortWriteUlong((PULONG)VGA_PORT_HGSMI_GUEST, data);
+}
+
+#if 0
+void vboxWddmProcessDisplayInfo (PPDEV ppdev)
+{
+    if (ppdev->bHGSMISupported)
+    {
+        /* Issue the screen info command. */
+        void *p = HGSMIHeapAlloc (&ppdev->hgsmiDisplayHeap,
+                                  sizeof (VBVAINFOSCREEN),
+                                  HGSMI_CH_VBVA,
+                                  VBVA_INFO_SCREEN);
+        if (!p)
+        {
+            DISPDBG((0, "VBoxDISP::VBoxProcessDisplayInfo: HGSMIHeapAlloc failed\n"));
+        }
+        else
+        {
+            VBVAINFOSCREEN *pScreen = (VBVAINFOSCREEN *)p;
+
+            pScreen->u32ViewIndex    = ppdev->iDevice;
+            pScreen->i32OriginX      = ppdev->ptlDevOrg.x;
+            pScreen->i32OriginY      = ppdev->ptlDevOrg.y;
+            pScreen->u32StartOffset  = 0;
+            pScreen->u32LineSize     = ppdev->lDeltaScreen > 0?ppdev->lDeltaScreen: -ppdev->lDeltaScreen;
+            pScreen->u32Width        = ppdev->cxScreen;
+            pScreen->u32Height       = ppdev->cyScreen;
+            pScreen->u16BitsPerPixel = (uint16_t)ppdev->ulBitCount;
+            pScreen->u16Flags        = VBVA_SCREEN_F_ACTIVE;
+
+            vboxHGSMIBufferSubmit (ppdev, p);
+
+            HGSMIHeapFree (&ppdev->hgsmiDisplayHeap, p);
+        }
+    }
+
+    return;
+}
+
+NTSTATUS vboxWddmGhInitPrimary(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, D3DKMDT_VIDPN_SOURCE_MODE *pVidPnSourceModeInfo)
+{
+    NTSTATUS Status;
+    PVBOXWDDM_SOURCE pSourceInfo = &pDevExt->aSources[srcId];
+    memset(pSourceInfo, 0, sizeof (VBOXWDDM_SOURCE));
+    pSourceInfo->VisScreenWidth = pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx;
+    pSourceInfo->VisScreenHeight = pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy;
+    pSourceInfo->BitsPerPlane = vboxWddmCalcBitsPerPixel(pVidPnSourceModeInfo->Format.Graphics.PixelFormat);
+    Assert(pSourceInfo->BitsPerPlane);
+    if (pSourceInfo->BitsPerPlane)
+    {
+        /*
+         * Set the current mode into the hardware.
+         */
+        if (VBoxVideoSetCurrentMode(pDevExt, srcId, pSourceInfo))
+        {
+
+
+        }
+        else
+        {
+            AssertBreakpoint();
+
+        }
+    }
+    else
+    {
+        drprintf((__FUNCTION__":ERROR: failed to caltulate bpp from pixel format (%d)\n",
+                pVidPnSourceModeInfo->Format.Graphics.PixelFormat));
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    return Status;
+
+
+
+//    DWORD returnedDataLength;
+//    DWORD MaxWidth, MaxHeight;
+//    VIDEO_MEMORY videoMemory;
+//    VIDEO_MEMORY_INFORMATION videoMemoryInformation;
+//    ULONG RemappingNeeded = 0;
+
+
+    /*
+     * don't need to map anything here, we use one common HGSMI heap for all sources
+     */
+
+    // If this is the first time we enable the surface we need to map in the
+    // memory also.
+    //
+
+    if (bFirst || RemappingNeeded)
+    {
+//        videoMemory.RequestedVirtualAddress = NULL;
+//
+//        if (EngDeviceIoControl(ppdev->hDriver,
+//                               IOCTL_VIDEO_MAP_VIDEO_MEMORY,
+//                               &videoMemory,
+//                               sizeof(VIDEO_MEMORY),
+//                               &videoMemoryInformation,
+//                               sizeof(VIDEO_MEMORY_INFORMATION),
+//                               &returnedDataLength))
+//        {
+//            DISPDBG((1, "DISP bInitSURF failed IOCTL_VIDEO_MAP\n"));
+//            return(FALSE);
+//        }
+//
+//        ppdev->pjScreen = (PBYTE)(videoMemoryInformation.FrameBufferBase);
+//
+//        if (videoMemoryInformation.FrameBufferBase !=
+//            videoMemoryInformation.VideoRamBase)
+//        {
+//            DISPDBG((0, "VideoRamBase does not correspond to FrameBufferBase\n"));
+//        }
+//
+//        //
+//        // Make sure we can access this video memory
+//        //
+//
+//        *(PULONG)(ppdev->pjScreen) = 0xaa55aa55;
+//
+//        if (*(PULONG)(ppdev->pjScreen) != 0xaa55aa55) {
+//
+//            DISPDBG((1, "Frame buffer memory is not accessible.\n"));
+//            return(FALSE);
+//        }
+//
+//        /* Clear VRAM to avoid distortions during the video mode change. */
+//        RtlZeroMemory(ppdev->pjScreen,
+//                      ppdev->cyScreen * (ppdev->lDeltaScreen > 0? ppdev->lDeltaScreen: -ppdev->lDeltaScreen));
+//
+//        //
+//        // Initialize the head of the offscreen list to NULL.
+//        //
+//
+//        ppdev->pOffscreenList = NULL;
+//
+//        // It's a hardware pointer; set up pointer attributes.
+//
+//        MaxHeight = ppdev->PointerCapabilities.MaxHeight;
+//
+//        // Allocate space for two DIBs (data/mask) for the pointer. If this
+//        // device supports a color Pointer, we will allocate a larger bitmap.
+//        // If this is a color bitmap we allocate for the largest possible
+//        // bitmap because we have no idea of what the pixel depth might be.
+//
+//        // Width rounded up to nearest byte multiple
+//
+//        if (!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER))
+//        {
+//            MaxWidth = (ppdev->PointerCapabilities.MaxWidth + 7) / 8;
+//        }
+//        else
+//        {
+//            MaxWidth = ppdev->PointerCapabilities.MaxWidth * sizeof(DWORD);
+//        }
+//
+//        ppdev->cjPointerAttributes =
+//                sizeof(VIDEO_POINTER_ATTRIBUTES) +
+//                ((sizeof(UCHAR) * MaxWidth * MaxHeight) * 2);
+//
+//        ppdev->pPointerAttributes = (PVIDEO_POINTER_ATTRIBUTES)
+//                EngAllocMem(0, ppdev->cjPointerAttributes, ALLOC_TAG);
+//
+//        if (ppdev->pPointerAttributes == NULL) {
+//
+//            DISPDBG((0, "bInitPointer EngAllocMem failed\n"));
+//            return(FALSE);
+//        }
+//
+//        ppdev->pPointerAttributes->Flags = ppdev->PointerCapabilities.Flags;
+//        ppdev->pPointerAttributes->WidthInBytes = MaxWidth;
+//        ppdev->pPointerAttributes->Width = ppdev->PointerCapabilities.MaxWidth;
+//        ppdev->pPointerAttributes->Height = MaxHeight;
+//        ppdev->pPointerAttributes->Column = 0;
+//        ppdev->pPointerAttributes->Row = 0;
+//        ppdev->pPointerAttributes->Enable = 0;
+
+        vboxInitVBoxVideo (ppdev, &videoMemoryInformation);
+
+#ifndef VBOX_WITH_HGSMI
+        if (ppdev->bVBoxVideoSupported)
+        {
+            /* Setup the display information. */
+            vboxSetupDisplayInfo (ppdev, &videoMemoryInformation);
+        }
+#endif /* !VBOX_WITH_HGSMI */
+    }
+
+
+    DISPDBG((1, "DISP bInitSURF: ppdev->ulBitCount %d\n", ppdev->ulBitCount));
+
+    if (   ppdev->ulBitCount == 16
+        || ppdev->ulBitCount == 24
+        || ppdev->ulBitCount == 32)
+    {
+#ifndef VBOX_WITH_HGSMI
+        if (ppdev->pInfo) /* Do not use VBVA on old hosts. */
+        {
+            /* Enable VBVA for this video mode. */
+            vboxVbvaEnable (ppdev);
+        }
+#else
+        if (ppdev->bHGSMISupported)
+        {
+            /* Enable VBVA for this video mode. */
+            ppdev->bHGSMISupported = vboxVbvaEnable (ppdev);
+            LogRel(("VBoxDisp[%d]: VBVA %senabled\n", ppdev->iDevice, ppdev->bHGSMISupported? "": "not "));
+        }
+#endif /* VBOX_WITH_HGSMI */
+    }
+
+    DISPDBG((1, "DISP bInitSURF success\n"));
+
+#ifndef VBOX_WITH_HGSMI
+    /* Update the display information. */
+    vboxUpdateDisplayInfo (ppdev);
+#else
+    /* Inform the host about this screen layout. */
+    DISPDBG((1, "bInitSURF: %d,%d\n", ppdev->ptlDevOrg.x, ppdev->ptlDevOrg.y));
+    VBoxProcessDisplayInfo (ppdev);
+#endif /* VBOX_WITH_HGSMI */
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    /* tells we can process host commands */
+    vboxVHWAEnable(ppdev);
+#endif
+
+    return(TRUE);
+}
+#endif
+
+HGSMIHEAP* vboxWddmHgsmiGetHeapFromCmdOffset(PDEVICE_EXTENSION pDevExt, HGSMIOFFSET offCmd)
+{
+    if(HGSMIAreaContainsOffset(&pDevExt->u.primary.Vdma.CmdHeap.area, offCmd))
+        return &pDevExt->u.primary.Vdma.CmdHeap;
+    if (HGSMIAreaContainsOffset(&pDevExt->u.primary.hgsmiAdapterHeap.area, offCmd))
+        return &pDevExt->u.primary.hgsmiAdapterHeap;
+    return NULL;
+}
+
+typedef enum
+{
+    VBOXWDDM_HGSMICMD_TYPE_UNDEFINED = 0,
+    VBOXWDDM_HGSMICMD_TYPE_CTL       = 1,
+    VBOXWDDM_HGSMICMD_TYPE_DMACMD    = 2
+} VBOXWDDM_HGSMICMD_TYPE;
+
+VBOXWDDM_HGSMICMD_TYPE vboxWddmHgsmiGetCmdTypeFromOffset(PDEVICE_EXTENSION pDevExt, HGSMIOFFSET offCmd)
+{
+    if(HGSMIAreaContainsOffset(&pDevExt->u.primary.Vdma.CmdHeap.area, offCmd))
+        return VBOXWDDM_HGSMICMD_TYPE_DMACMD;
+    if (HGSMIAreaContainsOffset(&pDevExt->u.primary.hgsmiAdapterHeap.area, offCmd))
+        return VBOXWDDM_HGSMICMD_TYPE_CTL;
+    return VBOXWDDM_HGSMICMD_TYPE_UNDEFINED;
+}
+
 
 #define VBOXWDDM_REG_DRVKEY_PREFIX L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\"
@@ -491,5 +753,105 @@
     )
 {
-    return false;
+    PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)MiniportDeviceContext;
+    BOOLEAN bOur = FALSE;
+    if (pDevExt->u.primary.pHostFlags) /* If HGSMI is enabled at all. */
+    {
+        VBOXSHGSMILIST CtlList;
+        VBOXSHGSMILIST DmaCmdList;
+        vboxSHGSMIListInit(&CtlList);
+        vboxSHGSMIListInit(&DmaCmdList);
+        do
+        {
+            uint32_t flags = pDevExt->u.primary.pHostFlags->u32HostFlags;
+            if (flags & HGSMIHOSTFLAGS_GCOMMAND_COMPLETED)
+            {
+                bOur = TRUE;
+                /* read the command offset */
+                HGSMIOFFSET offCmd = VBoxHGSMIGuestRead(pDevExt);
+                Assert(offCmd != HGSMIOFFSET_VOID);
+                if (offCmd != HGSMIOFFSET_VOID)
+                {
+                    VBOXWDDM_HGSMICMD_TYPE enmType = vboxWddmHgsmiGetCmdTypeFromOffset(pDevExt, offCmd);
+                    PVBOXSHGSMILIST pList;
+                    HGSMIHEAP * pHeap = NULL;
+                    switch (enmType)
+                    {
+                        case VBOXWDDM_HGSMICMD_TYPE_DMACMD:
+                            pList = &DmaCmdList;
+                            pHeap = &pDevExt->u.primary.Vdma.CmdHeap;
+                            break;
+                        case VBOXWDDM_HGSMICMD_TYPE_CTL:
+                            pList = &CtlList;
+                            pHeap = &pDevExt->u.primary.hgsmiAdapterHeap;
+                            break;
+                        default:
+                            AssertBreakpoint();
+                    }
+
+                    if (pHeap)
+                    {
+                        int rc = VBoxSHGSMICommandProcessCompletion (pHeap, offCmd, TRUE /*bool bIrq*/ , pList);
+                        AssertRC(rc);
+                    }
+                }
+            }
+            else if (flags & HGSMIHOSTFLAGS_COMMANDS_PENDING)
+            {
+                bOur = TRUE;
+                AssertBreakpoint();
+                /* @todo: FIXME: implement !!! */
+            }
+            else if (flags & HGSMIHOSTFLAGS_IRQ)
+            {
+                bOur = TRUE;
+                AssertBreakpoint();
+                /* unknown command */
+            }
+            else
+                break;
+        } while (1);
+
+        if (!vboxSHGSMIListIsEmpty(&CtlList))
+            vboxSHGSMIListCat(&pDevExt->CtlList, &CtlList);
+
+        if (!vboxSHGSMIListIsEmpty(&DmaCmdList))
+            vboxSHGSMIListCat(&pDevExt->DmaCmdList, &DmaCmdList);
+
+        if (pDevExt->bSetNotifyDxDpc)
+        {
+            pDevExt->bNotifyDxDpc = TRUE;
+            pDevExt->bSetNotifyDxDpc = FALSE;
+        }
+
+        if (bOur)
+            HGSMIClearIrq (pDevExt);
+    }
+
+    return bOur;
+}
+
+
+typedef struct VBOXWDDM_DPCDATA
+{
+    VBOXSHGSMILIST CtlList;
+    VBOXSHGSMILIST DmaCmdList;
+    BOOL bNotifyDpc;
+} VBOXWDDM_DPCDATA, *PVBOXWDDM_DPCDATA;
+
+typedef struct VBOXWDDM_GETDPCDATA_CONTEXT
+{
+    PDEVICE_EXTENSION pDevExt;
+    VBOXWDDM_DPCDATA data;
+} VBOXWDDM_GETDPCDATA_CONTEXT, *PVBOXWDDM_GETDPCDATA_CONTEXT;
+
+BOOLEAN vboxWddmGetDPCDataCallback(PVOID Context)
+{
+    PVBOXWDDM_GETDPCDATA_CONTEXT pdc = (PVBOXWDDM_GETDPCDATA_CONTEXT)Context;
+
+    vboxSHGSMICmdListDetach2List(&pdc->pDevExt->CtlList, &pdc->data.CtlList);
+    vboxSHGSMICmdListDetach2List(&pdc->pDevExt->DmaCmdList, &pdc->data.DmaCmdList);
+    pdc->data.bNotifyDpc = pdc->pDevExt->bNotifyDxDpc;
+    pdc->pDevExt->bNotifyDxDpc = FALSE;
+    return TRUE;
 }
 
@@ -498,5 +860,32 @@
     )
 {
-
+    PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)MiniportDeviceContext;
+
+    VBOXWDDM_DPCDATA dpcData = {0};
+    BOOLEAN bRet;
+
+    /* get DPC data at IRQL */
+    NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution(
+            pDevExt->u.primary.DxgkInterface.DeviceHandle,
+            vboxWddmGetDPCDataCallback,
+            &dpcData,
+            0,
+            &bRet);
+    Assert(Status == STATUS_SUCCESS);
+
+    if (!vboxSHGSMIListIsEmpty(&dpcData.CtlList))
+    {
+        int rc = VBoxSHGSMICommandPostprocessCompletion (&pDevExt->u.primary.hgsmiAdapterHeap, &dpcData.CtlList);
+        AssertRC(rc);
+    }
+
+    if (!vboxSHGSMIListIsEmpty(&dpcData.DmaCmdList))
+    {
+        int rc = VBoxSHGSMICommandPostprocessCompletion (&pDevExt->u.primary.Vdma.CmdHeap, &dpcData.DmaCmdList);
+        AssertRC(rc);
+    }
+
+    if (dpcData.bNotifyDpc)
+        pDevExt->u.primary.DxgkInterface.DxgkCbNotifyDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
 }
 
@@ -976,4 +1365,7 @@
 }
 
+/**
+ *
+ */
 NTSTATUS
 APIENTRY
@@ -1507,5 +1899,11 @@
             VBOXVIDPNCOFUNCMODALITY CbContext = {0};
             CbContext.pEnumCofuncModalityArg = pEnumCofuncModalityArg;
-            VBoxWddmGetModesTable(pContext, true, &CbContext.pModes, &CbContext.cModes, &CbContext.iPreferredMode, &CbContext.cResolutions, &CbContext.pResolutions);
+            VBoxWddmGetModesTable(pContext, /* PDEVICE_EXTENSION DeviceExtension */
+                    true, /* bool bRebuildTable*/
+                    &CbContext.pModes, /* VIDEO_MODE_INFORMATION ** ppModes*/
+                    &CbContext.cModes, /* uint32_t * pcModes */
+                    &CbContext.iPreferredMode, /* uint32_t * pPreferrableMode*/
+                    &CbContext.pResolutions, /* D3DKMDT_2DREGION **ppResolutions */
+                    &CbContext.cResolutions /* uint32_t * pcResolutions */);
             Assert(CbContext.cModes);
             Assert(CbContext.cModes > CbContext.iPreferredMode);
Index: /trunk/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp	(revision 26555)
+++ /trunk/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp	(revision 26556)
@@ -152,4 +152,7 @@
     HGSMILIST hostFIFOProcessed;       /* Processed by the guest. */
     HGSMILIST hostFIFOFree;            /* Buffers for reuse. */
+#ifdef VBOXVDMA
+    HGSMILIST guestCmdCompleted;       /* list of completed guest commands to be returned to the guest*/
+#endif
     RTCRITSECT    hostFIFOCritSect;    /* FIFO serialization lock. */
 
@@ -198,4 +201,5 @@
 #define HGSMILISTENTRY_2_FIFOENTRY(_pe) \
     ( (HGSMIHOSTFIFOENTRY*)((uint8_t *)(_pe) - RT_OFFSETOF(HGSMIHOSTFIFOENTRY, entry)) )
+
 //AssertCompile(RT_OFFSETOF(HGSMIHOSTFIFOENTRY, entry) == 0);
 
@@ -209,4 +213,41 @@
 
 static DECLCALLBACK(void) hgsmiHostCommandFreeCallback (void *pvCallback);
+
+#ifdef VBOXVDMA
+
+typedef struct _HGSMIGUESTCOMPLENTRY
+{
+    /* The list field. Must be the first field. */
+    HGSMILISTENTRY entry;
+    /* guest command buffer */
+    HGSMIOFFSET offBuffer;
+} HGSMIGUESTCOMPLENTRY;
+
+#define HGSMILISTENTRY_2_HGSMIGUESTCOMPLENTRY(_pe) \
+    ( (HGSMIGUESTCOMPLENTRY*)((uint8_t *)(_pe) - RT_OFFSETOF(HGSMIGUESTCOMPLENTRY, entry)) )
+
+static void hgsmiGuestCompletionFIFOFree (HGSMIINSTANCE *pIns, HGSMIGUESTCOMPLENTRY *pEntry)
+{
+    NOREF (pIns);
+    RTMemFree (pEntry);
+}
+
+static int hgsmiGuestCompletionFIFOAlloc (HGSMIINSTANCE *pIns, HGSMIGUESTCOMPLENTRY **ppEntry)
+{
+    int rc = VINF_SUCCESS;
+
+    NOREF (pIns);
+
+    HGSMIGUESTCOMPLENTRY *pEntry = (HGSMIGUESTCOMPLENTRY *)RTMemAllocZ (sizeof (HGSMIGUESTCOMPLENTRY));
+
+    if (pEntry)
+        *ppEntry = pEntry;
+    else
+        rc = VERR_NO_MEMORY;
+
+    return rc;
+}
+
+#endif
 
 static int hgsmiLock (HGSMIINSTANCE *pIns)
@@ -341,8 +382,40 @@
     VM_ASSERT_EMT(pIns->pVM);
 
+#ifndef VBOXVDMA
     /* Currently there is no functionality here. */
     NOREF(pIns);
 
     return HGSMIOFFSET_VOID;
+#else
+    /* use this to speedup guest cmd completion
+     * this mechanism is alternative to submitting H->G command for notification */
+    HGSMIOFFSET offCmd = HGSMIOFFSET_VOID;
+    int rc = hgsmiFIFOLock(pIns);
+    AssertRC(rc);
+    if(RT_SUCCESS(rc))
+    {
+        /* Get the host FIFO head entry. */
+        HGSMILISTENTRY *pHead = pIns->guestCmdCompleted.pHead;
+        if(pHead)
+            hgsmiListRemove (&pIns->guestCmdCompleted, pHead, NULL);
+
+        if(!pIns->guestCmdCompleted.pHead)
+            pIns->pHGFlags->u32HostFlags &= (~HGSMIHOSTFLAGS_GCOMMAND_COMPLETED);
+
+        hgsmiFIFOUnlock(pIns);
+
+        if (pHead)
+        {
+            HGSMIGUESTCOMPLENTRY *pEntry = HGSMILISTENTRY_2_HGSMIGUESTCOMPLENTRY(pHead);
+            offCmd = pEntry->offBuffer;
+
+            LogFlowFunc(("host FIFO head %p.\n", pEntry));
+
+            hgsmiGuestCompletionFIFOFree (pIns, pEntry);
+        }
+    }
+    /* Special value that means there is no host buffers to be processed. */
+    return offCmd;
+#endif
 }
 
@@ -1596,2 +1669,75 @@
     LogFlowFunc(("leave\n"));
 }
+
+#ifdef VBOXVDMA
+
+static int hgsmiGuestCommandComplete (HGSMIINSTANCE *pIns, HGSMIOFFSET offMem)
+{
+    HGSMIGUESTCOMPLENTRY *pEntry;
+
+    int rc = hgsmiGuestCompletionFIFOAlloc (pIns, &pEntry);
+
+    if (RT_SUCCESS (rc))
+    {
+        pEntry->offBuffer = offMem;
+
+        rc = hgsmiFIFOLock(pIns);
+        if (RT_SUCCESS (rc))
+        {
+            hgsmiListAppend (&pIns->guestCmdCompleted, &pEntry->entry);
+            pIns->pHGFlags->u32HostFlags |= HGSMIHOSTFLAGS_GCOMMAND_COMPLETED;
+
+            hgsmiFIFOUnlock(pIns);
+        }
+        else
+        {
+            hgsmiGuestCompletionFIFOFree(pIns, pEntry);
+        }
+    }
+
+    return rc;
+}
+
+int hgsmiCompleteGuestCommand(PHGSMIINSTANCE pIns,
+        HGSMIOFFSET offBuffer,
+        bool bDoIrq)
+{
+    int rc = hgsmiGuestCommandComplete (pIns, offBuffer);
+    if (RT_SUCCESS (rc))
+    {
+        if(bDoIrq)
+        {
+            /* Now guest can read the FIFO, the notification is informational. */
+            hgsmiNotifyGuest (pIns);
+        }
+    }
+    return rc;
+}
+
+int HGSMICompleteGuestCommand(PHGSMIINSTANCE pIns,
+        void *pvMem,
+        bool bDoIrq)
+{
+    LogFlowFunc(("pIns = %p, pvMem = %p\n", pIns, pvMem));
+
+    VM_ASSERT_OTHER_THREAD(pIns->pVM);
+
+    int rc = VINF_SUCCESS;
+    HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (&pIns->hostHeap, pvMem);
+    Assert(offBuffer != HGSMIOFFSET_VOID);
+    if (offBuffer != HGSMIOFFSET_VOID)
+    {
+        rc = hgsmiCompleteGuestCommand (pIns, offBuffer, bDoIrq);
+        AssertRC (rc);
+    }
+    else
+    {
+        LogRel(("invalid cmd offset \n"));
+        rc = VERR_INVALID_PARAMETER;
+    }
+
+    LogFlowFunc(("rc = %Rrc\n", rc));
+
+    return rc;
+}
+#endif
Index: /trunk/src/VBox/Devices/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Devices/Makefile.kmk	(revision 26555)
+++ /trunk/src/VBox/Devices/Makefile.kmk	(revision 26556)
@@ -340,4 +340,8 @@
 
 endif
+ifdef VBOXVDMA
+ DevicesR3_DEFS         += VBOXVDMA
+endif
+
 ifdef VBOX_WITH_VIDEOHWACCEL
  DevicesR3_DEFS         += VBOX_WITH_VIDEOHWACCEL
@@ -571,4 +575,7 @@
   VBoxDDGC_DEFS         += VBOX_WITH_HGSMI
  endif
+ ifdef VBOXVDMA
+  VBoxDDGC_DEFS         += VBOXVDMA
+ endif
 
  ifdef VBOX_WITH_USB
@@ -588,4 +595,8 @@
   VBoxDDGC_DEFS         += VBOX_WITH_HGSMI
  endif
+ ifdef VBOXVDMA
+  VBoxDDGC_DEFS         += VBOXVDMA
+ endif
+ 
  ifdef VBOX_WITH_VIDEOHWACCEL
   VBoxDDGC_DEFS         += VBOX_WITH_VIDEOHWACCEL
@@ -669,4 +680,8 @@
  VBoxDDR0_DEFS         += VBOX_WITH_HGSMI
 endif
+ifdef VBOXVDMA
+ VBoxDDR0_DEFS         += VBOXVDMA
+endif
+
 
 ifdef VBOX_WITH_USB
@@ -706,4 +721,7 @@
 ifdef VBOX_WITH_VIDEOHWACCEL
  VBoxDDR0_DEFS         += VBOX_WITH_VIDEOHWACCEL
+endif
+ifdef VBOXVDMA
+ VBoxDDR0_DEFS         += VBOXVDMA
 endif
 
