[Pkg-virtualbox-commits] [virtualbox] 01/03: Imported Upstream version 4.3.26-dfsg

Gianfranco Costamagna locutusofborg-guest at moszumanska.debian.org
Tue Mar 17 07:40:48 UTC 2015


This is an automated email from the git hooks/post-receive script.

locutusofborg-guest pushed a commit to branch master
in repository virtualbox.

commit 40b3330d30a580f62a19d95a51235fd20f0c5ffa
Author: Gianfranco Costamagna <costamagnagianfranco at yahoo.it>
Date:   Tue Mar 17 08:33:49 2015 +0100

    Imported Upstream version 4.3.26-dfsg
---
 Config.kmk                                         |    5 +-
 doc/manual/en_US/user_BasicConcepts.xml            |    8 +
 doc/manual/en_US/user_Introduction.xml             |   17 +-
 doc/manual/en_US/user_Storage.xml                  |    6 +
 doc/manual/user_ChangeLogImpl.xml                  |   68 +
 include/VBox/sup.h                                 |    1 +
 include/iprt/asm-amd64-x86.h                       |   43 +
 include/iprt/asn1-generator-pass.h                 |   27 +-
 include/iprt/x86.h                                 |   68 +-
 include/iprt/x86.mac                               |   27 +
 .../common/VBoxService/VBoxServiceVMInfo.cpp       |   37 +-
 src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd      |  Bin 1048576 -> 1048576 bytes
 src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd      |  Bin 1048576 -> 1048576 bytes
 .../Graphics/BIOS/VBoxVgaBiosAlternative.asm       |    6 +-
 .../Graphics/BIOS/VBoxVgaBiosAlternative.md5sum    |    2 +-
 src/VBox/Devices/Graphics/DevVGA-SVGA.cpp          |    6 +-
 src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.m    |    5 +
 src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp    | 1615 +++++++++++++++-----
 src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.cpp |    3 +
 src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.h   |   31 +-
 src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp    |  409 ++---
 src/VBox/Devices/Graphics/DevVGA-SVGA3d.h          |    4 +-
 src/VBox/Devices/Graphics/DevVGA_VBVA.cpp          |    2 +-
 src/VBox/Devices/Graphics/shaderlib/glsl_shader.c  |  105 ++
 src/VBox/Devices/Graphics/shaderlib/shader.c       |    2 +
 src/VBox/Devices/Graphics/shaderlib/shader_sm1.c   |    4 +
 .../Devices/Graphics/shaderlib/wined3d_private.h   |    6 +
 src/VBox/Devices/Graphics/testcase/dump-vmwgfx.c   |  629 ++++++++
 src/VBox/Devices/Makefile.kmk                      |    3 -
 src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm   |    4 +-
 .../Devices/PC/BIOS/VBoxBiosAlternative.md5sum     |    2 +-
 src/VBox/Devices/PC/ipxe/iPxeBiosBin.rom           |  Bin 53248 -> 54272 bytes
 .../VirtualBox/src/globals/VBoxGlobal.cpp          |    3 +-
 .../VirtualBox/src/selector/VBoxSnapshotsWgt.cpp   |   22 +-
 src/VBox/HostDrivers/Support/SUPDrv.c              |   29 +
 src/VBox/HostDrivers/Support/SUPDrvIOC.h           |    4 +-
 src/VBox/HostDrivers/Support/SUPDrvInternal.h      |    1 +
 src/VBox/HostDrivers/Support/SUPLib.cpp            |    2 +-
 .../HostDrivers/Support/darwin/SUPDrv-darwin.cpp   |   49 +
 src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c  |   23 +-
 src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp    |   68 +-
 src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbRt.cpp |    7 +-
 .../SharedOpenGL/render/renderspu_cocoa_helper.m   |  350 +++--
 src/VBox/Main/include/NetworkServiceRunner.h       |    5 +-
 src/VBox/Main/src-all/DisplayUtils.cpp             |    6 +-
 src/VBox/Main/src-client/ConsoleImpl.cpp           |    3 +
 src/VBox/Main/src-client/DisplayImpl.cpp           |    4 +
 src/VBox/Main/src-server/DHCPServerImpl.cpp        |   14 +-
 src/VBox/Main/src-server/HostDnsService.cpp        |   49 +-
 src/VBox/Main/src-server/HostDnsService.h          |    1 -
 src/VBox/Main/src-server/NATNetworkImpl.cpp        |    8 +-
 src/VBox/Main/src-server/NetworkServiceRunner.cpp  |   62 +-
 .../src-server/darwin/HostDnsServiceDarwin.cpp     |    1 -
 .../Main/src-server/linux/HostDnsServiceLinux.cpp  |    4 -
 src/VBox/Main/src-server/win/HostDnsServiceWin.cpp |    1 -
 src/VBox/NetworkServices/DHCP/Config.cpp           |   55 +-
 src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp      |   11 +
 src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp    |   11 +
 src/VBox/NetworkServices/NetLib/ComHostUtils.cpp   |    4 +-
 .../NetworkServices/NetLib/VBoxNetBaseService.cpp  |   59 +-
 .../NetworkServices/NetLib/VBoxNetBaseService.h    |    1 +
 src/VBox/NetworkServices/NetLib/utils.h            |    2 +-
 src/VBox/RDP/client/Makefile.in                    |    4 +-
 src/VBox/RDP/client/Makefile.kmk                   |    1 +
 src/VBox/RDP/client/vrdp/rdpusb.c                  |   52 +-
 src/VBox/Runtime/common/string/strformatrt.cpp     |    1 +
 src/VBox/Runtime/r0drv/linux/the-linux-kernel.h    |    5 +
 src/VBox/VMM/VMMR0/HMVMXR0.cpp                     |   17 +-
 src/VBox/VMM/VMMR3/CPUM.cpp                        |    7 +-
 src/VBox/VMM/VMMR3/PGMPhys.cpp                     |    2 +-
 70 files changed, 3137 insertions(+), 956 deletions(-)

diff --git a/Config.kmk b/Config.kmk
index dbf0b87..b1af32c 100644
--- a/Config.kmk
+++ b/Config.kmk
@@ -208,7 +208,7 @@ VBOX_VERSION_MINOR = 3
 # This is the current build number. It should be increased every time we publish a
 # new build. The define is available in every source file. Only even build numbers
 # will be published, odd numbers are set during development.
-VBOX_VERSION_BUILD = 24
+VBOX_VERSION_BUILD = 26
 # The raw version string. This *must not* contain any other information/fields than
 # major, minor and build revision (as it is now) -- also will be used for host/guest version
 # comparison.
@@ -5724,7 +5724,7 @@ endif
 SVN                    ?= svn$(HOSTSUFF_EXE)
 VBOX_SVN_REV_KMK        = $(PATH_OUT)/revision.kmk
 ifndef VBOX_SVN_REV
- VBOX_SVN_REV_FALLBACK := $(patsubst %:,,  $Rev: 98716 $  )
+ VBOX_SVN_REV_FALLBACK := $(patsubst %:,,  $Rev: 98988 $  )
  VBOX_SVN_DEP          := $(firstword $(wildcard $(PATH_ROOT)/.svn/wc.db $(abspath $(PATH_ROOT)/../.svn/wc.db) $(abspath $(PATH_ROOT)/../../.svn/wc.db) $(PATH_ROOT)/.svn/entries))
  ifeq ($(which $(SVN)),)
   VBOX_SVN_DEP         :=
@@ -5876,3 +5876,4 @@ st stat status:
 quick:
 	$(MAKE) VBOX_QUICK=1
 
+
diff --git a/doc/manual/en_US/user_BasicConcepts.xml b/doc/manual/en_US/user_BasicConcepts.xml
index 2905351..fb050c1 100644
--- a/doc/manual/en_US/user_BasicConcepts.xml
+++ b/doc/manual/en_US/user_BasicConcepts.xml
@@ -1220,6 +1220,14 @@
           linkend="intro-installing" /> for more information.</para>
         </note></para>
 
+      <para>When USB support is enabled for a VM, you can determine in detail
+      which devices will be automatically attached to the guest. For this, you
+      can create so-called "filters" by specifying certain properties of
+      the USB device. USB devices with a matching filter will be automatically
+      passed to the guest once they are attached to the host. USB devices
+      without a matching filter can be passed manually to the guest, for
+      example by using the Devices / USB devices menu.</para>
+
       <para>Clicking on the "+" button to the right of the "USB Device
       Filters" window creates a <emphasis role="bold">new filter.</emphasis>
       You can give the filter a name (for referencing it later) and specify
diff --git a/doc/manual/en_US/user_Introduction.xml b/doc/manual/en_US/user_Introduction.xml
index a91e4f7..fa6284a 100644
--- a/doc/manual/en_US/user_Introduction.xml
+++ b/doc/manual/en_US/user_Introduction.xml
@@ -324,7 +324,7 @@
 
       <listitem>
         <para><emphasis role="bold">VM groups.</emphasis> VirtualBox provides a
-        groups feature that enables the user to organize virtual machines
+        groups feature that enables the user to organize and control virtual machines
         collectively, as well as individually. In addition to basic groups, it
         is also possible for any VM to be in more than one group, and for
         groups to be nested in a hierarchy -- i.e. groups of groups. In
@@ -813,7 +813,8 @@
           large enough to hold the contents of your operating system and the
           applications you want to install -- for a modern Windows or Linux
           guest, you will probably need several gigabytes for any serious
-          use:</para>
+          use. The limit of the image file size can be changed later (see <xref
+          linkend="vboxmanage-modifyvdi"/> for details).</para>
 
           <mediaobject>
             <imageobject>
@@ -1273,24 +1274,30 @@
         </listitem>
         <listitem>
           <para>
-            Command line option 1) Create group and assign VM:
+            Command line option 1) Create a group and assign a VM:
             <screen>VBoxManage modifyvm "Fred" --groups "/TestGroup"</screen>
+            creates a group "TestGroup" and attaches the VM "Fred" to that group.
           </para>
           <para>
-            Command line option 2) Detach VM from group, and delete group if
-            empty: <screen>VBoxManage modifyvm "Fred" --groups ""</screen>
+            Command line option 2) Detach a VM from the group, and delete the group
+            if empty: <screen>VBoxManage modifyvm "Fred" --groups ""</screen>
+            It detaches all groups from the VM "Fred" and deletes the empty group.
           </para>
         </listitem>
         <listitem>
           <para>
             Multiple groups e.g.:
             <screen>VBoxManage modifyvm "Fred" --groups "/TestGroup,/TestGroup2"</screen>
+            It creates the groups "TestGroup" and "TestGroup2" (if they don't exist yet)
+            and attaches the VM "Fred" to both of them.
           </para>
         </listitem>
         <listitem>
           <para>
             Nested groups -- hierarchy of groups e.g.:
             <screen>VBoxManage modifyvm "Fred" --groups "/TestGroup/TestGroup2"</screen>
+            It attaches the VM "Fred" to the subgroup "TestGroup2" of the "TestGroup"
+            group.
           </para>
         </listitem>
         <listitem>
diff --git a/doc/manual/en_US/user_Storage.xml b/doc/manual/en_US/user_Storage.xml
index f790843..ee9cd6c 100644
--- a/doc/manual/en_US/user_Storage.xml
+++ b/doc/manual/en_US/user_Storage.xml
@@ -526,6 +526,12 @@
         <para>Technically, a "multiattach" image behaves identically to an
         "immutable" image except the differencing image is not reset every
         time the machine starts.</para>
+      <para>This mode is useful for sharing files which are almost never
+        written, for instance picture galleries, where every guest changes
+        only a small amount of data and the majority of the disk content
+        remains unchanged. The modified blocks are stored in differencing
+        images which remain reletively small and the shared content is stored
+        only once at the host.</para>
       </listitem>
 
       <listitem>
diff --git a/doc/manual/user_ChangeLogImpl.xml b/doc/manual/user_ChangeLogImpl.xml
index a6ae82b..e516e95 100644
--- a/doc/manual/user_ChangeLogImpl.xml
+++ b/doc/manual/user_ChangeLogImpl.xml
@@ -1,6 +1,74 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
   <sect1>
+    <title>Version 4.3.26 (2015-03-16)</title>
+
+    <para>This is a maintenance release. The following items were fixed and/or
+      added:</para>
+
+    <itemizedlist>
+
+      <listitem>
+        <para>GUI: in the snapshots pane, protect the age of snapshots against
+          wrong host time (bug #13955)</para>
+      </listitem>
+
+      <listitem>
+        <para>NAT Network: fixed a bug which prevented to propagate any DNS
+          name server / domain / search string information to the NAT network
+          (4.3.24 regression; bugs #13915, #13918)</para>
+      </listitem>
+
+      <listitem>
+        <para>NAT Network: don't delay the shutdown of VBoxSVC on
+          Windows hosts</para>
+      </listitem>
+
+      <listitem>
+        <para>Mouse support: the mouse could not be moved under rare
+          conditions if no Guest Additions are installed (4.3.24 regression;
+          bug #13935)</para>
+      </listitem>
+
+      <listitem>
+        <para>Storage: if the guest ejects a virtual CD/DVD medium, make the
+          change permanent (bugs #9858, #12885)</para>
+      </listitem>
+
+      <listitem>
+        <para>VGA: made saving secondary screen sizes possible in X11 guests</para>
+      </listitem>
+
+      <listitem>
+        <para>SDK: fixed the VirtualBox.tlb file (4.3.20 regression; bug #13943)</para>
+      </listitem>
+
+      <listitem>
+        <para>rdesktop-vrdp: make it work with USB devices again
+          (4.3.14 regression; bug #13901)</para>
+      </listitem>
+
+      <listitem>
+        <para>USB: fixed a possible BSOD on Windows hosts under rare conditions</para>
+      </listitem>
+
+      <listitem>
+        <para>iPXE: enable the HTTP download protocol on non-Linux hosts (bug #13628)</para>
+      </listitem>
+
+      <listitem>
+        <para>Mac OS X hosts: don't panic on hosts with activated SMAP (Broadwell
+          and later; bug #13951)</para>
+      </listitem>
+
+      <listitem>
+        <para>Linux hosts: don't crash Linux 4.0 hosts (bug #13835)</para>
+      </listitem>
+
+    </itemizedlist>
+  </sect1>
+
+  <sect1>
     <title>Version 4.3.24 (2015-03-02)</title>
 
     <para>This is a maintenance release. The following items were fixed and/or
diff --git a/include/VBox/sup.h b/include/VBox/sup.h
index 9e104a3..4dbda19 100644
--- a/include/VBox/sup.h
+++ b/include/VBox/sup.h
@@ -1432,6 +1432,7 @@ SUPR0DECL(int) SUPR0GipUnmap(PSUPDRVSESSION pSession);
 SUPR0DECL(int) SUPR0Printf(const char *pszFormat, ...);
 SUPR0DECL(SUPPAGINGMODE) SUPR0GetPagingMode(void);
 SUPR0DECL(uint32_t) SUPR0GetKernelFeatures(void);
+SUPR0DECL(RTCCUINTREG) SUPR0ChangeCR4(RTCCUINTREG fOrMask, RTCCUINTREG fAndMask);
 SUPR0DECL(int) SUPR0EnableVTx(bool fEnable);
 SUPR0DECL(bool) SUPR0SuspendVTxOnCpu(void);
 SUPR0DECL(void) SUPR0ResumeVTxOnCpu(bool fSuspended);
diff --git a/include/iprt/asm-amd64-x86.h b/include/iprt/asm-amd64-x86.h
index b0f0c5b..fa77cb2 100644
--- a/include/iprt/asm-amd64-x86.h
+++ b/include/iprt/asm-amd64-x86.h
@@ -2926,6 +2926,49 @@ DECLINLINE(void) ASMReadFenceSSE2(void)
 #endif
 }
 
+#if !defined(_MSC_VER) || !defined(RT_ARCH_AMD64)
+
+/*
+ * Clear the AC bit in the EFLAGS register.
+ * Requires the X86_CPUID_STEXT_FEATURE_EBX_SMAP CPUID bit set.
+ * Requires to be executed in R0.
+ */
+DECLINLINE(void) ASMClearAC(void)
+{
+#if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__ (".byte 0x0f,0x01,0xca\n\t");
+#else
+    __asm
+    {
+        _emit   0x0f
+        _emit   0x01
+        _emit   0xca
+    }
+#endif
+}
+
+
+/*
+ * Set the AC bit in the EFLAGS register.
+ * Requires the X86_CPUID_STEXT_FEATURE_EBX_SMAP CPUID bit set.
+ * Requires to be executed in R0.
+ */
+DECLINLINE(void) ASMSetAC(void)
+{
+#if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__ (".byte 0x0f,0x01,0xcb\n\t");
+#else
+    __asm
+    {
+        _emit   0x0f
+        _emit   0x01
+        _emit   0xcb
+    }
+#endif
+}
+
+#endif /* !_MSC_VER) || !RT_ARCH_AMD64 */
+
 /** @} */
 #endif
 
diff --git a/include/iprt/asn1-generator-pass.h b/include/iprt/asn1-generator-pass.h
index e198de8..30da121 100644
--- a/include/iprt/asn1-generator-pass.h
+++ b/include/iprt/asn1-generator-pass.h
@@ -1086,9 +1086,12 @@ RTASN1TMPL_DECL(void) RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(RT_CONCAT(P,RTASN1T
         default: break
 # define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
         case a_enmValue: \
-            RT_CONCAT(a_Api,_Delete)(pThis->a_UnionNm.a_PtrName); \
-            RTAsn1MemFree(&pThis->Allocation, pThis->a_UnionNm.a_PtrName); \
-            pThis->a_UnionNm.a_PtrName = NULL; \
+            if (pThis->a_UnionNm.a_PtrName) \
+            { \
+                RT_CONCAT(a_Api,_Delete)(pThis->a_UnionNm.a_PtrName); \
+                RTAsn1MemFree(&pThis->Allocation, pThis->a_UnionNm.a_PtrName); \
+                pThis->a_UnionNm.a_PtrName = NULL; \
+            } \
             break
 # define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation) \
     }
@@ -1103,15 +1106,21 @@ RTASN1TMPL_DECL(void) RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(RT_CONCAT(P,RTASN1T
         default: break
 # define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
         case a_enmChoice: \
-            RT_CONCAT(a_Api,_Delete)(pThis->a_PtrName); \
-            RTAsn1MemFree(&pThis->Allocation, pThis->a_PtrName); \
-            pThis->a_PtrName = NULL; \
+            if (pThis->a_PtrName) \
+            { \
+                RT_CONCAT(a_Api,_Delete)(pThis->a_PtrName); \
+                RTAsn1MemFree(&pThis->Allocation, pThis->a_PtrName); \
+                pThis->a_PtrName = NULL; \
+            } \
             break
 # define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
         case a_enmChoice: \
-            RT_CONCAT(a_Api,_Delete)(&pThis->a_PtrTnNm->a_Name); \
-            RTAsn1MemFree(&pThis->Allocation, pThis->a_PtrTnNm); \
-            pThis->a_PtrTnNm = NULL; \
+            if (pThis->a_PtrTnNm) \
+            { \
+                RT_CONCAT(a_Api,_Delete)(&pThis->a_PtrTnNm->a_Name); \
+                RTAsn1MemFree(&pThis->Allocation, pThis->a_PtrTnNm); \
+                pThis->a_PtrTnNm = NULL; \
+            } \
             break
 # define RTASN1TMPL_END_PCHOICE() \
     } \
diff --git a/include/iprt/x86.h b/include/iprt/x86.h
index f92c61c..b451c77 100644
--- a/include/iprt/x86.h
+++ b/include/iprt/x86.h
@@ -280,8 +280,10 @@ typedef struct X86CPUIDFEATECX
     unsigned    u1OSXSAVE : 1;
     /** Bit 28 - AVX - Supports AVX instruction extensions. */
     unsigned    u1AVX : 1;
-    /** Bit 29 - 30 - Reserved */
-    unsigned    u2Reserved3 : 2;
+    /** Bit 29 - F16C - Supports 16-bit floating point conversion instructions. */
+    unsigned    u1F16C : 1;
+    /** Bit 30 - RDRAND - Supports RDRAND. */
+    unsigned    u1RDRAND : 1;
     /** Bit 31 - Hypervisor present (we're a guest). */
     unsigned    u1HVP : 1;
 } X86CPUIDFEATECX;
@@ -451,6 +453,8 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX;
 #define X86_CPUID_FEATURE_ECX_AVX       RT_BIT(28)
 /** ECX Bit 29 - F16C - Half-precision convert instruction support. */
 #define X86_CPUID_FEATURE_ECX_F16C      RT_BIT(29)
+/** ECX Bit 30 - RDRAND instruction. */
+#define X86_CPUID_FEATURE_ECX_RDRAND    RT_BIT(30)
 /** ECX Bit 31 - Hypervisor Present (software only). */
 #define X86_CPUID_FEATURE_ECX_HVP       RT_BIT(31)
 
@@ -526,6 +530,61 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX;
 /** @} */
 
 
+/** @name CPUID Structured Extended Feature information.
+ * CPUID query with EAX=7.
+ * @{
+ */
+/** EBX Bit 0 - FSGSBASE - Supports RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE. */
+#define X86_CPUID_STEXT_FEATURE_EBX_FSGSBASE          RT_BIT(0)
+/** EBX Bit 1 - TSCADJUST - Supports MSR_IA32_TSC_ADJUST. */
+#define X86_CPUID_STEXT_FEATURE_EBX_TSC_ADJUST        RT_BIT(1)
+/** EBX Bit 3 - BMI1 - Advanced Bit Manipulation extension 1. */
+#define X86_CPUID_STEXT_FEATURE_EBX_BMI1              RT_BIT(3)
+/** EBX Bit 4 - HLE - Hardware Lock Elision. */
+#define X86_CPUID_STEXT_FEATURE_EBX_HLE               RT_BIT(4)
+/** EBX Bit 5 - AVX2 - Advanced Vector Extensions 2. */
+#define X86_CPUID_STEXT_FEATURE_EBX_AVX2              RT_BIT(5)
+/** EBX Bit 7 - SMEP - Supervisor Mode Execution Prevention. */
+#define X86_CPUID_STEXT_FEATURE_EBX_SMEP              RT_BIT(7)
+/** EBX Bit 8 - BMI2 - Advanced Bit Manipulation extension 2. */
+#define X86_CPUID_STEXT_FEATURE_EBX_BMI2              RT_BIT(8)
+/** EBX Bit 9 - ERMS - Supports Enhanced REP MOVSB/STOSB. */
+#define X86_CPUID_STEXT_FEATURE_EBX_ERMS              RT_BIT(9)
+/** EBX Bit 10 - INVPCID - Supports INVPCID. */
+#define X86_CPUID_STEXT_FEATURE_EBX_INVPCID           RT_BIT(10)
+/** EBX Bit 11 - RTM - Supports Restricted Transactional Memory. */
+#define X86_CPUID_STEXT_FEATURE_EBX_RTM               RT_BIT(11)
+/** EBX Bit 12 - PQM - Supports Platform Quality of Service Monitoring. */
+#define X86_CPUID_STEXT_FEATURE_EBX_PQM               RT_BIT(12)
+/** EBX Bit 13 - DEPFPU_CS_DS - Deprecates FPU CS, FPU DS values if set. */
+#define X86_CPUID_STEXT_FEATURE_EBX_DEPR_FPU_CS_DS    RT_BIT(13)
+/** EBX Bit 14 - MPE - Supports Intel Memory Protection Extensions. */
+#define X86_CPUID_STEXT_FEATURE_EBX_MPE               RT_BIT(14)
+/** EBX Bit 15 - PQE - Supports Platform Quality of Service Enforcement. */
+#define X86_CPUID_STEXT_FEATURE_EBX_PQE               RT_BIT(15)
+/** EBX Bit 16 - AVX512F - Supports AVX512F. */
+#define X86_CPUID_STEXT_FEATURE_EBX_AVX512F           RT_BIT(16)
+/** EBX Bit 18 - RDSEED - Supports RDSEED. */
+#define X86_CPUID_STEXT_FEATURE_EBX_RDSEED            RT_BIT(18)
+/** EBX Bit 19 - ADX - Supports ADCX/ADOX. */
+#define X86_CPUID_STEXT_FEATURE_EBX_ADX               RT_BIT(19)
+/** EBX Bit 20 - SMAP - Supports Supervisor Mode Access Prevention. */
+#define X86_CPUID_STEXT_FEATURE_EBX_SMAP              RT_BIT(20)
+/** EBX Bit 23 - CLFLUSHOPT - Supports CLFLUSHOPT (Cache Line Flush). */
+#define X86_CPUID_STEXT_FEATURE_EBX_CLFLUSHOPT        RT_BIT(23)
+/** EBX Bit 25 - INTEL_PT - Supports Intel Processor Trace. */
+#define X86_CPUID_STEXT_FEATURE_EBX_INTEL_PT          RT_BIT(25)
+/** EBX Bit 26 - AVX512PF - Supports AVX512PF. */
+#define X86_CPUID_STEXT_FEATURE_EBX_AVX512PF          RT_BIT(26)
+/** EBX Bit 27 - AVX512ER - Supports AVX512ER. */
+#define X86_CPUID_STEXT_FEATURE_EBX_AVX512ER          RT_BIT(27)
+/** EBX Bit 28 - AVX512CD - Supports AVX512CD. */
+#define X86_CPUID_STEXT_FEATURE_EBX_AVX512CD          RT_BIT(28)
+/** EBX Bit 29 - SHA - Supports Secure Hash Algorithm extensions. */
+#define X86_CPUID_STEXT_FEATURE_EBX_SHA               RT_BIT(29)
+/** @} */
+
+
 /** @name CPUID Extended Feature information.
  *  CPUID query with EAX=0x80000001.
  *  @{
@@ -737,6 +796,8 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX;
 #define X86_CR4_OSXSAVE                     RT_BIT(18)
 /** Bit 20 - SMEP - Supervisor-mode Execution Prevention enabled. */
 #define X86_CR4_SMEP                        RT_BIT(20)
+/** Bit 21 - SMAP - Supervisor-mode Access Prevention enabled. */
+#define X86_CR4_SMAP                        RT_BIT(21)
 /** @} */
 
 
@@ -960,6 +1021,9 @@ AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x00040000)) == 0);
 #define MSR_IA32_FEATURE_CONTROL_SMX_VMXON  RT_BIT(1)
 #define MSR_IA32_FEATURE_CONTROL_VMXON      RT_BIT(2)
 
+/** Per-processor TSC adjust MSR. */
+#define MSR_IA32_TSC_ADJUST                 0x3B
+
 /** BIOS update trigger (microcode update). */
 #define MSR_IA32_BIOS_UPDT_TRIG             0x79
 
diff --git a/include/iprt/x86.mac b/include/iprt/x86.mac
index 733ce42..62f4967 100644
--- a/include/iprt/x86.mac
+++ b/include/iprt/x86.mac
@@ -84,6 +84,7 @@
 %define X86_CPUID_FEATURE_ECX_OSXSAVE   RT_BIT(27)
 %define X86_CPUID_FEATURE_ECX_AVX       RT_BIT(28)
 %define X86_CPUID_FEATURE_ECX_F16C      RT_BIT(29)
+%define X86_CPUID_FEATURE_ECX_RDRAND    RT_BIT(30)
 %define X86_CPUID_FEATURE_ECX_HVP       RT_BIT(31)
 %define X86_CPUID_FEATURE_EDX_FPU       RT_BIT(0)
 %define X86_CPUID_FEATURE_EDX_VME       RT_BIT(1)
@@ -116,6 +117,30 @@
 %define X86_CPUID_FEATURE_EDX_PBE       RT_BIT(31)
 %define X86_CPUID_MWAIT_ECX_EXT            RT_BIT(0)
 %define X86_CPUID_MWAIT_ECX_BREAKIRQIF0    RT_BIT(1)
+%define X86_CPUID_STEXT_FEATURE_EBX_FSGSBASE          RT_BIT(0)
+%define X86_CPUID_STEXT_FEATURE_EBX_TSC_ADJUST        RT_BIT(1)
+%define X86_CPUID_STEXT_FEATURE_EBX_BMI1              RT_BIT(3)
+%define X86_CPUID_STEXT_FEATURE_EBX_HLE               RT_BIT(4)
+%define X86_CPUID_STEXT_FEATURE_EBX_AVX2              RT_BIT(5)
+%define X86_CPUID_STEXT_FEATURE_EBX_SMEP              RT_BIT(7)
+%define X86_CPUID_STEXT_FEATURE_EBX_BMI2              RT_BIT(8)
+%define X86_CPUID_STEXT_FEATURE_EBX_ERMS              RT_BIT(9)
+%define X86_CPUID_STEXT_FEATURE_EBX_INVPCID           RT_BIT(10)
+%define X86_CPUID_STEXT_FEATURE_EBX_RTM               RT_BIT(11)
+%define X86_CPUID_STEXT_FEATURE_EBX_PQM               RT_BIT(12)
+%define X86_CPUID_STEXT_FEATURE_EBX_DEPR_FPU_CS_DS    RT_BIT(13)
+%define X86_CPUID_STEXT_FEATURE_EBX_MPE               RT_BIT(14)
+%define X86_CPUID_STEXT_FEATURE_EBX_PQE               RT_BIT(15)
+%define X86_CPUID_STEXT_FEATURE_EBX_AVX512F           RT_BIT(16)
+%define X86_CPUID_STEXT_FEATURE_EBX_RDSEED            RT_BIT(18)
+%define X86_CPUID_STEXT_FEATURE_EBX_ADX               RT_BIT(19)
+%define X86_CPUID_STEXT_FEATURE_EBX_SMAP              RT_BIT(20)
+%define X86_CPUID_STEXT_FEATURE_EBX_CLFLUSHOPT        RT_BIT(23)
+%define X86_CPUID_STEXT_FEATURE_EBX_INTEL_PT          RT_BIT(25)
+%define X86_CPUID_STEXT_FEATURE_EBX_AVX512PF          RT_BIT(26)
+%define X86_CPUID_STEXT_FEATURE_EBX_AVX512ER          RT_BIT(27)
+%define X86_CPUID_STEXT_FEATURE_EBX_AVX512CD          RT_BIT(28)
+%define X86_CPUID_STEXT_FEATURE_EBX_SHA               RT_BIT(29)
 %define X86_CPUID_EXT_FEATURE_ECX_LAHF_SAHF     RT_BIT(0)
 %define X86_CPUID_EXT_FEATURE_EDX_SYSCALL       RT_BIT(11)
 %define X86_CPUID_EXT_FEATURE_EDX_NX            RT_BIT(20)
@@ -209,6 +234,7 @@
 %define X86_CR4_PCIDE                       RT_BIT(17)
 %define X86_CR4_OSXSAVE                     RT_BIT(18)
 %define X86_CR4_SMEP                        RT_BIT(20)
+%define X86_CR4_SMAP                        RT_BIT(21)
 %define X86_DR6_B0                          RT_BIT(0)
 %define X86_DR6_B1                          RT_BIT(1)
 %define X86_DR6_B2                          RT_BIT(2)
@@ -287,6 +313,7 @@
 %define MSR_IA32_FEATURE_CONTROL_LOCK       RT_BIT(0)
 %define MSR_IA32_FEATURE_CONTROL_SMX_VMXON  RT_BIT(1)
 %define MSR_IA32_FEATURE_CONTROL_VMXON      RT_BIT(2)
+%define MSR_IA32_TSC_ADJUST                 0x3B
 %define MSR_IA32_BIOS_UPDT_TRIG             0x79
 %define MSR_IA32_BIOS_SIGN_ID               0x8B
 %define MSR_IA32_PMC0                       0xC1
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
index 45ca3ae..5f6894a 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
@@ -703,26 +703,29 @@ static int vboxserviceVMInfoWriteUsers(void)
                                     setpwent();
                                     struct passwd *ppwEntry = getpwuid(uid);
                                     if (   ppwEntry
-                                        && ppwEntry->pw_uid >= uid_min /* Only respect users, not daemons etc. */
                                         && ppwEntry->pw_name)
                                     {
-                                        VBoxServiceVerbose(4, "ConsoleKit: session '%s' -> %s (uid: %RU32)\n",
-                                                           *ppszCurSession, ppwEntry->pw_name, uid);
-
-                                        bool fFound = false;
-                                        for (uint32_t i = 0; i < cUsersInList && !fFound; i++)
-                                            fFound = strcmp(papszUsers[i], ppwEntry->pw_name) == 0;
-
-                                        if (!fFound)
+                                        if (ppwEntry->pw_uid >= uid_min /* Only respect users, not daemons etc. */)
                                         {
-                                            VBoxServiceVerbose(4, "ConsoleKit: adding user \"%s\" to list\n",
-                                                               ppwEntry->pw_name);
-
-                                            rc = RTStrDupEx(&papszUsers[cUsersInList], (const char *)ppwEntry->pw_name);
-                                            if (RT_FAILURE(rc))
-                                                break;
-                                            cUsersInList++;
+                                            VBoxServiceVerbose(4, "ConsoleKit: session '%s' -> %s (uid: %RU32)\n",
+                                                               *ppszCurSession, ppwEntry->pw_name, uid);
+
+                                            bool fFound = false;
+                                            for (uint32_t i = 0; i < cUsersInList && !fFound; i++)
+                                                fFound = strcmp(papszUsers[i], ppwEntry->pw_name) == 0;
+
+                                            if (!fFound)
+                                            {
+                                                VBoxServiceVerbose(4, "ConsoleKit: adding user \"%s\" to list\n",
+                                                                   ppwEntry->pw_name);
+
+                                                rc = RTStrDupEx(&papszUsers[cUsersInList], (const char *)ppwEntry->pw_name);
+                                                if (RT_FAILURE(rc))
+                                                    break;
+                                                cUsersInList++;
+                                            }
                                         }
+                                        /* else silently ignore the user */
                                     }
                                     else
                                         VBoxServiceError("ConsoleKit: unable to lookup user name for uid=%RU32\n", uid);
@@ -734,7 +737,7 @@ static int vboxserviceVMInfoWriteUsers(void)
                             if (pReplyUnixUser)
                                 dbus_message_unref(pReplyUnixUser);
                         }
-                        else
+                        else if (fActive) /* don't bitch about inactive users */
                         {
                             static int s_iBitchedAboutConsoleKit = 0;
                             if (s_iBitchedAboutConsoleKit < 1)
diff --git a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd
index 73c6b59..6d4d015 100644
Binary files a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd and b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd differ
diff --git a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd
index 7821508..9eeb19c 100644
Binary files a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd and b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd differ
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm
index bff629f..ae1fcc2 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm
@@ -6781,7 +6781,7 @@ vesa_pm_end:                                 ; 0xc4714 LB 0x1
 
 section _DATA progbits vstart=0x4800 align=1 ; size=0x36e1 class=DATA group=DGROUP
 _msg_vga_init:                               ; 0xc4800 LB 0x2f
-    db  'Oracle VM VirtualBox Version 4.3.24 VGA BIOS', 00dh, 00ah, 000h
+    db  'Oracle VM VirtualBox Version 4.3.26 VGA BIOS', 00dh, 00ah, 000h
 _vga_modes:                                  ; 0xc482f LB 0x80
     db  000h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h, 001h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h
     db  002h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h, 003h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h
@@ -7669,7 +7669,7 @@ _vbebios_vendor_name:                        ; 0xc7e35 LB 0x13
 _vbebios_product_name:                       ; 0xc7e48 LB 0x21
     db  'Oracle VM VirtualBox VBE Adapter', 000h
 _vbebios_product_revision:                   ; 0xc7e69 LB 0x24
-    db  'Oracle VM VirtualBox Version 4.3.24', 000h
+    db  'Oracle VM VirtualBox Version 4.3.26', 000h
 _vbebios_info_string:                        ; 0xc7e8d LB 0x2b
     db  'VirtualBox VBE Display Adapter enabled', 00dh, 00ah, 00dh, 00ah, 000h
 _no_vbebios_info_string:                     ; 0xc7eb8 LB 0x29
@@ -7700,4 +7700,4 @@ section CONST2 progbits vstart=0x7ee2 align=1 ; size=0x0 class=DATA group=DGROUP
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
-    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 05eh
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 05ah
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum
index c15db79..86178c8 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum
@@ -1 +1 @@
-2c0ba7379b392d71f7cd61d98b5d9693 *VBoxVgaBios.rom
+3b54ab3f5a02a44d992aeebca0540f33 *VBoxVgaBios.rom
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp b/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
index 2e01a8d..023c8b1 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
@@ -2099,7 +2099,6 @@ static void *vmsvgaFIFOGetCmdPayload(uint32_t cbPayloadReq, uint32_t volatile *p
             STAM_REL_COUNTER_INC(&pSVGAState->StatFifoErrors);
             LogRelMax(16, ("vmsvgaFIFOGetCmdPayload: Invalid offNextCmd=%#x (offFifoMin=%#x offFifoMax=%#x)\n",
                            offNextCmd, offFifoMin, offFifoMax));
-            /** @todo release counter.   */
             cbAfter = offFifoMax - offCurrentCmd;
         }
         cbBefore = 0;
@@ -2114,7 +2113,6 @@ static void *vmsvgaFIFOGetCmdPayload(uint32_t cbPayloadReq, uint32_t volatile *p
             STAM_REL_COUNTER_INC(&pSVGAState->StatFifoErrors);
             LogRelMax(16, ("vmsvgaFIFOGetCmdPayload: Invalid offNextCmd=%#x (offFifoMin=%#x offFifoMax=%#x)\n",
                            offNextCmd, offFifoMin, offFifoMax));
-            /** @todo release counter.   */
             cbBefore = 0;
         }
     }
@@ -2169,7 +2167,7 @@ static void *vmsvgaFIFOGetCmdPayload(uint32_t cbPayloadReq, uint32_t volatile *p
             memcpy(pbBounceBuf + cbAlreadyRead,
                    (uint8_t *)pFIFO + offCurrentCmd + cbAlreadyRead,
                    cbAfter - cbAlreadyRead);
-            cbAlreadyRead += cbAfter - cbAlreadyRead;
+            cbAlreadyRead = cbAfter;
         }
         memcpy(pbBounceBuf + cbAlreadyRead,
                (uint8_t *)pFIFO + offFifoMin + cbAlreadyRead - cbAfter,
@@ -2932,7 +2930,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
                         SVGA3dCmdDefineContext *pCmd = (SVGA3dCmdDefineContext *)(pHdr + 1);
                         VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
 
-                        rc = vmsvga3dContextDefine(pThis, pCmd->cid, false /*fOtherProfile*/);
+                        rc = vmsvga3dContextDefine(pThis, pCmd->cid);
                         break;
                     }
 
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.m b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.m
index dfb0ea1..a21eace 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.m
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.m
@@ -734,6 +734,11 @@ void vmsvga3dCocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLCo
 
     DEBUG_MSG(("cocoaViewMakeCurrentContext(%p, %p)\n", (void*)pView, (void*)pCtx));
 
+    /* Always flush before flush. glXMakeCurrent and wglMakeCurrent does this
+       implicitly, seemingly NSOpenGLContext::makeCurrentContext doesn't. */
+    if ([NSOpenGLContext currentContext] != 0)
+        glFlush();
+
     if (pView)
     {
         [(VMSVGA3DOverlayView*)pView setGLCtx:pCtx];
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp
index e579bf5..5a82b50 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp
@@ -19,6 +19,13 @@
 /*******************************************************************************
 *   Header Files                                                               *
 *******************************************************************************/
+/* Enable to disassemble defined shaders. (Windows host only) */
+#if defined(RT_OS_WINDOWS) && defined(DEBUG) && 0 /* Disabled as we don't have the DirectX SDK avaible atm. */
+# define DUMP_SHADER_DISASSEMBLY
+#endif
+#ifdef DEBUG_bird
+# define RTMEM_WRAP_TO_EF_APIS
+#endif
 #define LOG_GROUP LOG_GROUP_DEV_VMSVGA
 #include <VBox/vmm/pdmdev.h>
 #include <VBox/version.h>
@@ -78,6 +85,9 @@ typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname,
 # include <GL/glext.h>
 # define VBOX_VMSVGA3D_GL_HACK_LEVEL 0x103
 #endif
+#ifdef DUMP_SHADER_DISASSEMBLY
+# include <d3dx9shader.h>
+#endif
 #include "vmsvga_glext/glext.h"
 
 #include "shaderlib/shaderlib.h"
@@ -87,16 +97,28 @@ typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname,
 #include <float.h>
 
 
-/* Generated by VBoxDef2LazyLoad from the VBoxSVGA3D.def and VBoxSVGA3DObjC.def files. */
-extern "C" int ExplicitlyLoadVBoxSVGA3D(bool fResolveAllImports, PRTERRINFO pErrInfo);
-#ifdef RT_OS_DARWIN
-extern "C" int ExplicitlyLoadVBoxSVGA3DObjC(bool fResolveAllImports, PRTERRINFO pErrInfo);
-#endif
-
-
 /*******************************************************************************
 *   Defined Constants And Macros                                               *
 *******************************************************************************/
+/** Experimental: Create a dedicated context for handling surfaces in, thus
+ * avoiding orphaned surfaces after context destruction.
+ *
+ * This cures, for instance, an assertion on fedora 21 that happens in
+ * vmsvga3dSurfaceStretchBlt if the login screen and the desktop has different
+ * sizes.  The context of the login screen seems to have just been destroyed
+ * earlier and I believe the driver/X/whoever is attemting to strech the old
+ * screen content onto the new sized screen.
+ *
+ * @remarks This probably comes at a slight preformance expense, as we currently
+ *          switches context when setting up the surface the first time.  Not sure
+ *          if we really need to, but as this is an experiment, I'm playing it safe.
+ */
+#define VMSVGA3D_OGL_WITH_SHARED_CTX
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+/** Fake surface ID for the shared context. */
+# define VMSVGA3D_SHARED_CTX_ID     UINT32_C(0xffffeeee)
+#endif
+
 /** @def VBOX_VMSVGA3D_GL_HACK_LEVEL
  * Turns out that on Linux gl.h may often define the first 2-4 OpenGL versions
  * worth of extensions, but missing out on a function pointer of fifteen.  This
@@ -142,6 +164,20 @@ static void *MyNSGLGetProcAddress(const char *pszSymbol)
 /* Enable to render the result of DrawPrimitive in a seperate window. */
 //#define DEBUG_GFX_WINDOW
 
+
+/** @name VMSVGA3D_DEF_CTX_F_XXX - vmsvga3dContextDefineOgl flags.
+ * @{ */
+/** When clear, the  context is created using the default OpenGL profile.
+ * When set, it's created using the alternative profile.  The latter is only
+ * allowed if the VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE is set.  */
+#define VMSVGA3D_DEF_CTX_F_OTHER_PROFILE    RT_BIT_32(0)
+/** Defining the shared context.  */
+#define VMSVGA3D_DEF_CTX_F_SHARED_CTX       RT_BIT_32(1)
+/** Defining the init time context (EMT).  */
+#define VMSVGA3D_DEF_CTX_F_INIT             RT_BIT_32(2)
+/** @} */
+
+
 #define VMSVGA3D_CLEAR_CURRENT_CONTEXT(pState)                          \
     do { (pState)->idActiveContext = OPENGL_INVALID_ID; } while (0)
 
@@ -151,33 +187,206 @@ static void *MyNSGLGetProcAddress(const char *pszSymbol)
  * @parm    pContext    The new context.
  */
 #ifdef RT_OS_WINDOWS
-# define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext)                   \
-    if ((pState)->idActiveContext != pContext->id)                        \
-    {                                                                     \
+# define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
+    if ((pState)->idActiveContext != (pContext)->id) \
+    { \
         BOOL fMakeCurrentRc = wglMakeCurrent((pContext)->hdc, (pContext)->hglrc); \
-        Assert(fMakeCurrentRc == TRUE);                                   \
-        pState->idActiveContext = (pContext)->id;                         \
+        Assert(fMakeCurrentRc == TRUE); \
+        LogFlowFunc(("Changing context: %#x -> %#x\n", (pState)->idActiveContext, (pContext)->id)); \
+        (pState)->idActiveContext = (pContext)->id; \
     } else do { } while (0)
 
 #elif defined(RT_OS_DARWIN)
 # define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
-    if ((pState)->idActiveContext != (pContext)->id)                    \
-    {                                                                   \
+    if ((pState)->idActiveContext != (pContext)->id) \
+    { \
         vmsvga3dCocoaViewMakeCurrentContext((pContext)->cocoaView, (pContext)->cocoaContext); \
-        (pState)->idActiveContext = (pContext)->id;                     \
+        LogFlowFunc(("Changing context: %#x -> %#x\n", (pState)->idActiveContext, (pContext)->id)); \
+        (pState)->idActiveContext = (pContext)->id; \
     } else do { } while (0)
 #else
 # define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
-    if ((pState)->idActiveContext != (pContext)->id)                    \
-    {                                                                   \
-        Bool fMakeCurrentRc = glXMakeCurrent((pState)->display,         \
-                                             (pContext)->window,        \
-                                             (pContext)->glxContext);   \
-        Assert(fMakeCurrentRc == True);                                 \
-        (pState)->idActiveContext = (pContext)->id;                     \
+    if ((pState)->idActiveContext != (pContext)->id) \
+    { \
+        Bool fMakeCurrentRc = glXMakeCurrent((pState)->display, \
+                                             (pContext)->window, \
+                                             (pContext)->glxContext); \
+        Assert(fMakeCurrentRc == True); \
+        LogFlowFunc(("Changing context: %#x -> %#x\n", (pState)->idActiveContext, (pContext)->id)); \
+        (pState)->idActiveContext = (pContext)->id; \
     } else do { } while (0)
 #endif
 
+/** @def VMSVGA3D_CLEAR_GL_ERRORS
+ * Clears all pending OpenGL errors.
+ *
+ * If I understood this correctly, OpenGL maintains a bitmask internally and
+ * glGetError gets the next bit (clearing it) from the bitmap and translates it
+ * into a GL_XXX constant value which it then returns.  A single OpenGL call can
+ * set more than one bit, and they stick around across calls, from what I
+ * understand.
+ *
+ * So in order to be able to use glGetError to check whether a function
+ * succeeded, we need to call glGetError until all error bits have been cleared.
+ * This macro does that (in all types of builds).
+ *
+ * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS
+ */
+#define VMSVGA3D_CLEAR_GL_ERRORS() \
+    do { \
+        if (RT_UNLIKELY(glGetError() != GL_NO_ERROR)) /* predict no errors pending */ \
+        { \
+            uint32_t iErrorClearingLoopsLeft = 64; \
+            while (glGetError() != GL_NO_ERROR && iErrorClearingLoopsLeft > 0) \
+                iErrorClearingLoopsLeft--; \
+        } \
+    } while (0)
+
+/** @def VMSVGA3D_GET_LAST_GL_ERROR
+ * Gets the last OpenGL error, stores it in a_pContext->lastError and returns
+ * it.
+ *
+ * @returns Same as glGetError.
+ * @param   a_pContext  The context to store the error in.
+ *
+ * @sa VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
+ */
+#define VMSVGA3D_GET_GL_ERROR(a_pContext) ((a_pContext)->lastError = glGetError())
+
+/** @def VMSVGA3D_GL_SUCCESS
+ * Checks whether VMSVGA3D_GET_LAST_GL_ERROR() return GL_NO_ERROR.
+ *
+ * Will call glGetError() and store the result in a_pContext->lastError.
+ * Will predict GL_NO_ERROR outcome.
+ *
+ * @returns True on success, false on error.
+ * @parm    a_pContext  The context to store the error in.
+ *
+ * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_COMPLAIN
+ */
+#define VMSVGA3D_GL_IS_SUCCESS(a_pContext) RT_LIKELY((((a_pContext)->lastError = glGetError()) == GL_NO_ERROR))
+
+/** @def VMSVGA3D_GL_COMPLAIN
+ * Complains about one or more OpenGL errors (first in a_pContext->lastError).
+ *
+ * Strict builds will trigger an assertion, while other builds will put the
+ * first few occurences in the release log.
+ *
+ * All GL errors will be cleared after invocation.  Assumes lastError
+ * is an error, will not check for GL_NO_ERROR.
+ *
+ * @param   a_pState        The 3D state structure.
+ * @param   a_pContext      The context that holds the first error.
+ * @param   a_LogRelDetails Argument list for LogRel or similar that describes
+ *                          the operation in greater detail.
+ *
+ * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS
+ */
+#ifdef VBOX_STRICT
+# define VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
+    do { \
+        AssertMsg((a_pState)->idActiveContext == (a_pContext)->id, \
+                  ("idActiveContext=%#x id=%x\n", (a_pState)->idActiveContext, (a_pContext)->id)); \
+        RTAssertMsg2Weak a_LogRelDetails; \
+        GLenum iNextError; \
+        while ((iNextError = glGetError()) != GL_NO_ERROR) \
+            RTAssertMsg2Weak("next error: %#x\n", iNextError); \
+        AssertMsgFailed(("first error: %#x (idActiveContext=%#x)\n", (a_pContext)->lastError, (a_pContext)->id)); \
+    } while (0)
+#else
+# define VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
+    do { \
+        LogRelMax(32, ("VMSVGA3d: OpenGL error %#x (idActiveContext=%#x) on line %u ", (a_pContext)->lastError, (a_pContext)->id)); \
+        GLenum iNextError; \
+        while ((iNextError = glGetError()) != GL_NO_ERROR) \
+            LogRelMax(32, (" - also error %#x ", iNextError)); \
+        LogRelMax(32, a_LogRelDetails); \
+    } while (0)
+#endif
+
+/** @def VMSVGA3D_GL_GET_AND_COMPLAIN
+ * Combination of VMSVGA3D_GET_GL_ERROR and VMSVGA3D_GL_COMPLAIN, assuming that
+ * there is a pending error.
+ *
+ * @param   a_pState    The 3D state structure.
+ * @param   a_pContext  The context that holds the first error.
+ * @param   a_LogRelDetails Argument list for LogRel or similar that describes
+ *                          the operation in greater detail.
+ *
+ * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
+ */
+#define VMSVGA3D_GL_GET_AND_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
+    do { \
+        VMSVGA3D_GET_GL_ERROR(a_pContext); \
+        VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails); \
+    } while (0)
+
+/** @def VMSVGA3D_GL_ASSERT_SUCCESS
+ * Asserts that VMSVGA3D_GL_IS_SUCCESS is true, complains if not.
+ *
+ * Uses VMSVGA3D_GL_COMPLAIN for complaining, so check it out wrt to release
+ * logging in non-strict builds.
+ *
+ * @param   a_pState    The 3D state structure.
+ * @param   a_pContext  The context that holds the first error.
+ * @param   a_LogRelDetails Argument list for LogRel or similar that describes
+ *                          the operation in greater detail.
+ *
+ * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
+ */
+#define VMSVGA3D_GL_ASSERT_SUCCESS(a_pState, a_pContext, a_LogRelDetails) \
+    if (VMSVGA3D_GL_IS_SUCCESS(a_pContext)) \
+    { /* likely */ } \
+    else do { \
+        VMSVGA3D_GET_GL_ERROR(a_pContext); \
+        VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails); \
+    } while (0)
+
+/** @def VMSVGA3D_ASSERT_GL_CALL_EX
+ * Executes the specified OpenGL API call and asserts that it succeeded, variant
+ * with extra logging flexibility.
+ *
+ * ASSUMES no GL errors pending prior to invocation - caller should use
+ * VMSVGA3D_CLEAR_GL_ERRORS if uncertain.
+ *
+ * Uses VMSVGA3D_GL_COMPLAIN for complaining, so check it out wrt to release
+ * logging in non-strict builds.
+ *
+ * @param   a_GlCall    Expression making an OpenGL call.
+ * @param   a_pState    The 3D state structure.
+ * @param   a_pContext  The context that holds the first error.
+ * @param   a_LogRelDetails Argument list for LogRel or similar that describes
+ *                          the operation in greater detail.
+ *
+ * @sa VMSVGA3D_ASSERT_GL_CALL, VMSVGA3D_GL_ASSERT_SUCCESS,
+ *     VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
+ */
+#define VMSVGA3D_ASSERT_GL_CALL_EX(a_GlCall, a_pState, a_pContext, a_LogRelDetails) \
+    do { \
+        (a_GlCall); \
+        VMSVGA3D_GL_ASSERT_SUCCESS(a_pState, a_pContext, a_LogRelDetails); \
+    } while (0)
+
+/** @def VMSVGA3D_ASSERT_GL_CALL
+ * Executes the specified OpenGL API call and asserts that it succeeded.
+ *
+ * ASSUMES no GL errors pending prior to invocation - caller should use
+ * VMSVGA3D_CLEAR_GL_ERRORS if uncertain.
+ *
+ * Uses VMSVGA3D_GL_COMPLAIN for complaining, so check it out wrt to release
+ * logging in non-strict builds.
+ *
+ * @param   a_GlCall    Expression making an OpenGL call.
+ * @param   a_pState    The 3D state structure.
+ * @param   a_pContext  The context that holds the first error.
+ *
+ * @sa VMSVGA3D_ASSERT_GL_CALL_EX, VMSVGA3D_GL_ASSERT_SUCCESS,
+ *     VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
+ */
+#define VMSVGA3D_ASSERT_GL_CALL(a_GlCall, a_pState, a_pContext) \
+    VMSVGA3D_ASSERT_GL_CALL_EX(a_GlCall, a_pState, a_pContext, ("%s\n", #a_GlCall))
+
+
 /** @def VMSVGA3D_CHECK_LAST_ERROR
  * Checks that the last OpenGL error code indicates success.
  *
@@ -185,11 +394,11 @@ static void *MyNSGLGetProcAddress(const char *pszSymbol)
  * builds it will do nothing and is a NOOP.
  *
  * @parm    pState      The VMSVGA3d state.
- * @parm    pContext    The new context.
+ * @parm    pContext    The context.
  *
- * @todo    Revamp this to include the OpenGL operation so we can see what went
- *          wrong.  Maybe include a few of the first occurances in the release
- *          log of regular builds.
+ * @todo    Replace with proper error handling, it's crazy to return
+ *          VERR_INTERNAL_ERROR in strict builds and just barge on ahead in
+ *          release builds.
  */
 #ifdef VBOX_STRICT
 # define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext) do {                   \
@@ -293,9 +502,13 @@ static SSMFIELD const g_aVMSVGA3DMIPMAPLEVELFields[] =
 typedef struct
 {
     uint32_t                id;
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+    uint32_t                idAssociatedContextUnused;
+#else
     uint32_t                idAssociatedContext;
+#endif
     uint32_t                flags;
-    SVGA3dSurfaceFormat     format; 
+    SVGA3dSurfaceFormat     format;
     GLint                   internalFormatGL;
     GLint                   formatGL;
     GLint                   typeGL;
@@ -307,7 +520,7 @@ typedef struct
     } oglId;
     SVGA3dSurfaceFace       faces[SVGA3D_MAX_SURFACE_FACES];
     uint32_t                cFaces;
-    PVMSVGA3DMIPMAPLEVEL    pMipmapLevels; 
+    PVMSVGA3DMIPMAPLEVEL    pMipmapLevels;
     uint32_t                multiSampleCount;
     SVGA3dTextureFilter     autogenFilter;
     uint32_t                cbBlock;        /* block/pixel size in bytes */
@@ -321,7 +534,11 @@ typedef struct
 static SSMFIELD const g_aVMSVGA3DSURFACEFields[] =
 {
     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, id),
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+    SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, idAssociatedContextUnused),
+#else
     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, idAssociatedContext),
+#endif
     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, flags),
     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, format),
     SSMFIELD_ENTRY(                 VMSVGA3DSURFACE, internalFormatGL),
@@ -627,7 +844,7 @@ typedef struct VMSVGA3DSTATE
     } caps;
 
     uint32_t                cContexts;
-    PVMSVGA3DCONTEXT        paContext;
+    PVMSVGA3DCONTEXT       *papContexts;
     uint32_t                cSurfaces;
     PVMSVGA3DSURFACE        paSurface;
 #ifdef DEBUG_GFX_WINDOW_TEST_CONTEXT
@@ -649,6 +866,11 @@ typedef struct VMSVGA3DSTATE
 
     /** Shader talk back interface. */
     VBOXVMSVGASHADERIF      ShaderIf;
+
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+    /** The shared context. */
+    VMSVGA3DCONTEXT         SharedCtx;
+#endif
 } VMSVGA3DSTATE;
 /** Pointer to the VMSVGA3d state. */
 typedef VMSVGA3DSTATE *PVMSVGA3DSTATE;
@@ -675,13 +897,41 @@ static SSMFIELD const g_aVMSVGA3DSTATEFields[] =
     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, caps),
 
     SSMFIELD_ENTRY(                 VMSVGA3DSTATE, cContexts),
-    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, paContext),
+    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, papContexts),
     SSMFIELD_ENTRY(                 VMSVGA3DSTATE, cSurfaces),
     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, paSurface),
     SSMFIELD_ENTRY_TERM()
 };
 
 
+/** Save and setup everything. */
+#define VMSVGA3D_PARANOID_TEXTURE_PACKING
+
+/**
+ * Saved texture packing parameters (shared by both pack and unpack).
+ */
+typedef struct VMSVGAPACKPARAMS
+{
+    GLint       iAlignment;
+    GLint       cxRow;
+#ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
+    GLint       cyImage;
+    GLboolean   fSwapBytes;
+    GLboolean   fLsbFirst;
+    GLint       cSkipRows;
+    GLint       cSkipPixels;
+    GLint       cSkipImages;
+#endif
+} VMSVGAPACKPARAMS;
+/** Pointer to saved texture packing parameters. */
+typedef VMSVGAPACKPARAMS *PVMSVGAPACKPARAMS;
+/** Pointer to const saved texture packing parameters. */
+typedef VMSVGAPACKPARAMS const *PCVMSVGAPACKPARAMS;
+
+
+/*******************************************************************************
+*   Global Variables                                                           *
+*******************************************************************************/
 /* Define the default light parameters as specified by MSDN. */
 /* @todo move out; fetched from Wine */
 const SVGA3dLightData vmsvga3d_default_light =
@@ -700,10 +950,23 @@ const SVGA3dLightData vmsvga3d_default_light =
     0.0f                            /* phi */
 };
 
-RT_C_DECLS_BEGIN
-static int vmsvga3dCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext, PVMSVGA3DSURFACE pSurface);
+
+/*******************************************************************************
+*   Internal Functions                                                         *
+*******************************************************************************/
+static int  vmsvga3dCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext, PVMSVGA3DSURFACE pSurface);
+static int  vmsvga3dContextDefineOgl(PVGASTATE pThis, uint32_t cid, uint32_t fFlags);
 static void vmsvgaColor2GLFloatArray(uint32_t color, GLfloat *pRed, GLfloat *pGreen, GLfloat *pBlue, GLfloat *pAlpha);
-RT_C_DECLS_END
+static void vmsvga3dSetPackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
+                                  PVMSVGAPACKPARAMS pSave);
+static void vmsvga3dRestorePackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
+                                      PCVMSVGAPACKPARAMS pSave);
+
+/* Generated by VBoxDef2LazyLoad from the VBoxSVGA3D.def and VBoxSVGA3DObjC.def files. */
+extern "C" int ExplicitlyLoadVBoxSVGA3D(bool fResolveAllImports, PRTERRINFO pErrInfo);
+#ifdef RT_OS_DARWIN
+extern "C" int ExplicitlyLoadVBoxSVGA3DObjC(bool fResolveAllImports, PRTERRINFO pErrInfo);
+#endif
 
 
 /**
@@ -1056,7 +1319,7 @@ static DECLCALLBACK(void) vmsvga3dShaderIfSwitchInitProfile(PVBOXVMSVGASHADERIF
 {
 #ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
     PVMSVGA3DSTATE pState = RT_FROM_MEMBER(pThis, VMSVGA3DSTATE, ShaderIf);
-    VMSVGA3D_SET_CURRENT_CONTEXT(pState, &pState->paContext[fOtherProfile ? 2 : 1]);
+    VMSVGA3D_SET_CURRENT_CONTEXT(pState, pState->papContexts[fOtherProfile ? 2 : 1]);
 #else
     NOREF(pThis);
     NOREF(fOtherProfile);
@@ -1177,10 +1440,10 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
     /*
      * OpenGL function calls aren't possible without a valid current context, so create a fake one here.
      */
-    rc = vmsvga3dContextDefine(pThis, 1, false /*fOtherProfile*/);
+    rc = vmsvga3dContextDefineOgl(pThis, 1, VMSVGA3D_DEF_CTX_F_INIT);
     AssertRCReturn(rc, rc);
 
-    pContext = &pState->paContext[1];
+    pContext = pState->papContexts[1];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     LogRel(("VMSVGA3d: OpenGL version: %s\n"
@@ -1202,11 +1465,11 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
      * Get the extension list for the alternative profile so we can better
      * figure out the shader model and stuff.
      */
-    rc = vmsvga3dContextDefine(pThis, 2, true /*fOtherProfile*/);
+    rc = vmsvga3dContextDefineOgl(pThis, 2, VMSVGA3D_DEF_CTX_F_INIT | VMSVGA3D_DEF_CTX_F_OTHER_PROFILE);
     AssertLogRelRCReturn(rc, rc);
-    pContext = &pState->paContext[1]; /* Array may have been reallocated. */
+    pContext = pState->papContexts[1]; /* Array may have been reallocated. */
 
-    pOtherCtx = &pState->paContext[2];
+    pOtherCtx = pState->papContexts[2];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pOtherCtx);
 
     LogRel(("VMSVGA3d: Alternative OpenGL version: %s\n"
@@ -1229,7 +1492,7 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
 #endif
 
 
-    if (vmsvga3dCheckGLExtension(pState, 3.0, " GL_ARB_framebuffer_object "))
+    if (vmsvga3dCheckGLExtension(pState, 3.0f, " GL_ARB_framebuffer_object "))
     {
         pState->ext.glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)OGLGETPROCADDRESS("glIsRenderbuffer");
         pState->ext.glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)OGLGETPROCADDRESS("glBindRenderbuffer");
@@ -1317,9 +1580,9 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
     /* Extension support */
 #if defined(RT_OS_DARWIN)
     /** @todo OpenGL version history suggest this, verify...  */
-    pState->ext.fEXT_stencil_two_side = vmsvga3dCheckGLExtension(pState, 2.0, " GL_EXT_stencil_two_side ");
+    pState->ext.fEXT_stencil_two_side = vmsvga3dCheckGLExtension(pState, 2.0f, " GL_EXT_stencil_two_side ");
 #else
-    pState->ext.fEXT_stencil_two_side = vmsvga3dCheckGLExtension(pState, 0.0, " GL_EXT_stencil_two_side ");
+    pState->ext.fEXT_stencil_two_side = vmsvga3dCheckGLExtension(pState, 0.0f, " GL_EXT_stencil_two_side ");
 #endif
 
     /*
@@ -1372,9 +1635,9 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
                                    pState->ext.glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB,
                                                                  &pState->caps.maxVertexShaderInstructions));
     }
-    pState->caps.fS3TCSupported = vmsvga3dCheckGLExtension(pState, 0.0, " GL_EXT_texture_compression_s3tc ");
+    pState->caps.fS3TCSupported = vmsvga3dCheckGLExtension(pState, 0.0f, " GL_EXT_texture_compression_s3tc ");
 
-    /* http://http://www.opengl.org/wiki/Detecting_the_Shader_Model 
+    /* http://http://www.opengl.org/wiki/Detecting_the_Shader_Model
      * ARB Assembly Language
      * These are done through testing the presence of extensions. You should test them in this order:
      * GL_NV_gpu_program4: SM 4.0 or better.
@@ -1384,16 +1647,16 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
      *
      */
     /** @todo: distinguish between vertex and pixel shaders??? */
-    if (   vmsvga3dCheckGLExtension(pState, 0.0, " GL_NV_gpu_program4 ")
+    if (   vmsvga3dCheckGLExtension(pState, 0.0f, " GL_NV_gpu_program4 ")
         || strstr(pState->pszOtherExtensions, " GL_NV_gpu_program4 "))
     {
         pState->caps.vertexShaderVersion   = SVGA3DVSVERSION_40;
         pState->caps.fragmentShaderVersion = SVGA3DPSVERSION_40;
     }
     else
-    if (   vmsvga3dCheckGLExtension(pState, 0.0, " GL_NV_vertex_program3 ")
+    if (   vmsvga3dCheckGLExtension(pState, 0.0f, " GL_NV_vertex_program3 ")
         || strstr(pState->pszOtherExtensions, " GL_NV_vertex_program3 ")
-        || vmsvga3dCheckGLExtension(pState, 0.0, " GL_ARB_shader_texture_lod ")  /* Wine claims this suggests SM 3.0 support */
+        || vmsvga3dCheckGLExtension(pState, 0.0f, " GL_ARB_shader_texture_lod ")  /* Wine claims this suggests SM 3.0 support */
         || strstr(pState->pszOtherExtensions, " GL_ARB_shader_texture_lod ")
         )
     {
@@ -1401,7 +1664,7 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
         pState->caps.fragmentShaderVersion = SVGA3DPSVERSION_30;
     }
     else
-    if (   vmsvga3dCheckGLExtension(pState, 0.0, " GL_ARB_fragment_program ")
+    if (   vmsvga3dCheckGLExtension(pState, 0.0f, " GL_ARB_fragment_program ")
         || strstr(pState->pszOtherExtensions, " GL_ARB_fragment_program "))
     {
         pState->caps.vertexShaderVersion   = SVGA3DVSVERSION_20;
@@ -1568,8 +1831,8 @@ int vmsvga3dReset(PVGASTATE pThis)
     /* Destroy all leftover contexts. */
     for (uint32_t i = 0; i < pState->cContexts; i++)
     {
-        if (pState->paContext[i].id != SVGA3D_INVALID_ID)
-            vmsvga3dContextDestroy(pThis, pState->paContext[i].id);
+        if (pState->papContexts[i]->id != SVGA3D_INVALID_ID)
+            vmsvga3dContextDestroy(pThis, pState->papContexts[i]->id);
     }
     return VINF_SUCCESS;
 }
@@ -1618,12 +1881,24 @@ int vmsvga3dTerminate(PVGASTATE pThis)
 #define VMSVGA3D_OPENGL
 #include "DevVGA-SVGA3d-shared.h"
 
+/**
+ * Worker for vmsvga3dQueryCaps that figures out supported operations for a
+ * given surface format capability.
+ *
+ * @returns Supported/indented operations (SVGA3DFORMAT_OP_XXX).
+ * @param   pState3D        The 3D state.
+ * @param   idx3dCaps       The SVGA3D_CAPS_XXX value of the surface format.
+ *
+ * @remarks See fromat_cap_table in svga_format.c (mesa/gallium) for a reference
+ *          of implicit guest expectations:
+ *              http://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/svga/svga_format.c
+ */
 static uint32_t vmsvga3dGetSurfaceFormatSupport(PVMSVGA3DSTATE pState3D, uint32_t idx3dCaps)
 {
     uint32_t result = 0;
 
     /* @todo missing:
-     * 
+     *
      * SVGA3DFORMAT_OP_PIXELSIZE
      */
 
@@ -1632,7 +1907,7 @@ static uint32_t vmsvga3dGetSurfaceFormatSupport(PVMSVGA3DSTATE pState3D, uint32_
     case SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8:
     case SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5:
     case SVGA3D_DEVCAP_SURFACEFMT_R5G6B5:
-        result |= SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB 
+        result |= SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB
                |  SVGA3DFORMAT_OP_CONVERT_TO_ARGB
                |  SVGA3DFORMAT_OP_DISPLAYMODE           /* Should not be set for alpha formats. */
                |  SVGA3DFORMAT_OP_3DACCELERATION;       /* implies OP_DISPLAYMODE */
@@ -1642,7 +1917,7 @@ static uint32_t vmsvga3dGetSurfaceFormatSupport(PVMSVGA3DSTATE pState3D, uint32_
     case SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10:
     case SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5:
     case SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4:
-        result |=     SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB 
+        result |=     SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB
                   |   SVGA3DFORMAT_OP_CONVERT_TO_ARGB
                   |   SVGA3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET;
         break;
@@ -1742,8 +2017,15 @@ int vmsvga3dQueryCaps(PVGASTATE pThis, uint32_t idx3dCaps, uint32_t *pu32Val)
 
     *pu32Val = 0;
 
+    /*
+     * The capabilities access by current (2015-03-01) linux sources (gallium,
+     * vmwgfx, xorg-video-vmware) are annotated, caps without xref annotations
+     * aren't access.
+     */
+
     switch (idx3dCaps)
     {
+    /* Linux: vmwgfx_fifo.c in kmod; only used with SVGA_CAP_GBOBJECTS. */
     case SVGA3D_DEVCAP_3D:
         *pu32Val = 1; /* boolean? */
         break;
@@ -1760,6 +2042,7 @@ int vmsvga3dQueryCaps(PVGASTATE pThis, uint32_t idx3dCaps, uint32_t *pu32Val)
         *pu32Val = pState->caps.maxClipDistances;
         break;
 
+    /* Linux: svga_screen.c in gallium; 3.0 or later required. */
     case SVGA3D_DEVCAP_VERTEX_SHADER_VERSION:
         *pu32Val = pState->caps.vertexShaderVersion;
         break;
@@ -1769,6 +2052,7 @@ int vmsvga3dQueryCaps(PVGASTATE pThis, uint32_t idx3dCaps, uint32_t *pu32Val)
         *pu32Val = (pState->caps.vertexShaderVersion != SVGA3DVSVERSION_NONE);
         break;
 
+    /* Linux: svga_screen.c in gallium; 3.0 or later required. */
     case SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION:
         *pu32Val = pState->caps.fragmentShaderVersion;
         break;
@@ -1805,6 +2089,7 @@ int vmsvga3dQueryCaps(PVGASTATE pThis, uint32_t idx3dCaps, uint32_t *pu32Val)
     case SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING:
         break;
 
+    /* Linux: svga_screen.c in gallium; capped at 80.0, default 1.0. */
     case SVGA3D_DEVCAP_MAX_POINT_SIZE:
         AssertCompile(sizeof(uint32_t) == sizeof(float));
         *(float *)pu32Val = pState->caps.flPointSize[1];
@@ -1815,11 +2100,13 @@ int vmsvga3dQueryCaps(PVGASTATE pThis, uint32_t idx3dCaps, uint32_t *pu32Val)
         rc = VERR_INVALID_PARAMETER;
         break;
 
+    /* Linux: svga_screen.c in gallium (for PIPE_CAP_MAX_TEXTURE_2D_LEVELS); have default if missing. */
     case SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH:
     case SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT:
         *pu32Val = pState->caps.maxRectangleTextureSize;
         break;
 
+    /* Linux: svga_screen.c in gallium (for PIPE_CAP_MAX_TEXTURE_3D_LEVELS); have default if missing. */
     case SVGA3D_DEVCAP_MAX_VOLUME_EXTENT:
         //*pu32Val = pCaps->MaxVolumeExtent;
         break;
@@ -1832,6 +2119,7 @@ int vmsvga3dQueryCaps(PVGASTATE pThis, uint32_t idx3dCaps, uint32_t *pu32Val)
         //*pu32Val = pCaps->MaxTextureAspectRatio;
         break;
 
+    /* Linux: svga_screen.c in gallium (for PIPE_CAPF_MAX_TEXTURE_ANISOTROPY); defaults to 4.0. */
     case SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY:
         *pu32Val = pState->caps.maxTextureAnisotropy;
         break;
@@ -1841,6 +2129,7 @@ int vmsvga3dQueryCaps(PVGASTATE pThis, uint32_t idx3dCaps, uint32_t *pu32Val)
         *pu32Val =  0xFFFFF; /* hardcoded in Wine */
         break;
 
+    /* Linux: svga_screen.c in gallium (for PIPE_SHADER_VERTEX/PIPE_SHADER_CAP_MAX_INSTRUCTIONS); defaults to 512. */
     case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS:
         *pu32Val = pState->caps.maxVertexShaderInstructions;
         break;
@@ -1849,10 +2138,12 @@ int vmsvga3dQueryCaps(PVGASTATE pThis, uint32_t idx3dCaps, uint32_t *pu32Val)
         *pu32Val = pState->caps.maxFragmentShaderInstructions;
         break;
 
+    /* Linux: svga_screen.c in gallium (for PIPE_SHADER_VERTEX/PIPE_SHADER_CAP_MAX_TEMPS); defaults to 32. */
     case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS:
         *pu32Val = pState->caps.maxVertexShaderTemps;
         break;
 
+    /* Linux: svga_screen.c in gallium (for PIPE_SHADER_FRAGMENT/PIPE_SHADER_CAP_MAX_TEMPS); defaults to 32. */
     case SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS:
         *pu32Val = pState->caps.maxFragmentShaderTemps;
         break;
@@ -1900,7 +2191,25 @@ int vmsvga3dQueryCaps(PVGASTATE pThis, uint32_t idx3dCaps, uint32_t *pu32Val)
         *pu32Val = SVGA3D_MAX_SURFACE_IDS;
         break;
 
-    /* Supported surface formats. */
+#if 0 /* Appeared more recently, not yet implemented. */
+   /* Linux: svga_screen.c in gallium; defaults to FALSE. */
+   case SVGA3D_DEVCAP_LINE_AA:
+       break;
+   /* Linux: svga_screen.c in gallium; defaults to FALSE. */
+   case SVGA3D_DEVCAP_LINE_STIPPLE:
+       break;
+   /* Linux: svga_screen.c in gallium; defaults to 1.0. */
+   case SVGA3D_DEVCAP_MAX_LINE_WIDTH:
+       break;
+   /* Linux: svga_screen.c in gallium; defaults to 1.0. */
+   case SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH:
+       break;
+#endif
+
+    /*
+     * Supported surface formats.
+     * Linux: svga_format.c in gallium, format_cap_table defines implicit expectations.
+     */
     case SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8:
     case SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8:
     case SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10:
@@ -1950,6 +2259,7 @@ int vmsvga3dQueryCaps(PVGASTATE pThis, uint32_t idx3dCaps, uint32_t *pu32Val)
         *pu32Val = vmsvga3dGetSurfaceFormatSupport(pState, idx3dCaps);
         break;
 
+    /* Linux: Not referenced in current sources. */
     case SVGA3D_DEVCAP_SURFACEFMT_BC4_UNORM:
     case SVGA3D_DEVCAP_SURFACEFMT_BC5_UNORM:
         Log(("CAPS: Unknown CAP %s\n", vmsvga3dGetCapString(idx3dCaps)));
@@ -1969,130 +2279,158 @@ int vmsvga3dQueryCaps(PVGASTATE pThis, uint32_t idx3dCaps, uint32_t *pu32Val)
 
 /**
  * Convert SVGA format value to its OpenGL equivalent
+ *
+ * @remarks  Clues to be had in format_texture_info table (wined3d/utils.c) with
+ *           help from wined3dformat_from_d3dformat().
  */
 static void vmsvga3dSurfaceFormat2OGL(PVMSVGA3DSURFACE pSurface, SVGA3dSurfaceFormat format)
 {
     switch (format)
     {
-    case SVGA3D_X8R8G8B8:
+    case SVGA3D_X8R8G8B8:               /* D3DFMT_X8R8G8B8 - WINED3DFMT_B8G8R8X8_UNORM */
         pSurface->internalFormatGL = GL_RGB8;
         pSurface->formatGL = GL_BGRA;
         pSurface->typeGL = GL_UNSIGNED_INT_8_8_8_8_REV;
         break;
-    case SVGA3D_A8R8G8B8:
+    case SVGA3D_A8R8G8B8:               /* D3DFMT_A8R8G8B8 - WINED3DFMT_B8G8R8A8_UNORM */
         pSurface->internalFormatGL = GL_RGBA8;
         pSurface->formatGL = GL_BGRA;
         pSurface->typeGL = GL_UNSIGNED_INT_8_8_8_8_REV;
         break;
-    case SVGA3D_R5G6B5:
-        pSurface->internalFormatGL = GL_RGB;
+    case SVGA3D_R5G6B5:                 /* D3DFMT_R5G6B5 - WINED3DFMT_B5G6R5_UNORM */
+        pSurface->internalFormatGL = GL_RGB5;
         pSurface->formatGL = GL_RGB;
         pSurface->typeGL = GL_UNSIGNED_SHORT_5_6_5;
+        AssertMsgFailed(("Test me - SVGA3D_R5G6B5\n"));
         break;
-    case SVGA3D_X1R5G5B5:
-        pSurface->internalFormatGL = GL_RGB;
-        pSurface->formatGL = GL_RGB;
+    case SVGA3D_X1R5G5B5:               /* D3DFMT_X1R5G5B5 - WINED3DFMT_B5G5R5X1_UNORM */
+        pSurface->internalFormatGL = GL_RGB5;
+        pSurface->formatGL = GL_BGRA;
         pSurface->typeGL = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+        AssertMsgFailed(("Test me - SVGA3D_X1R5G5B5\n"));
         break;
-    case SVGA3D_A1R5G5B5:
-        pSurface->internalFormatGL = GL_RGBA;
-        pSurface->formatGL = GL_RGB;
+    case SVGA3D_A1R5G5B5:               /* D3DFMT_A1R5G5B5 - WINED3DFMT_B5G5R5A1_UNORM */
+        pSurface->internalFormatGL = GL_RGB5_A1;
+        pSurface->formatGL = GL_BGRA;
         pSurface->typeGL = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+        AssertMsgFailed(("Test me - SVGA3D_A1R5G5B5\n"));
         break;
-    case SVGA3D_A4R4G4B4:
-        pSurface->internalFormatGL = GL_RGBA;
-        pSurface->formatGL = GL_RGBA;
-        pSurface->typeGL =  GL_UNSIGNED_SHORT_4_4_4_4;
+    case SVGA3D_A4R4G4B4:               /* D3DFMT_A4R4G4B4 - WINED3DFMT_B4G4R4A4_UNORM */
+        pSurface->internalFormatGL = GL_RGBA4;
+        pSurface->formatGL = GL_BGRA;
+        pSurface->typeGL = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+        AssertMsgFailed(("Test me - SVGA3D_A4R4G4B4\n"));
         break;
 
-    case SVGA3D_Z_D32:
+    case SVGA3D_Z_D32:                  /* D3DFMT_D32 - WINED3DFMT_D32_UNORM */
         pSurface->internalFormatGL = GL_DEPTH_COMPONENT32;
         pSurface->formatGL = GL_DEPTH_COMPONENT;
         pSurface->typeGL = GL_UNSIGNED_INT;
         break;
-    case SVGA3D_Z_D16:
-        pSurface->internalFormatGL = GL_DEPTH_COMPONENT16;
+    case SVGA3D_Z_D16:                  /* D3DFMT_D16 - WINED3DFMT_D16_UNORM */
+        pSurface->internalFormatGL = GL_DEPTH_COMPONENT16; /** @todo Wine suggests GL_DEPTH_COMPONENT24. */
         pSurface->formatGL = GL_DEPTH_COMPONENT;
         pSurface->typeGL = GL_UNSIGNED_SHORT;
+        AssertMsgFailed(("Test me - SVGA3D_Z_D16\n"));
         break;
-    case SVGA3D_Z_D24S8:
+    case SVGA3D_Z_D24S8:                /* D3DFMT_D24S8 - WINED3DFMT_D24_UNORM_S8_UINT */
         pSurface->internalFormatGL = GL_DEPTH24_STENCIL8;
         pSurface->formatGL = GL_DEPTH_STENCIL;
         pSurface->typeGL = GL_UNSIGNED_INT;
         break;
-    case SVGA3D_Z_D15S1:
+    case SVGA3D_Z_D15S1:                /* D3DFMT_D15S1 - WINED3DFMT_S1_UINT_D15_UNORM */
         pSurface->internalFormatGL = GL_DEPTH_COMPONENT16;  /* @todo ??? */
         pSurface->formatGL = GL_DEPTH_STENCIL;
         pSurface->typeGL = GL_UNSIGNED_SHORT;
+        /** @todo Wine sources hints at no hw support for this, so test this one! */
+        AssertMsgFailed(("Test me - SVGA3D_Z_D15S1\n"));
         break;
-    case SVGA3D_Z_D24X8:
+    case SVGA3D_Z_D24X8:                /* D3DFMT_D24X8 - WINED3DFMT_X8D24_UNORM */
         pSurface->internalFormatGL = GL_DEPTH_COMPONENT24;
         pSurface->formatGL = GL_DEPTH_COMPONENT;
         pSurface->typeGL = GL_UNSIGNED_INT;
         break;
 
     /* Advanced D3D9 depth formats. */
-    case SVGA3D_Z_DF16:
+    case SVGA3D_Z_DF16:                 /* D3DFMT_DF16? - not supported */
         pSurface->internalFormatGL = GL_DEPTH_COMPONENT16;
         pSurface->formatGL = GL_DEPTH_COMPONENT;
         pSurface->typeGL = GL_FLOAT;
         break;
 
-    case SVGA3D_Z_DF24:
+    case SVGA3D_Z_DF24:                 /* D3DFMT_DF24? - not supported */
         pSurface->internalFormatGL = GL_DEPTH_COMPONENT24;
         pSurface->formatGL = GL_DEPTH_COMPONENT;
         pSurface->typeGL = GL_FLOAT;        /* ??? */
         break;
 
-    case SVGA3D_Z_D24S8_INT:
+    case SVGA3D_Z_D24S8_INT:            /* D3DFMT_??? - not supported */
         pSurface->internalFormatGL = GL_DEPTH24_STENCIL8;
         pSurface->formatGL = GL_DEPTH_STENCIL;
         pSurface->typeGL = GL_INT;        /* ??? */
         break;
 
-    case SVGA3D_DXT1:
+    case SVGA3D_DXT1:                   /* D3DFMT_DXT1 - WINED3DFMT_DXT1 */
         pSurface->internalFormatGL = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+#if 0
         pSurface->formatGL = GL_RGBA_S3TC;          /* ??? */
         pSurface->typeGL = GL_UNSIGNED_INT;         /* ??? */
+#else   /* wine suggests: */
+        pSurface->formatGL = GL_RGBA;
+        pSurface->typeGL = GL_UNSIGNED_BYTE;
+        AssertMsgFailed(("Test me - SVGA3D_DXT1\n"));
+#endif
         break;
 
-    case SVGA3D_DXT3:
+    case SVGA3D_DXT3:                   /* D3DFMT_DXT3 - WINED3DFMT_DXT3 */
         pSurface->internalFormatGL = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+#if 0 /** @todo this needs testing... */
         pSurface->formatGL = GL_RGBA_S3TC;          /* ??? */
         pSurface->typeGL = GL_UNSIGNED_INT;         /* ??? */
+#else   /* wine suggests: */
+        pSurface->formatGL = GL_RGBA;
+        pSurface->typeGL = GL_UNSIGNED_BYTE;
+        AssertMsgFailed(("Test me - SVGA3D_DXT3\n"));
+#endif
         break;
 
-    case SVGA3D_DXT5:
+    case SVGA3D_DXT5:                   /* D3DFMT_DXT5 - WINED3DFMT_DXT5 */
         pSurface->internalFormatGL = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+#if 0 /** @todo this needs testing... */
         pSurface->formatGL = GL_RGBA_S3TC;
         pSurface->typeGL = GL_UNSIGNED_INT;
+#else   /* wine suggests: */
+        pSurface->formatGL = GL_RGBA;
+        pSurface->typeGL = GL_UNSIGNED_BYTE;
+        AssertMsgFailed(("Test me - SVGA3D_DXT5\n"));
+#endif
         break;
 
-    case SVGA3D_LUMINANCE8:
+    case SVGA3D_LUMINANCE8:             /* D3DFMT_? - ? */
         pSurface->internalFormatGL = GL_LUMINANCE8_EXT;
         pSurface->formatGL = GL_LUMINANCE;
         pSurface->typeGL = GL_UNSIGNED_BYTE;
         break;
 
-    case SVGA3D_LUMINANCE16:
+    case SVGA3D_LUMINANCE16:            /* D3DFMT_? - ? */
         pSurface->internalFormatGL = GL_LUMINANCE16_EXT;
         pSurface->formatGL = GL_LUMINANCE;
         pSurface->typeGL = GL_UNSIGNED_SHORT;
         break;
 
-    case SVGA3D_LUMINANCE4_ALPHA4:
+    case SVGA3D_LUMINANCE4_ALPHA4:     /* D3DFMT_? - ? */
         pSurface->internalFormatGL = GL_LUMINANCE4_ALPHA4_EXT;
         pSurface->formatGL = GL_LUMINANCE_ALPHA;
         pSurface->typeGL = GL_UNSIGNED_BYTE;
         break;
 
-    case SVGA3D_LUMINANCE8_ALPHA8:
+    case SVGA3D_LUMINANCE8_ALPHA8:     /* D3DFMT_? - ? */
         pSurface->internalFormatGL = GL_LUMINANCE8_ALPHA8_EXT;
         pSurface->formatGL = GL_LUMINANCE_ALPHA;
         pSurface->typeGL = GL_UNSIGNED_BYTE;    /* unsigned_short causes issues even though this type should be 16-bit */
         break;
 
-    case SVGA3D_ALPHA8:
+    case SVGA3D_ALPHA8:                /* D3DFMT_A8? - WINED3DFMT_A8_UNORM? */
         pSurface->internalFormatGL = GL_ALPHA8_EXT;
         pSurface->formatGL = GL_ALPHA;
         pSurface->typeGL = GL_UNSIGNED_BYTE;
@@ -2124,42 +2462,62 @@ static void vmsvga3dSurfaceFormat2OGL(PVMSVGA3DSURFACE pSurface, SVGA3dSurfaceFo
         return D3DFMT_A2W10V10U10;
 #endif
 
-    case SVGA3D_ARGB_S10E5:   /* 16-bit floating-point ARGB */
+    case SVGA3D_ARGB_S10E5:   /* 16-bit floating-point ARGB */ /* D3DFMT_A16B16G16R16F - WINED3DFMT_R16G16B16A16_FLOAT */
         pSurface->internalFormatGL = GL_RGBA16F;
         pSurface->formatGL = GL_RGBA;
+#if 0 /* bird: wine uses half float, sounds correct to me... */
         pSurface->typeGL = GL_FLOAT;
+#else
+        pSurface->typeGL = GL_HALF_FLOAT;
+        AssertMsgFailed(("Test me - SVGA3D_ARGB_S10E5\n"));
+#endif
         break;
 
-    case SVGA3D_ARGB_S23E8:   /* 32-bit floating-point ARGB */
+    case SVGA3D_ARGB_S23E8:   /* 32-bit floating-point ARGB */ /* D3DFMT_A32B32G32R32F - WINED3DFMT_R32G32B32A32_FLOAT */
         pSurface->internalFormatGL = GL_RGBA32F;
         pSurface->formatGL = GL_RGBA;
-        pSurface->typeGL = GL_FLOAT;    /* ?? */
+        pSurface->typeGL = GL_FLOAT;    /* ?? - same as wine, so probably correct */
         break;
 
-    case SVGA3D_A2R10G10B10:
-        pSurface->internalFormatGL = GL_RGB10_A2; /* ?? */
+    case SVGA3D_A2R10G10B10:            /* D3DFMT_A2R10G10B10 - WINED3DFMT_B10G10R10A2_UNORM */
+        pSurface->internalFormatGL = GL_RGB10_A2; /* ?? - same as wine, so probably correct */
+#if 0 /* bird: Wine uses GL_BGRA instead of GL_RGBA. */
         pSurface->formatGL = GL_RGBA;
+#else
+        pSurface->formatGL = GL_BGRA;
+#endif
         pSurface->typeGL = GL_UNSIGNED_INT;
+        AssertMsgFailed(("Test me - SVGA3D_A2R10G10B10\n"));
         break;
 
 
     /* Single- and dual-component floating point formats */
-    case SVGA3D_R_S10E5:
+    case SVGA3D_R_S10E5:                /* D3DFMT_R16F - WINED3DFMT_R16_FLOAT */
         pSurface->internalFormatGL = GL_R16F;
         pSurface->formatGL = GL_RED;
+#if 0 /* bird: wine uses half float, sounds correct to me... */
         pSurface->typeGL = GL_FLOAT;
+#else
+        pSurface->typeGL = GL_HALF_FLOAT;
+        AssertMsgFailed(("Test me - SVGA3D_R_S10E5\n"));
+#endif
         break;
-    case SVGA3D_R_S23E8:
+    case SVGA3D_R_S23E8:                /* D3DFMT_R32F - WINED3DFMT_R32_FLOAT */
         pSurface->internalFormatGL = GL_R32F;
         pSurface->formatGL = GL_RG;
         pSurface->typeGL = GL_FLOAT;
         break;
-    case SVGA3D_RG_S10E5:
+    case SVGA3D_RG_S10E5:               /* D3DFMT_G16R16F - WINED3DFMT_R16G16_FLOAT */
         pSurface->internalFormatGL = GL_RG16F;
         pSurface->formatGL = GL_RG;
+#if 0 /* bird: wine uses half float, sounds correct to me... */
         pSurface->typeGL = GL_FLOAT;
+#else
+        pSurface->typeGL = GL_HALF_FLOAT;
+        AssertMsgFailed(("Test me - SVGA3D_RG_S10E5\n"));
+#endif
         break;
-    case SVGA3D_RG_S23E8:
+    case SVGA3D_RG_S23E8:               /* D3DFMT_G32R32F - WINED3DFMT_R32G32_FLOAT */
         pSurface->internalFormatGL = GL_RG32F;
         pSurface->formatGL = GL_RG;
         pSurface->typeGL = GL_FLOAT;
@@ -2183,16 +2541,26 @@ static void vmsvga3dSurfaceFormat2OGL(PVMSVGA3DSURFACE pSurface, SVGA3dSurfaceFo
         return D3DFMT_V16U16;
 #endif
 
-    case SVGA3D_G16R16:
+    case SVGA3D_G16R16:                 /* D3DFMT_G16R16 - WINED3DFMT_R16G16_UNORM */
         pSurface->internalFormatGL = GL_RG16;
         pSurface->formatGL = GL_RG;
+#if 0 /* bird: Wine uses GL_UNSIGNED_SHORT here. */
         pSurface->typeGL = GL_UNSIGNED_INT;
+#else
+        pSurface->typeGL = GL_UNSIGNED_SHORT;
+        AssertMsgFailed(("test me - SVGA3D_G16R16\n"));
+#endif
         break;
 
-    case SVGA3D_A16B16G16R16:
+    case SVGA3D_A16B16G16R16:           /* D3DFMT_A16B16G16R16 - WINED3DFMT_R16G16B16A16_UNORM */
         pSurface->internalFormatGL = GL_RGBA16;
-        pSurface->formatGL = GL_RG;
+        pSurface->formatGL = GL_RGBA;
+#if 0 /* bird: Wine uses GL_UNSIGNED_SHORT here. */
         pSurface->typeGL = GL_UNSIGNED_INT;     /* ??? */
+#else
+        pSurface->typeGL = GL_UNSIGNED_SHORT;
+        AssertMsgFailed(("Test me - SVGA3D_A16B16G16R16\n"));
+#endif
         break;
 
 #if 0
@@ -2247,7 +2615,7 @@ int vmsvga3dSurfaceDefine(PVGASTATE pThis, uint32_t sid, uint32_t surfaceFlags,
     PVMSVGA3DSTATE   pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
-    Log(("vmsvga3dSurfaceDefine: sid=%x surfaceFlags=%x format=%s (%x) multiSampleCount=%d autogenFilter=%d, cMipLevels=%d size=(%d,%d,%d)\n", 
+    Log(("vmsvga3dSurfaceDefine: sid=%x surfaceFlags=%x format=%s (%x) multiSampleCount=%d autogenFilter=%d, cMipLevels=%d size=(%d,%d,%d)\n",
          sid, surfaceFlags, vmsvgaSurfaceType2String(format), format, multisampleCount, autogenFilter, cMipLevels, pMipLevelSize->width, pMipLevelSize->height, pMipLevelSize->depth));
 
     AssertReturn(sid < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);
@@ -2258,8 +2626,9 @@ int vmsvga3dSurfaceDefine(PVGASTATE pThis, uint32_t sid, uint32_t surfaceFlags,
 
     if (sid >= pState->cSurfaces)
     {
-        pState->paSurface = (PVMSVGA3DSURFACE )RTMemRealloc(pState->paSurface, sizeof(VMSVGA3DSURFACE) * (sid + 1));
-        AssertReturn(pState->paSurface, VERR_NO_MEMORY);
+        void *pvNew = RTMemRealloc(pState->paSurface, sizeof(VMSVGA3DSURFACE) * (sid + 1));
+        AssertReturn(pvNew, VERR_NO_MEMORY);
+        pState->paSurface = (PVMSVGA3DSURFACE)pvNew;
         memset(&pState->paSurface[pState->cSurfaces], 0, sizeof(VMSVGA3DSURFACE) * (sid + 1 - pState->cSurfaces));
         for (uint32_t i = pState->cSurfaces; i < sid + 1; i++)
             pState->paSurface[i].id = SVGA3D_INVALID_ID;
@@ -2273,12 +2642,16 @@ int vmsvga3dSurfaceDefine(PVGASTATE pThis, uint32_t sid, uint32_t surfaceFlags,
     pSurface = &pState->paSurface[sid];
     memset(pSurface, 0, sizeof(*pSurface));
     pSurface->id                    = sid;
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+    pSurface->idAssociatedContextUnused = SVGA3D_INVALID_ID;
+#else
     pSurface->idAssociatedContext   = SVGA3D_INVALID_ID;
+#endif
     vmsvga3dSurfaceFormat2OGL(pSurface, format);
 
     pSurface->oglId.buffer = OPENGL_INVALID_ID;
 
-    /* The surface type is sort of undefined now, even though the hints and format can help to clear that up. 
+    /* The surface type is sort of undefined now, even though the hints and format can help to clear that up.
      * In some case we'll have to wait until the surface is used to create the D3D object.
      */
     switch (format)
@@ -2404,7 +2777,7 @@ int vmsvga3dSurfaceDefine(PVGASTATE pThis, uint32_t sid, uint32_t surfaceFlags,
         /* Unknown; decide later. */
         break;
     }
-   
+
     /* Allocate buffer to hold the surface data until we can move it into a D3D object */
     for (uint32_t iFace=0; iFace < pSurface->cFaces; iFace++)
     {
@@ -2433,32 +2806,54 @@ int vmsvga3dSurfaceDestroy(PVGASTATE pThis, uint32_t sid)
         &&  pState->paSurface[sid].id == sid)
     {
         PVMSVGA3DSURFACE pSurface = &pState->paSurface[sid];
-        PVMSVGA3DCONTEXT pContext = NULL;
+        PVMSVGA3DCONTEXT pContext;
 
         Log(("vmsvga3dSurfaceDestroy id %x\n", sid));
 
+#if 1 /* Windows is doing this, guess it makes sense here as well... */
+        /* Check all contexts if this surface is used as a render target or active texture. */
+        for (uint32_t cid = 0; cid < pState->cContexts; cid++)
+        {
+            pContext = pState->papContexts[cid];
+            if (pContext->id == cid)
+            {
+                for (uint32_t i = 0; i < RT_ELEMENTS(pContext->aSidActiveTexture); i++)
+                    if (pContext->aSidActiveTexture[i] == sid)
+                        pContext->aSidActiveTexture[i] = SVGA3D_INVALID_ID;
+                if (pContext->sidRenderTarget == sid)
+                    pContext->sidRenderTarget = SVGA3D_INVALID_ID;
+            }
+        }
+#endif
+
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+        pContext = &pState->SharedCtx;
+        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+#else
         /* @todo stricter checks for associated context */
         uint32_t cid = pSurface->idAssociatedContext;
         if (    cid <= pState->cContexts
-            &&  pState->paContext[cid].id == cid)
+            &&  pState->papContexts[cid]->id == cid)
         {
-            pContext = &pState->paContext[cid];
+            pContext = pState->papContexts[cid];
             VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
         }
-        else
+        /* If there is a GL buffer or something associated with the surface, we
+           really need something here, so pick any active context. */
+        else if (pSurface->oglId.buffer != OPENGL_INVALID_ID)
         {
-            /* Pick any active context; we need something here */
             for (cid = 0; cid < pState->cContexts; cid++)
             {
-                if (pState->paContext[cid].id == cid)
+                if (pState->papContexts[cid]->id == cid)
                 {
-                    pContext = &pState->paContext[cid];
+                    pContext = pState->papContexts[cid];
                     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
                     break;
                 }
             }
-            AssertReturn(pContext, VERR_INTERNAL_ERROR);    /* otherwise crashes/fails */
+            AssertReturn(pContext, VERR_INTERNAL_ERROR); /* otherwise crashes/fails; create temp context if this ever triggers! */
         }
+#endif
 
         switch (pSurface->flags & (SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP))
         {
@@ -2558,10 +2953,126 @@ int vmsvga3dSurfaceCopy(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3dSurfac
     return VINF_SUCCESS;
 }
 
+
+/**
+ * Save texture unpacking parameters and loads those appropriate for the given
+ * surface.
+ *
+ * @param   pState              The VMSVGA3D state structure.
+ * @param   pContext            The active context.
+ * @param   pSurface            The surface.
+ * @param   pSave               Where to save stuff.
+ */
+static void vmsvga3dSetUnpackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
+                                    PVMSVGAPACKPARAMS pSave)
+{
+    /*
+     * Save (ignore errors, setting the defaults we want and avoids restore).
+     */
+    pSave->iAlignment = 1;
+    VMSVGA3D_ASSERT_GL_CALL(glGetIntegerv(GL_UNPACK_ALIGNMENT, &pSave->iAlignment), pState, pContext);
+    pSave->cxRow = 0;
+    VMSVGA3D_ASSERT_GL_CALL(glGetIntegerv(GL_UNPACK_ROW_LENGTH, &pSave->cxRow), pState, pContext);
+
+#ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
+    pSave->cyImage = 0;
+    glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &pSave->cyImage);
+    Assert(pSave->cyImage == 0);
+
+    pSave->fSwapBytes = GL_FALSE;
+    glGetBooleanv(GL_UNPACK_SWAP_BYTES, &pSave->fSwapBytes);
+    Assert(pSave->fSwapBytes == GL_FALSE);
+
+    pSave->fLsbFirst = GL_FALSE;
+    glGetBooleanv(GL_UNPACK_LSB_FIRST, &pSave->fLsbFirst);
+    Assert(pSave->fLsbFirst == GL_FALSE);
+
+    pSave->cSkipRows = 0;
+    glGetIntegerv(GL_UNPACK_SKIP_ROWS, &pSave->cSkipRows);
+    Assert(pSave->cSkipRows == 0);
+
+    pSave->cSkipPixels = 0;
+    glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &pSave->cSkipPixels);
+    Assert(pSave->cSkipPixels == 0);
+
+    pSave->cSkipImages = 0;
+    glGetIntegerv(GL_UNPACK_SKIP_IMAGES, &pSave->cSkipImages);
+    Assert(pSave->cSkipImages == 0);
+
+    VMSVGA3D_CLEAR_GL_ERRORS();
+#endif
+
+    /*
+     * Setup unpack.
+     *
+     * Note! We use 1 as alignment here because we currently don't do any
+     *       aligning of line pitches anywhere.
+     */
+    NOREF(pSurface);
+    if (pSave->iAlignment != 1)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1), pState, pContext);
+    if (pSave->cxRow != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0), pState, pContext);
+#ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
+    if (pSave->cyImage != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0), pState, pContext);
+    if (pSave->fSwapBytes != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE), pState, pContext);
+    if (pSave->fLsbFirst != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE), pState, pContext);
+    if (pSave->cSkipRows != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_SKIP_ROWS, 0), pState, pContext);
+    if (pSave->cSkipPixels != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0), pState, pContext);
+    if (pSave->cSkipImages != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0), pState, pContext);
+#endif
+}
+
+
+/**
+ * Restores texture unpacking parameters.
+ *
+ * @param   pState              The VMSVGA3D state structure.
+ * @param   pContext            The active context.
+ * @param   pSurface            The surface.
+ * @param   pSave               Where stuff was saved.
+ */
+static void vmsvga3dRestoreUnpackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
+                                        PCVMSVGAPACKPARAMS pSave)
+{
+    NOREF(pSurface);
+    if (pSave->iAlignment != 1)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, pSave->iAlignment), pState, pContext);
+    if (pSave->cxRow != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, pSave->cxRow), pState, pContext);
+#ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
+    if (pSave->cyImage != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, pSave->cyImage), pState, pContext);
+    if (pSave->fSwapBytes != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_SWAP_BYTES, pSave->fSwapBytes), pState, pContext);
+    if (pSave->fLsbFirst != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_LSB_FIRST, pSave->fLsbFirst), pState, pContext);
+    if (pSave->cSkipRows != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_SKIP_ROWS, pSave->cSkipRows), pState, pContext);
+    if (pSave->cSkipPixels != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_SKIP_PIXELS, pSave->cSkipPixels), pState, pContext);
+    if (pSave->cSkipImages != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_UNPACK_SKIP_IMAGES, pSave->cSkipImages), pState, pContext);
+#endif
+}
+
+
 /* Create D3D texture object for the specified surface. */
-static int vmsvga3dCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext, PVMSVGA3DSURFACE pSurface)
+static int vmsvga3dCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext,
+                                 PVMSVGA3DSURFACE pSurface)
 {
     GLint activeTexture = 0;
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+    uint32_t idPrevCtx = pState->idActiveContext;
+    pContext = &pState->SharedCtx;
+    VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+#endif
 
     glGenTextures(1, &pSurface->oglId.texture);
     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
@@ -2574,23 +3085,29 @@ static int vmsvga3dCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContex
     glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
 
+    /* Set the unpacking parameters. */
+    VMSVGAPACKPARAMS SavedParams;
+    vmsvga3dSetUnpackParams(pState, pContext, pSurface, &SavedParams);
+
     if (pSurface->fDirty)
     {
         Log(("vmsvga3dCreateTexture: sync dirty texture\n"));
         for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
         {
-            if (pSurface->pMipmapLevels[i].fDirty)
+            /* Paranoia: Always do level 0 here to mirror the non-dirty case. */
+            if (pSurface->pMipmapLevels[i].fDirty || i == 0)
             {
-                Log(("vmsvga3dCreateTexture: sync dirty texture mipmap level %d (pitch %x)\n", i, pSurface->pMipmapLevels[i].cbSurfacePitch));
-
-                glTexImage2D(GL_TEXTURE_2D, 
-                             i, 
-                             pSurface->internalFormatGL, 
-                             pSurface->pMipmapLevels[i].size.width, 
-                             pSurface->pMipmapLevels[i].size.height, 
-                             0, 
-                             pSurface->formatGL, 
-                             pSurface->typeGL, 
+                if (pSurface->pMipmapLevels[i].fDirty)
+                    Log(("vmsvga3dCreateTexture: sync dirty texture mipmap level %d (pitch %x)\n", i, pSurface->pMipmapLevels[i].cbSurfacePitch));
+
+                glTexImage2D(GL_TEXTURE_2D,
+                             i,
+                             pSurface->internalFormatGL,
+                             pSurface->pMipmapLevels[i].size.width,
+                             pSurface->pMipmapLevels[i].size.height,
+                             0,
+                             pSurface->formatGL,
+                             pSurface->typeGL,
                              pSurface->pMipmapLevels[i].pSurfaceData);
 
                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
@@ -2601,27 +3118,45 @@ static int vmsvga3dCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContex
         pSurface->fDirty = false;
     }
     else
-        /* Reserve texture memory. */
-        glTexImage2D(GL_TEXTURE_2D, 
-                     0, 
-                     pSurface->internalFormatGL, 
-                     pSurface->pMipmapLevels[0].size.width, 
-                     pSurface->pMipmapLevels[0].size.height, 
-                     0, 
+    {
+        /* Allocate and initialize texture memory.  Passing the zero filled pSurfaceData avoids
+           exposing random host memory to the guest and helps a with the fedora 21 surface
+           corruption issues (launchpad, background, search field, login). */
+        glTexImage2D(GL_TEXTURE_2D,
+                     0,
+                     pSurface->internalFormatGL,
+                     pSurface->pMipmapLevels[0].size.width,
+                     pSurface->pMipmapLevels[0].size.height,
+                     0,
                      pSurface->formatGL,
-                     pSurface->typeGL, 
-                     NULL);
+                     pSurface->typeGL,
+                     pSurface->pMipmapLevels[0].pSurfaceData);
+        VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
+    }
+
+    /* Restore unpacking parameters. */
+    vmsvga3dRestoreUnpackParams(pState, pContext, pSurface, &SavedParams);
 
     /* Restore the old active texture. */
     glBindTexture(GL_TEXTURE_2D, activeTexture);
     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
 
     pSurface->flags              |= SVGA3D_SURFACE_HINT_TEXTURE;
+#ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
+    LogFlow(("vmsvga3dCreateTexture: sid=%x idAssociatedContext %#x -> %#x; oglId.texture=%#x\n",
+             pSurface->id, pSurface->idAssociatedContext, idAssociatedContext, pSurface->oglId.texture));
     pSurface->idAssociatedContext = idAssociatedContext;
+#endif
+
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+    if (idPrevCtx < pState->cContexts && pState->papContexts[idPrevCtx]->id == idPrevCtx)
+        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pState->papContexts[idPrevCtx]);
+#endif
     return VINF_SUCCESS;
 }
 
-int vmsvga3dSurfaceStretchBlt(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3dBox destBox, SVGA3dSurfaceImageId src, SVGA3dBox srcBox, SVGA3dStretchBltMode mode)
+int vmsvga3dSurfaceStretchBlt(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3dBox destBox,
+                              SVGA3dSurfaceImageId src, SVGA3dBox srcBox, SVGA3dStretchBltMode mode)
 {
     PVMSVGA3DSTATE      pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
     PVMSVGA3DSURFACE    pSurfaceSrc;
@@ -2643,7 +3178,17 @@ int vmsvga3dSurfaceStretchBlt(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3d
     AssertReturn(pSurfaceSrc->faces[0].numMipLevels > src.mipmap, VERR_INVALID_PARAMETER);
     AssertReturn(pSurfaceDest->faces[0].numMipLevels > dest.mipmap, VERR_INVALID_PARAMETER);
 
-    Log(("vmsvga3dSurfaceStretchBlt: src sid=%x (%d,%d)(%d,%d) dest sid=%x (%d,%d)(%d,%d) mode=%x\n", src.sid, srcBox.x, srcBox.y, srcBox.x + srcBox.w, srcBox.y + srcBox.h, dest.sid, destBox.x, destBox.y, destBox.x + destBox.w, destBox.y + destBox.h, mode));
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+    Log(("vmsvga3dSurfaceStretchBlt: src sid=%x (%d,%d)(%d,%d) dest sid=%x (%d,%d)(%d,%d) mode=%x\n",
+         src.sid, srcBox.x, srcBox.y, srcBox.x + srcBox.w, srcBox.y + srcBox.h,
+         dest.sid, destBox.x, destBox.y, destBox.x + destBox.w, destBox.y + destBox.h, mode));
+    cid = SVGA3D_INVALID_ID;
+    pContext = &pState->SharedCtx;
+    VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+#else
+    Log(("vmsvga3dSurfaceStretchBlt: src sid=%x cid=%x (%d,%d)(%d,%d) dest sid=%x cid=%x (%d,%d)(%d,%d) mode=%x\n",
+         src.sid, pSurfaceSrc->idAssociatedContext, srcBox.x, srcBox.y, srcBox.x + srcBox.w, srcBox.y + srcBox.h,
+         dest.sid, pSurfaceDest->idAssociatedContext, destBox.x, destBox.y, destBox.x + destBox.w, destBox.y + destBox.h, mode));
 
     /* @todo stricter checks for associated context */
     cid = pSurfaceDest->idAssociatedContext;
@@ -2651,13 +3196,14 @@ int vmsvga3dSurfaceStretchBlt(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3d
         cid = pSurfaceSrc->idAssociatedContext;
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSurfaceStretchBlt invalid context id!\n"));
         AssertFailedReturn(VERR_INVALID_PARAMETER);
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+#endif
 
     if (pSurfaceSrc->oglId.texture == OPENGL_INVALID_ID)
     {
@@ -2682,13 +3228,15 @@ int vmsvga3dSurfaceStretchBlt(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3d
     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
 
     /* Bind the source and destination objects to the right place. */
-    pState->ext.glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pSurfaceSrc->oglId.texture, src.mipmap);
+    pState->ext.glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+                                       pSurfaceSrc->oglId.texture, src.mipmap);
     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
-    pState->ext.glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pSurfaceDest->oglId.texture, dest.mipmap);
+    pState->ext.glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+                                       pSurfaceDest->oglId.texture, dest.mipmap);
     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
 
-    Log(("src conv. (%d,%d)(%d,%d); dest conv (%d,%d)(%d,%d)\n", srcBox.x, D3D_TO_OGL_Y_COORD(pSurfaceSrc, srcBox.y + srcBox.h),     
-         srcBox.x + srcBox.w, D3D_TO_OGL_Y_COORD(pSurfaceSrc, srcBox.y), destBox.x, D3D_TO_OGL_Y_COORD(pSurfaceDest, destBox.y + destBox.h),  
+    Log(("src conv. (%d,%d)(%d,%d); dest conv (%d,%d)(%d,%d)\n", srcBox.x, D3D_TO_OGL_Y_COORD(pSurfaceSrc, srcBox.y + srcBox.h),
+         srcBox.x + srcBox.w, D3D_TO_OGL_Y_COORD(pSurfaceSrc, srcBox.y), destBox.x, D3D_TO_OGL_Y_COORD(pSurfaceDest, destBox.y + destBox.h),
          destBox.x + destBox.w, D3D_TO_OGL_Y_COORD(pSurfaceDest, destBox.y)));
 
     pState->ext.glBlitFramebuffer(srcBox.x,
@@ -2711,7 +3259,7 @@ int vmsvga3dSurfaceStretchBlt(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3d
 #endif
                                   destBox.x + destBox.w,                                    /* exclusive. */
 #ifdef MANUAL_FLIP_SURFACE_DATA
-                                  D3D_TO_OGL_Y_COORD(pSurfaceDest, destBox.y),              /* exclusive */                         
+                                  D3D_TO_OGL_Y_COORD(pSurfaceDest, destBox.y),              /* exclusive */
 #else
                                   destBox.y + destBox.h,
 #endif
@@ -2726,7 +3274,117 @@ int vmsvga3dSurfaceStretchBlt(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3d
     return VINF_SUCCESS;
 }
 
-int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceImageId host, SVGA3dTransferType transfer, uint32_t cCopyBoxes, SVGA3dCopyBox *pBoxes)
+/**
+ * Save texture packing parameters and loads those appropriate for the given
+ * surface.
+ *
+ * @param   pState              The VMSVGA3D state structure.
+ * @param   pContext            The active context.
+ * @param   pSurface            The surface.
+ * @param   pSave               Where to save stuff.
+ */
+static void vmsvga3dSetPackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
+                                  PVMSVGAPACKPARAMS pSave)
+{
+    /*
+     * Save (ignore errors, setting the defaults we want and avoids restore).
+     */
+    pSave->iAlignment = 1;
+    VMSVGA3D_ASSERT_GL_CALL(glGetIntegerv(GL_UNPACK_ALIGNMENT, &pSave->iAlignment), pState, pContext);
+    pSave->cxRow = 0;
+    VMSVGA3D_ASSERT_GL_CALL(glGetIntegerv(GL_UNPACK_ROW_LENGTH, &pSave->cxRow), pState, pContext);
+
+#ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
+    pSave->cyImage = 0;
+    glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &pSave->cyImage);
+    Assert(pSave->cyImage == 0);
+
+    pSave->fSwapBytes = GL_FALSE;
+    glGetBooleanv(GL_PACK_SWAP_BYTES, &pSave->fSwapBytes);
+    Assert(pSave->fSwapBytes == GL_FALSE);
+
+    pSave->fLsbFirst = GL_FALSE;
+    glGetBooleanv(GL_PACK_LSB_FIRST, &pSave->fLsbFirst);
+    Assert(pSave->fLsbFirst == GL_FALSE);
+
+    pSave->cSkipRows = 0;
+    glGetIntegerv(GL_PACK_SKIP_ROWS, &pSave->cSkipRows);
+    Assert(pSave->cSkipRows == 0);
+
+    pSave->cSkipPixels = 0;
+    glGetIntegerv(GL_PACK_SKIP_PIXELS, &pSave->cSkipPixels);
+    Assert(pSave->cSkipPixels == 0);
+
+    pSave->cSkipImages = 0;
+    glGetIntegerv(GL_PACK_SKIP_IMAGES, &pSave->cSkipImages);
+    Assert(pSave->cSkipImages == 0);
+
+    VMSVGA3D_CLEAR_GL_ERRORS();
+#endif
+
+    /*
+     * Setup unpack.
+     *
+     * Note! We use 1 as alignment here because we currently don't do any
+     *       aligning of line pitches anywhere.
+     */
+    NOREF(pSurface);
+    if (pSave->iAlignment != 1)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_ALIGNMENT, 1), pState, pContext);
+    if (pSave->cxRow != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_ROW_LENGTH, 0), pState, pContext);
+#ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
+    if (pSave->cyImage != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0), pState, pContext);
+    if (pSave->fSwapBytes != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE), pState, pContext);
+    if (pSave->fLsbFirst != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_LSB_FIRST, GL_FALSE), pState, pContext);
+    if (pSave->cSkipRows != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_SKIP_ROWS, 0), pState, pContext);
+    if (pSave->cSkipPixels != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_SKIP_PIXELS, 0), pState, pContext);
+    if (pSave->cSkipImages != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_SKIP_IMAGES, 0), pState, pContext);
+#endif
+}
+
+
+/**
+ * Restores texture packing parameters.
+ *
+ * @param   pState              The VMSVGA3D state structure.
+ * @param   pContext            The active context.
+ * @param   pSurface            The surface.
+ * @param   pSave               Where stuff was saved.
+ */
+static void vmsvga3dRestorePackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
+                                      PCVMSVGAPACKPARAMS pSave)
+{
+    NOREF(pSurface);
+    if (pSave->iAlignment != 1)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_ALIGNMENT, pSave->iAlignment), pState, pContext);
+    if (pSave->cxRow != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_ROW_LENGTH, pSave->cxRow), pState, pContext);
+#ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
+    if (pSave->cyImage != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_IMAGE_HEIGHT, pSave->cyImage), pState, pContext);
+    if (pSave->fSwapBytes != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_SWAP_BYTES, pSave->fSwapBytes), pState, pContext);
+    if (pSave->fLsbFirst != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_LSB_FIRST, pSave->fLsbFirst), pState, pContext);
+    if (pSave->cSkipRows != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_SKIP_ROWS, pSave->cSkipRows), pState, pContext);
+    if (pSave->cSkipPixels != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_SKIP_PIXELS, pSave->cSkipPixels), pState, pContext);
+    if (pSave->cSkipImages != 0)
+        VMSVGA3D_ASSERT_GL_CALL(glPixelStorei(GL_PACK_SKIP_IMAGES, pSave->cSkipImages), pState, pContext);
+#endif
+}
+
+
+int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceImageId host, SVGA3dTransferType transfer,
+                       uint32_t cCopyBoxes, SVGA3dCopyBox *pBoxes)
 {
     PVMSVGA3DSTATE          pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
     PVMSVGA3DSURFACE        pSurface;
@@ -2743,9 +3401,9 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
     pMipLevel = &pSurface->pMipmapLevels[host.mipmap];
 
     if (pSurface->flags & SVGA3D_SURFACE_HINT_TEXTURE)
-        Log(("vmsvga3dSurfaceDMA TEXTURE guestptr gmr=%x offset=%x pitch=%x host sid=%x face=%d mipmap=%d transfer=%x cCopyBoxes=%d\n", guest.ptr.gmrId, guest.ptr.offset, guest.pitch, host.sid, host.face, host.mipmap, transfer, cCopyBoxes));
+        Log(("vmsvga3dSurfaceDMA TEXTURE guestptr gmr=%x offset=%x pitch=%x host sid=%x face=%d mipmap=%d transfer=%s cCopyBoxes=%d\n", guest.ptr.gmrId, guest.ptr.offset, guest.pitch, host.sid, host.face, host.mipmap, (transfer == SVGA3D_WRITE_HOST_VRAM) ? "READ" : "WRITE", cCopyBoxes));
     else
-        Log(("vmsvga3dSurfaceDMA guestptr gmr=%x offset=%x pitch=%x host sid=%x face=%d mipmap=%d transfer=%x cCopyBoxes=%d\n", guest.ptr.gmrId, guest.ptr.offset, guest.pitch, host.sid, host.face, host.mipmap, transfer, cCopyBoxes));
+        Log(("vmsvga3dSurfaceDMA guestptr gmr=%x offset=%x pitch=%x host sid=%x face=%d mipmap=%d transfer=%s cCopyBoxes=%d\n", guest.ptr.gmrId, guest.ptr.offset, guest.pitch, host.sid, host.face, host.mipmap, (transfer == SVGA3D_WRITE_HOST_VRAM) ? "READ" : "WRITE", cCopyBoxes));
 
     if (pSurface->oglId.texture == OPENGL_INVALID_ID)
     {
@@ -2783,13 +3441,13 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
             cbSrcPitch = (guest.pitch == 0) ? pBoxes[i].w * pSurface->cbBlock : guest.pitch;
 #ifdef MANUAL_FLIP_SURFACE_DATA
             pBufferStart =    (uint8_t *)pMipLevel->pSurfaceData
-                            + pBoxes[i].x * pSurface->cbBlock 
+                            + pBoxes[i].x * pSurface->cbBlock
                             + pMipLevel->cbSurface - pBoxes[i].y * pMipLevel->cbSurfacePitch
                             - pMipLevel->cbSurfacePitch;      /* flip image during copy */
 #else
             pBufferStart = (uint8_t *)pMipLevel->pSurfaceData + uDestOffset;
 #endif
-            rc = vmsvgaGMRTransfer(pThis, 
+            rc = vmsvgaGMRTransfer(pThis,
                                    transfer,
                                    pBufferStart,
 #ifdef MANUAL_FLIP_SURFACE_DATA
@@ -2812,15 +3470,19 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
     }
     else
     {
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+        PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;
+#else
         /* @todo stricter checks for associated context */
         uint32_t cid = pSurface->idAssociatedContext;
         if (    cid >= pState->cContexts
-            ||  pState->paContext[cid].id != cid)
+            ||  pState->papContexts[cid]->id != cid)
         {
-            Log(("vmsvga3dSurfaceDMA invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->paContext[cid].id));
+            Log(("vmsvga3dSurfaceDMA invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
             AssertFailedReturn(VERR_INVALID_PARAMETER);
         }
-        PVMSVGA3DCONTEXT pContext = &pState->paContext[cid];
+        PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
+#endif
         VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
         for (unsigned i = 0; i < cCopyBoxes; i++)
@@ -2868,32 +3530,42 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
                 {
                     GLint activeTexture;
 
+                    /* Must bind texture to the current context in order to read it. */
                     glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
                     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
 
                     glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
                     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
 
+                    /* Set row length and alignment of the input data. */
+                    VMSVGAPACKPARAMS SavedParams;
+                    vmsvga3dSetPackParams(pState, pContext, pSurface, &SavedParams);
+
                     glGetTexImage(GL_TEXTURE_2D,
                                   host.mipmap,
-                                  pSurface->formatGL, 
-                                  pSurface->typeGL, 
+                                  pSurface->formatGL,
+                                  pSurface->typeGL,
                                   pDoubleBuffer);
                     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
 
+                    vmsvga3dRestorePackParams(pState, pContext, pSurface, &SavedParams);
+
                     /* Restore the old active texture. */
                     glBindTexture(GL_TEXTURE_2D, activeTexture);
                     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
 
                     uDestOffset = pBoxes[i].x * pSurface->cbBlock + pBoxes[i].y * pMipLevel->cbSurfacePitch;
-                    AssertReturn(uDestOffset + pBoxes[i].w * pSurface->cbBlock + (pBoxes[i].h - 1) * pMipLevel->cbSurfacePitch <= pMipLevel->cbSurface, VERR_INTERNAL_ERROR);
+                    AssertReturnStmt(   uDestOffset + pBoxes[i].w * pSurface->cbBlock + (pBoxes[i].h - 1) * pMipLevel->cbSurfacePitch
+                                     <= pMipLevel->cbSurface,
+                                     RTMemFree(pDoubleBuffer),
+                                     VERR_INTERNAL_ERROR);
 
                     cbSurfacePitch = pMipLevel->cbSurfacePitch;
 
 #ifdef MANUAL_FLIP_SURFACE_DATA
-                    pBufferStart =   pDoubleBuffer 
-                                   + pBoxes[i].x * pSurface->cbBlock 
-                                   + pMipLevel->cbSurface - pBoxes[i].y * cbSurfacePitch 
+                    pBufferStart =   pDoubleBuffer
+                                   + pBoxes[i].x * pSurface->cbBlock
+                                   + pMipLevel->cbSurface - pBoxes[i].y * cbSurfacePitch
                                    - cbSurfacePitch;      /* flip image during copy */
 #else
                     pBufferStart = pDoubleBuffer + uDestOffset;
@@ -2909,7 +3581,7 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
 #endif
                 }
 
-                rc = vmsvgaGMRTransfer(pThis, 
+                rc = vmsvgaGMRTransfer(pThis,
                                        transfer,
                                        pBufferStart,
 #ifdef MANUAL_FLIP_SURFACE_DATA
@@ -2928,7 +3600,6 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
                 if (transfer == SVGA3D_WRITE_HOST_VRAM)
                 {
                     GLint activeTexture = 0;
-                    GLint alignment;
 
                     glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
                     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
@@ -2940,9 +3611,8 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
                     Log(("vmsvga3dSurfaceDMA: copy texture mipmap level %d (pitch %x)\n", host.mipmap, pMipLevel->cbSurfacePitch));
 
                     /* Set row length and alignment of the input data. */
-                    glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
-                    glPixelStorei(GL_UNPACK_ROW_LENGTH, pBoxes[i].w);
-                    glPixelStorei(GL_UNPACK_ALIGNMENT, pSurface->cbBlock);
+                    VMSVGAPACKPARAMS SavedParams;
+                    vmsvga3dSetUnpackParams(pState, pContext, pSurface, &SavedParams); /** @todo do we need to set ROW_LENGTH to w here? */
 
                     glTexSubImage2D(GL_TEXTURE_2D,
                                     host.mipmap,
@@ -2950,15 +3620,14 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
                                     pBoxes[i].y,
                                     pBoxes[i].w,
                                     pBoxes[i].h,
-                                    pSurface->formatGL, 
-                                    pSurface->typeGL, 
+                                    pSurface->formatGL,
+                                    pSurface->typeGL,
                                     pDoubleBuffer);
 
                     VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
 
                     /* Restore old values. */
-                    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-                    glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
+                    vmsvga3dRestoreUnpackParams(pState, pContext, pSurface, &SavedParams);
 
                     /* Restore the old active texture. */
                     glBindTexture(GL_TEXTURE_2D, activeTexture);
@@ -2979,39 +3648,63 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
             case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
             case SVGA3D_SURFACE_HINT_INDEXBUFFER:
             {
-                uint8_t *pData;
-                unsigned uDestOffset;
-
                 Assert(pBoxes[i].h == 1);
 
+                VMSVGA3D_CLEAR_GL_ERRORS();
                 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pSurface->oglId.buffer);
-                VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
-
-                pData = (uint8_t *)pState->ext.glMapBuffer(GL_ARRAY_BUFFER, (transfer == SVGA3D_READ_HOST_VRAM) ? GL_READ_ONLY : GL_WRITE_ONLY);
-                VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
-                Assert(pData);
-
-                uDestOffset = pBoxes[i].x * pSurface->cbBlock + pBoxes[i].y * pMipLevel->cbSurfacePitch;
-                AssertReturn(uDestOffset + pBoxes[i].w * pSurface->cbBlock + (pBoxes[i].h - 1) * pMipLevel->cbSurfacePitch <= pMipLevel->cbSurface, VERR_INTERNAL_ERROR);
-
-                Log(("Lock %s memory for rectangle (%d,%d)(%d,%d)\n", (fVertex) ? "vertex" : "index", pBoxes[i].x, pBoxes[i].y, pBoxes[i].x + pBoxes[i].w, pBoxes[i].y + pBoxes[i].h));
-
-                rc = vmsvgaGMRTransfer(pThis, 
-                                       transfer,
-                                       pData + uDestOffset, 
-                                       pMipLevel->cbSurfacePitch, 
-                                       guest.ptr,
-                                       pBoxes[i].srcx * pSurface->cbBlock + pBoxes[i].srcy * cbSrcPitch,
-                                       cbSrcPitch,
-                                       pBoxes[i].w * pSurface->cbBlock,
-                                       pBoxes[i].h);
-                AssertRC(rc);
-
-                Log4(("first line:\n%.*Rhxd\n", cbSrcPitch, pData));
+                if (VMSVGA3D_GL_IS_SUCCESS(pContext))
+                {
+                    GLenum enmGlTransfer = (transfer == SVGA3D_READ_HOST_VRAM) ? GL_READ_ONLY : GL_WRITE_ONLY;
+                    uint8_t *pbData = (uint8_t *)pState->ext.glMapBuffer(GL_ARRAY_BUFFER, enmGlTransfer);
+                    if (RT_LIKELY(pbData != NULL))
+                    {
+#if defined(VBOX_STRICT) && defined(RT_OS_DARWIN)
+                        GLint cbStrictBufSize;
+                        glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &cbStrictBufSize);
+                        Assert(VMSVGA3D_GL_IS_SUCCESS(pContext));
+# ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+                        AssertMsg(cbStrictBufSize >= (int32_t)pMipLevel->cbSurface,
+                                  ("cbStrictBufSize=%#x cbSurface=%#x pContext->id=%#x\n", (uint32_t)cbStrictBufSize, pMipLevel->cbSurface, pContext->id));
+# else
+                        AssertMsg(cbStrictBufSize >= (int32_t)pMipLevel->cbSurface,
+                                  ("cbStrictBufSize=%#x cbSurface=%#x isAssociatedContext=%#x pContext->id=%#x\n", (uint32_t)cbStrictBufSize, pMipLevel->cbSurface, pSurface->idAssociatedContext, pContext->id));
+# endif
+#endif
 
-                pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER);
-                VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
+                        unsigned offDst = pBoxes[i].x * pSurface->cbBlock + pBoxes[i].y * pMipLevel->cbSurfacePitch;
+                        if (RT_LIKELY(   offDst + pBoxes[i].w * pSurface->cbBlock  + (pBoxes[i].h - 1) * pMipLevel->cbSurfacePitch
+                                      <= pMipLevel->cbSurface))
+                        {
+                            Log(("Lock %s memory for rectangle (%d,%d)(%d,%d)\n", (fVertex) ? "vertex" : "index",
+                                 pBoxes[i].x, pBoxes[i].y, pBoxes[i].x + pBoxes[i].w, pBoxes[i].y + pBoxes[i].h));
+
+                            rc = vmsvgaGMRTransfer(pThis,
+                                                   transfer,
+                                                   pbData + offDst,
+                                                   pMipLevel->cbSurfacePitch,
+                                                   guest.ptr,
+                                                   pBoxes[i].srcx * pSurface->cbBlock + pBoxes[i].srcy * cbSrcPitch,
+                                                   cbSrcPitch,
+                                                   pBoxes[i].w * pSurface->cbBlock,
+                                                   pBoxes[i].h);
+                            AssertRC(rc);
+
+                            Log4(("first line:\n%.*Rhxd\n", cbSrcPitch, pbData));
+                        }
+                        else
+                        {
+                            AssertFailed();
+                            rc = VERR_INTERNAL_ERROR;
+                        }
 
+                        pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER);
+                        VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
+                    }
+                    else
+                        VMSVGA3D_GL_GET_AND_COMPLAIN(pState, pContext, ("glMapBuffer(GL_ARRAY_BUFFER, %#x) -> NULL\n", enmGlTransfer));
+                }
+                else
+                    VMSVGA3D_GL_COMPLAIN(pState, pContext, ("glBindBuffer(GL_ARRAY_BUFFER, %#x)\n", pSurface->oglId.buffer));
                 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, 0);
                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
                 break;
@@ -3046,7 +3739,7 @@ int vmsvga3dSurfaceBlitToScreen(PVGASTATE pThis, uint32_t dest, SVGASignedRect d
         /* easy case; no clipping */
         SVGA3dCopyBox        box;
         SVGA3dGuestImage     dst;
-       
+
         box.x       = destRect.left;
         box.y       = destRect.top;
         box.z       = 0;
@@ -3082,7 +3775,7 @@ int vmsvga3dSurfaceBlitToScreen(PVGASTATE pThis, uint32_t dest, SVGASignedRect d
 
         /* @todo merge into one SurfaceDMA call */
         for (uint32_t i = 0; i < cRects; i++)
-        {   
+        {
             /* The clipping rectangle is relative to the top-left corner of srcRect & destRect. Adjust here. */
             box.srcx = srcRect.left + pRect[i].left;
             box.srcy = srcRect.top  + pRect[i].top;
@@ -3117,7 +3810,9 @@ int vmsvga3dGenerateMipmaps(PVGASTATE pThis, uint32_t sid, SVGA3dTextureFilter f
     AssertReturn(sid < pState->cSurfaces && pState->paSurface[sid].id == sid, VERR_INVALID_PARAMETER);
 
     pSurface = &pState->paSurface[sid];
+#ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
     AssertReturn(pSurface->idAssociatedContext != SVGA3D_INVALID_ID, VERR_INTERNAL_ERROR);
+#endif
 
     Assert(filter != SVGA3D_TEX_FILTER_FLATCUBIC);
     Assert(filter != SVGA3D_TEX_FILTER_GAUSSIANCUBIC);
@@ -3125,17 +3820,23 @@ int vmsvga3dGenerateMipmaps(PVGASTATE pThis, uint32_t sid, SVGA3dTextureFilter f
 
     Log(("vmsvga3dGenerateMipmaps: sid=%x filter=%d\n", sid, filter));
 
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+    cid = SVGA3D_INVALID_ID;
+    pContext = &pState->SharedCtx;
+    VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+#else
     /* @todo stricter checks for associated context */
     cid = pSurface->idAssociatedContext;
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dGenerateMipmaps invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+#endif
 
     if (pSurface->oglId.texture == OPENGL_INVALID_ID)
     {
@@ -3158,7 +3859,7 @@ int vmsvga3dGenerateMipmaps(PVGASTATE pThis, uint32_t sid, SVGA3dTextureFilter f
     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
 
     /* Generate the mip maps. */
-    pState->ext.glGenerateMipmap(GL_TEXTURE_2D);    
+    pState->ext.glGenerateMipmap(GL_TEXTURE_2D);
     VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
 
     /* Restore the old texture. */
@@ -3175,7 +3876,7 @@ int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3
     int                 rc = VINF_SUCCESS;
     PVMSVGA3DCONTEXT    pContext;
     uint32_t            cid;
-    struct 
+    struct
     {
         uint32_t        x;
         uint32_t        y;
@@ -3188,8 +3889,20 @@ int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3
     AssertReturn(sid < pState->cSurfaces && pState->paSurface[sid].id == sid, VERR_INVALID_PARAMETER);
 
     pSurface = &pState->paSurface[sid];
+#ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
     AssertReturn(pSurface->idAssociatedContext != SVGA3D_INVALID_ID, VERR_INTERNAL_ERROR);
+#endif
 
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+    /* @todo stricter checks for associated context */
+    Log(("vmsvga3dCommandPresent: sid=%x cRects=%d\n", sid, cRects));
+    for (uint32_t i=0; i < cRects; i++)
+        Log(("vmsvga3dCommandPresent: rectangle %d src=(%d,%d) (%d,%d)(%d,%d)\n", i, pRect[i].srcx, pRect[i].srcy, pRect[i].x, pRect[i].y, pRect[i].x + pRect[i].w, pRect[i].y + pRect[i].h));
+
+    cid = SVGA3D_INVALID_ID;
+    pContext = &pState->SharedCtx;
+    VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+#else
     /* @todo stricter checks for associated context */
     cid = pSurface->idAssociatedContext;
     Log(("vmsvga3dCommandPresent: sid=%x cRects=%d cid=%x\n", sid, cRects, cid));
@@ -3199,13 +3912,14 @@ int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3
     }
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dCommandPresent invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+#endif
 
     /* Source surface different size? */
     if (pSurface->pMipmapLevels[0].size.width  != pThis->svga.uWidth ||
@@ -3487,21 +4201,23 @@ DECLCALLBACK(int) vmsvga3dXEventThread(RTTHREAD ThreadSelf, void *pvUser)
  * @returns VBox status code.
  * @param   pThis           VGA device instance data.
  * @param   cid             Context id
- * @param   fOtherProfile   When clear, the context is created using the default
- *                          OpenGL profile.  When set, it's created using the
- *                          alternative profile.  The latter is only allowed if
- *                          the VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE is set.
+ * @param   fFlags          VMSVGA3D_DEF_CTX_F_XXX.
  */
-int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fOtherProfile)
+static int vmsvga3dContextDefineOgl(PVGASTATE pThis, uint32_t cid, uint32_t fFlags)
 {
     int                     rc;
     PVMSVGA3DCONTEXT        pContext;
     PVMSVGA3DSTATE          pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
 
     AssertReturn(pState, VERR_NO_MEMORY);
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+    AssertReturn(   cid < SVGA3D_MAX_CONTEXT_IDS
+                 || (cid == VMSVGA3D_SHARED_CTX_ID && (fFlags & VMSVGA3D_DEF_CTX_F_SHARED_CTX)), VERR_INVALID_PARAMETER);
+#else
     AssertReturn(cid < SVGA3D_MAX_CONTEXT_IDS, VERR_INVALID_PARAMETER);
+#endif
 #if !defined(VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE) || !(defined(RT_OS_DARWIN))
-    AssertReturn(!fOtherProfile, VERR_INTERNAL_ERROR_3);
+    AssertReturn(!(fFlags & VMSVGA3D_DEF_CTX_F_OTHER_PROFILE), VERR_INTERNAL_ERROR_3);
 #endif
 
     Log(("vmsvga3dContextDefine id %x\n", cid));
@@ -3509,26 +4225,74 @@ int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fOtherProfile)
     if (pState->idTestContext == SVGA_ID_INVALID)
     {
         pState->idTestContext = 207;
-        rc = vmsvga3dContextDefine(pThis, pState->idTestContext, false /*fOtherProfile*/);
+        rc = vmsvga3dContextDefine(pThis, pState->idTestContext);
         AssertRCReturn(rc, rc);
     }
 #endif
 
-    if (cid >= pState->cContexts)
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+    if (cid == VMSVGA3D_SHARED_CTX_ID)
+        pContext = &pState->SharedCtx;
+    else
+#endif
     {
-        pState->paContext = (PVMSVGA3DCONTEXT)RTMemRealloc(pState->paContext, sizeof(VMSVGA3DCONTEXT) * (cid + 1));
-        AssertReturn(pState->paContext, VERR_NO_MEMORY);
-        memset(&pState->paContext[pState->cContexts], 0, sizeof(VMSVGA3DCONTEXT) * (cid + 1 - pState->cContexts));
-        for (uint32_t i = pState->cContexts; i < cid + 1; i++)
-            pState->paContext[i].id = SVGA3D_INVALID_ID;
+        if (cid >= pState->cContexts)
+        {
+            /* Grow the array. */
+            uint32_t cNew = RT_ALIGN(cid + 15, 16);
+            void *pvNew = RTMemRealloc(pState->papContexts, sizeof(pState->papContexts[0]) * cNew);
+            AssertReturn(pvNew, VERR_NO_MEMORY);
+            pState->papContexts = (PVMSVGA3DCONTEXT *)pvNew;
+            while (pState->cContexts < cNew)
+            {
+                pContext = (PVMSVGA3DCONTEXT)RTMemAllocZ(sizeof(*pContext));
+                AssertReturn(pContext, VERR_NO_MEMORY);
+                pContext->id = SVGA3D_INVALID_ID;
+                pState->papContexts[pState->cContexts++] = pContext;
+            }
+        }
+        /* If one already exists with this id, then destroy it now. */
+        if (pState->papContexts[cid]->id != SVGA3D_INVALID_ID)
+            vmsvga3dContextDestroy(pThis, cid);
 
-        pState->cContexts = cid + 1;
+        pContext = pState->papContexts[cid];
     }
-    /* If one already exists with this id, then destroy it now. */
-    if (pState->paContext[cid].id != SVGA3D_INVALID_ID)
-        vmsvga3dContextDestroy(pThis, cid);
 
-    pContext = &pState->paContext[cid];
+    /*
+     * Find the shared context (necessary for sharing e.g. textures between contexts).
+     */
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+    PVMSVGA3DCONTEXT pSharedCtx = NULL;
+    if (!(fFlags & (VMSVGA3D_DEF_CTX_F_INIT | VMSVGA3D_DEF_CTX_F_SHARED_CTX)))
+    {
+        pSharedCtx = &pState->SharedCtx;
+        if (pSharedCtx->id != VMSVGA3D_SHARED_CTX_ID)
+        {
+            rc = vmsvga3dContextDefineOgl(pThis, VMSVGA3D_SHARED_CTX_ID, VMSVGA3D_DEF_CTX_F_SHARED_CTX);
+            AssertLogRelRCReturn(rc, rc);
+        }
+    }
+#else
+    // TODO isn't this default on Linux since OpenGL 1.1?
+    /* Find the first active context to share the display list with (necessary for sharing e.g. textures between contexts). */
+    PVMSVGA3DCONTEXT pSharedCtx = NULL;
+    for (uint32_t i = 0; i < pState->cContexts; i++)
+        if (   pState->papContexts[i]->id != SVGA3D_INVALID_ID
+            && i != cid
+# ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+            && pState->papContexts[i]->fOtherProfile == RT_BOOL(fFlags & VMSVGA3D_DEF_CTX_F_OTHER_PROFILE)
+# endif
+           )
+        {
+            Log(("Sharing display lists between cid=%d and cid=%d\n", pContext->id, i));
+            pSharedCtx = pState->papContexts[i];
+            break;
+        }
+#endif
+
+    /*
+     * Initialize the context.
+     */
     memset(pContext, 0, sizeof(*pContext));
     pContext->id                = cid;
     for (uint32_t i = 0; i < RT_ELEMENTS(pContext->aSidActiveTexture); i++)
@@ -3579,8 +4343,8 @@ int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fOtherProfile)
 
     pContext->hdc   = GetDC(pContext->hwnd);
     AssertMsgReturn(pContext->hdc, ("GetDC %x failed with %d\n", pContext->hwnd, GetLastError()), VERR_INTERNAL_ERROR);
-    
-    PIXELFORMATDESCRIPTOR pfd = { 
+
+    PIXELFORMATDESCRIPTOR pfd = {
         sizeof(PIXELFORMATDESCRIPTOR),  /*  size of this pfd */
         1,                              /* version number */
         PFD_DRAW_TO_WINDOW |            /* support window */
@@ -3599,7 +4363,7 @@ int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fOtherProfile)
         PFD_MAIN_PLANE,                 /* main layer */
         0,                              /* reserved */
         0, 0, 0                         /* layer masks ignored */
-    }; 
+    };
     int     pixelFormat;
     BOOL    ret;
 
@@ -3612,39 +4376,19 @@ int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fOtherProfile)
     AssertMsgReturn(ret == TRUE, ("SetPixelFormat failed with %d\n", GetLastError()), VERR_INTERNAL_ERROR);
 
     pContext->hglrc = wglCreateContext(pContext->hdc);
-    AssertMsgReturn(pContext->hglrc, ("wglCreateContext %x failed with %d\n", pContext->hdc, GetLastError()), VERR_INTERNAL_ERROR);    
+    AssertMsgReturn(pContext->hglrc, ("wglCreateContext %x failed with %d\n", pContext->hdc, GetLastError()), VERR_INTERNAL_ERROR);
 
-    // TODO isn't this default on Linux since OpenGL 1.1?
-    /* Find the first active context to share the display list with (necessary for sharing e.g. textures between contexts). */
-    for (uint32_t i = 0; i < pState->cContexts; i++)
+    if (pSharedCtx)
     {
-        if (    pState->paContext[i].id != SVGA3D_INVALID_ID
-            &&  i != pContext->id)
-        {
-            Log(("Sharing display lists between cid=%d and cid=%d\n", pContext->id, i));
-            ret = wglShareLists(pState->paContext[i].hglrc, pContext->hglrc);
-            Assert(ret == TRUE);
-            break;
-        }
+        ret = wglShareLists(pSharedCtx->hglrc, pContext->hglrc);
+        AssertMsg(ret == TRUE, ("wglShareLists(%p, %p) failed with %d\n", pSharedCtx->hglrc, pContext->hglrc, GetLastError()));
     }
 
 #elif defined(RT_OS_DARWIN)
-    pContext->fOtherProfile = fOtherProfile;
+    pContext->fOtherProfile = RT_BOOL(fFlags & VMSVGA3D_DEF_CTX_F_OTHER_PROFILE);
 
-    /* Find the first active context to share the display list with (necessary for sharing e.g. textures between contexts). */
-    NativeNSOpenGLContextRef shareContext = NULL;
-    for (uint32_t i = 0; i < pState->cContexts; i++)
-    {
-        if (    pState->paContext[i].id != SVGA3D_INVALID_ID
-            &&  i != pContext->id
-            &&  pState->paContext[i].fOtherProfile == fOtherProfile)
-        {
-            Log(("Sharing display lists between cid=%d and cid=%d\n", pContext->id, i));
-            shareContext = pState->paContext[i].cocoaContext;
-            break;
-        }
-    }
-    vmsvga3dCocoaCreateContext(&pContext->cocoaContext, shareContext, fOtherProfile);
+    NativeNSOpenGLContextRef shareContext = pSharedCtx ? pSharedCtx->cocoaContext : NULL;
+    vmsvga3dCocoaCreateContext(&pContext->cocoaContext, shareContext, pContext->fOtherProfile);
     NativeNSViewRef pHostView = (NativeNSViewRef)pThis->svga.u64HostWindowId;
     vmsvga3dCocoaCreateView(&pContext->cocoaView, pHostView);
 
@@ -3652,7 +4396,7 @@ int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fOtherProfile)
     Window hostWindow = (Window)pThis->svga.u64HostWindowId;
 
     if (pState->display == NULL)
-    { 
+    {
         /* get an X display and make sure we have glX 1.3 */
         pState->display = XOpenDisplay(0);
         Assert(pState->display);
@@ -3693,19 +4437,7 @@ int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fOtherProfile)
 
     /* the window is hidden by default and only mapped when CommandPresent is executed on it */
 
-    /* Find the first active context to share the display list with (necessary for sharing e.g. textures between contexts). */
-    GLXContext shareContext = NULL;
-    for (uint32_t i = 0; i < pState->cContexts; i++)
-    {
-        if (    pState->paContext[i].id != SVGA3D_INVALID_ID
-            &&  i != pContext->id)
-        {
-            Log(("Sharing display lists between cid=%d and cid=%d\n", pContext->id, i));
-            shareContext = pState->paContext[i].glxContext;
-            break;
-        }
-    }
-
+    GLXContext shareContext = pSharedCtx ? pSharedCtx->glxContext : NULL;
     pContext->glxContext = glXCreateContext(pState->display, vi, shareContext, GL_TRUE);
     AssertMsgReturn(pContext->glxContext, ("glXCreateContext failed"), VERR_INTERNAL_ERROR);
 #endif
@@ -3750,6 +4482,20 @@ int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fOtherProfile)
     return VINF_SUCCESS;
 }
 
+
+/**
+ * Create a new 3d context
+ *
+ * @returns VBox status code.
+ * @param   pThis           VGA device instance data.
+ * @param   cid             Context id
+ */
+int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid)
+{
+    return vmsvga3dContextDefineOgl(pThis, cid, 0/*fFlags*/);
+}
+
+
 /**
  * Destroy an existing 3d context
  *
@@ -3765,9 +4511,9 @@ int vmsvga3dContextDestroy(PVGASTATE pThis, uint32_t cid)
     AssertReturn(cid < SVGA3D_MAX_CONTEXT_IDS, VERR_INVALID_PARAMETER);
 
     if (    cid < pState->cContexts
-        &&  pState->paContext[cid].id == cid)
+        &&  pState->papContexts[cid]->id == cid)
     {
-        PVMSVGA3DCONTEXT pContext = &pState->paContext[cid];
+        PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
 
         Log(("vmsvga3dContextDestroy id %x\n", cid));
 
@@ -3802,6 +4548,49 @@ int vmsvga3dContextDestroy(PVGASTATE pThis, uint32_t cid)
             AssertRC(rc);
         }
 
+#ifndef VMSVGA3D_OGL_WITH_SHARED_CTX /* This is done on windows - prevents various assertions at runtime, as well as shutdown & reset assertions when destroying surfaces. */
+        /* Check for all surfaces that are associated with this context to remove all dependencies */
+        for (uint32_t sid = 0; sid < pState->cSurfaces; sid++)
+        {
+            PVMSVGA3DSURFACE pSurface = &pState->paSurface[sid];
+            if (    pSurface->idAssociatedContext == cid
+                &&  pSurface->id == sid)
+            {
+                int rc;
+
+                Log(("vmsvga3dContextDestroy: remove all dependencies for surface %x\n", sid));
+
+                uint32_t            surfaceFlags = pSurface->flags;
+                SVGA3dSurfaceFormat format = pSurface->format;
+                SVGA3dSurfaceFace   face[SVGA3D_MAX_SURFACE_FACES];
+                uint32_t            multisampleCount = pSurface->multiSampleCount;
+                SVGA3dTextureFilter autogenFilter = pSurface->autogenFilter;
+                SVGA3dSize         *pMipLevelSize;
+                uint32_t            cFaces = pSurface->cFaces;
+
+                pMipLevelSize = (SVGA3dSize *)RTMemAllocZ(pSurface->faces[0].numMipLevels * pSurface->cFaces * sizeof(SVGA3dSize));
+                AssertReturn(pMipLevelSize, VERR_NO_MEMORY);
+
+                for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
+                {
+                    for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
+                    {
+                        uint32_t idx = i + iFace * pSurface->faces[0].numMipLevels;
+                        memcpy(&pMipLevelSize[idx], &pSurface->pMipmapLevels[idx].size, sizeof(SVGA3dSize));
+                    }
+                }
+                memcpy(face, pSurface->faces, sizeof(pSurface->faces));
+
+                /* Recreate the surface with the original settings; destroys the contents, but that seems fairly safe since the context is also destroyed. */
+                rc = vmsvga3dSurfaceDestroy(pThis, sid);
+                AssertRC(rc);
+
+                rc = vmsvga3dSurfaceDefine(pThis, sid, surfaceFlags, format, face, multisampleCount, autogenFilter, face[0].numMipLevels * cFaces, pMipLevelSize);
+                AssertRC(rc);
+            }
+        }
+#endif
+
         if (pContext->idFramebuffer != OPENGL_INVALID_ID)
         {
             /* Unbind the object from the framebuffer target. */
@@ -3822,7 +4611,7 @@ int vmsvga3dContextDestroy(PVGASTATE pThis, uint32_t cid)
             }
         }
 #ifdef RT_OS_WINDOWS
-        wglMakeCurrent(NULL, NULL);
+        wglMakeCurrent(pContext->hdc, NULL);
         wglDeleteContext(pContext->hglrc);
         ReleaseDC(pContext->hwnd, pContext->hdc);
 
@@ -3858,7 +4647,7 @@ int vmsvga3dChangeMode(PVGASTATE pThis)
     /* Resize all active contexts. */
     for (uint32_t i = 0; i < pState->cContexts; i++)
     {
-        PVMSVGA3DCONTEXT pContext = &pState->paContext[i];
+        PVMSVGA3DCONTEXT pContext = pState->papContexts[i];
         uint32_t cid = pContext->id;
 
         if (cid != SVGA3D_INVALID_ID)
@@ -3866,7 +4655,7 @@ int vmsvga3dChangeMode(PVGASTATE pThis)
 #ifdef RT_OS_WINDOWS
             CREATESTRUCT          cs;
 
-            memset(&cs, 0, sizeof(cs));            
+            memset(&cs, 0, sizeof(cs));
             cs.cx = pThis->svga.uWidth;
             cs.cy = pThis->svga.uHeight;
 
@@ -3897,12 +4686,12 @@ int vmsvga3dSetTransform(PVGASTATE pThis, uint32_t cid, SVGA3dTransformType type
     Log(("vmsvga3dSetTransform cid=%x %s\n", cid, vmsvgaTransformToString(type)));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetTransform invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     /* Save this matrix for vm state save/restore. */
@@ -4004,12 +4793,12 @@ int vmsvga3dSetZRange(PVGASTATE pThis, uint32_t cid, SVGA3dZRange zRange)
     Log(("vmsvga3dSetZRange cid=%x min=%d max=%d\n", cid, (uint32_t)(zRange.min * 100.0), (uint32_t)(zRange.max * 100.0)));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetZRange invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     pContext->state.zRange = zRange;
@@ -4104,7 +4893,7 @@ static GLenum vmsvgaCmpFunc2GL(uint32_t cmpFunc)
         return GL_GEQUAL;
     case SVGA3D_CMP_ALWAYS:
         return GL_ALWAYS;
-    default: 
+    default:
         AssertFailed();
         return GL_LESS;
     }
@@ -4146,25 +4935,25 @@ int vmsvga3dSetRenderState(PVGASTATE pThis, uint32_t cid, uint32_t cRenderStates
     Log(("vmsvga3dSetRenderState cid=%x cRenderStates=%d\n", cid, cRenderStates));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetRenderState invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     for (unsigned i = 0; i < cRenderStates; i++)
     {
         GLenum enableCap = ~0U;
-        Log(("vmsvga3dSetRenderState: cid=%d state=%s (%d) val=%x\n", cid, vmsvga3dGetRenderStateName(pRenderState[i].state), pRenderState[i].state, pRenderState[i].uintValue));        
+        Log(("vmsvga3dSetRenderState: cid=%x state=%s (%d) val=%x\n", cid, vmsvga3dGetRenderStateName(pRenderState[i].state), pRenderState[i].state, pRenderState[i].uintValue));
         /* Save the render state for vm state saving. */
         if (pRenderState[i].state < SVGA3D_RS_MAX)
             pContext->state.aRenderState[pRenderState[i].state] = pRenderState[i];
 
         switch (pRenderState[i].state)
         {
-        case SVGA3D_RS_ZENABLE:                /* SVGA3dBool */    
+        case SVGA3D_RS_ZENABLE:                /* SVGA3dBool */
             enableCap = GL_DEPTH_TEST;
             val = pRenderState[i].uintValue;
             break;
@@ -4493,7 +5282,7 @@ int vmsvga3dSetRenderState(PVGASTATE pThis, uint32_t cid, uint32_t cRenderStates
         case SVGA3D_RS_BLENDEQUATIONALPHA:     /* SVGA3dBlendEquation */
         case SVGA3D_RS_BLENDEQUATION:          /* SVGA3dBlendEquation */
             if (pContext->state.aRenderState[SVGA3D_RS_SEPARATEALPHABLENDENABLE].uintValue != 0)
-                pState->ext.glBlendEquationSeparate(vmsvga3dBlendEquation2GL(pContext->state.aRenderState[SVGA3D_RS_BLENDEQUATION].uintValue), 
+                pState->ext.glBlendEquationSeparate(vmsvga3dBlendEquation2GL(pContext->state.aRenderState[SVGA3D_RS_BLENDEQUATION].uintValue),
                                                     vmsvga3dBlendEquation2GL(pContext->state.aRenderState[SVGA3D_RS_BLENDEQUATIONALPHA].uintValue));
             else
             {
@@ -4981,12 +5770,12 @@ int vmsvga3dSetRenderTarget(PVGASTATE pThis, uint32_t cid, SVGA3dRenderTargetTyp
     Log(("vmsvga3dSetRenderTarget cid=%x type=%x surface id=%x\n", cid, type, target.sid));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetRenderTarget invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     /* Save for vm state save/restore. */
@@ -5033,32 +5822,51 @@ int vmsvga3dSetRenderTarget(PVGASTATE pThis, uint32_t cid, SVGA3dRenderTargetTyp
         if (pRenderTarget->oglId.texture == OPENGL_INVALID_ID)
         {
             Log(("vmsvga3dSetRenderTarget: create renderbuffer to be used as render target; surface id=%x type=%d format=%d\n", target.sid, pRenderTarget->flags, pRenderTarget->internalFormatGL));
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+            pContext = &pState->SharedCtx;
+            VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+#endif
             pState->ext.glGenRenderbuffers(1, &pRenderTarget->oglId.renderbuffer);
             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
 
             pState->ext.glBindRenderbuffer(GL_RENDERBUFFER, pRenderTarget->oglId.renderbuffer);
             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
 
-            pState->ext.glRenderbufferStorage(GL_RENDERBUFFER, 
-                                              pRenderTarget->internalFormatGL, 
-                                              pRenderTarget->pMipmapLevels[0].size.width, 
+            pState->ext.glRenderbufferStorage(GL_RENDERBUFFER,
+                                              pRenderTarget->internalFormatGL,
+                                              pRenderTarget->pMipmapLevels[0].size.width,
                                               pRenderTarget->pMipmapLevels[0].size.height);
             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
 
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+            pState->ext.glBindRenderbuffer(GL_RENDERBUFFER, OPENGL_INVALID_ID);
+            VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
+
+            pContext = pState->papContexts[cid];
+            VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+#else
+            LogFlow(("vmsvga3dSetRenderTarget: sid=%x idAssociatedContext %#x -> %#x\n", pRenderTarget->id, pRenderTarget->idAssociatedContext, cid));
             pRenderTarget->idAssociatedContext = cid;
+#endif
         }
+#ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
         else
+#endif
         {
             pState->ext.glBindRenderbuffer(GL_RENDERBUFFER, pRenderTarget->oglId.renderbuffer);
             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
         }
+#ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
         Assert(pRenderTarget->idAssociatedContext == cid);
+#endif
         Assert(!pRenderTarget->fDirty);
         AssertReturn(pRenderTarget->oglId.texture != OPENGL_INVALID_ID, VERR_INVALID_PARAMETER);
 
         pRenderTarget->flags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL;
 
-        pState->ext.glFramebufferRenderbuffer(GL_FRAMEBUFFER, (type == SVGA3D_RT_DEPTH) ? GL_DEPTH_ATTACHMENT : GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, pRenderTarget->oglId.renderbuffer);
+        pState->ext.glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+                                              (type == SVGA3D_RT_DEPTH) ? GL_DEPTH_ATTACHMENT : GL_STENCIL_ATTACHMENT,
+                                              GL_RENDERBUFFER, pRenderTarget->oglId.renderbuffer);
         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
         break;
 
@@ -5237,7 +6045,7 @@ static GLenum vmsvga3dTextureAddress2OGL(SVGA3dTextureAddress value)
         AssertFailed();
         return GL_CLAMP_TO_EDGE_SGIS; /* @todo correct? */
 
-    case SVGA3D_TEX_ADDRESS_EDGE:        
+    case SVGA3D_TEX_ADDRESS_EDGE:
     case SVGA3D_TEX_ADDRESS_INVALID:
     default:
         AssertFailed();
@@ -5285,12 +6093,12 @@ int vmsvga3dSetTextureState(PVGASTATE pThis, uint32_t cid, uint32_t cTextureStat
     Log(("vmsvga3dSetTextureState %x cTextureState=%d\n", cid, cTextureStates));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetTextureState invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     for (unsigned i = 0; i < cTextureStates; i++)
@@ -5307,11 +6115,21 @@ int vmsvga3dSetTextureState(PVGASTATE pThis, uint32_t cid, uint32_t cTextureStat
         }
 
         /* Active the right texture unit for subsequent texture state changes. */
-        if (pTextureState[i].stage != currentStage)
+        if (pTextureState[i].stage != currentStage || i == 0)
         {
-            pState->ext.glActiveTexture(GL_TEXTURE0 + pTextureState[i].stage);
-            VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
-            currentStage = pTextureState[i].stage;
+            /** @todo Is this the appropriate limit for all kinds of textures?  It is the
+             * size of aSidActiveTexture and for binding/unbinding we cannot exceed it. */
+            if (pTextureState[i].stage < SVGA3D_MAX_TEXTURE_STAGE)
+            {
+                pState->ext.glActiveTexture(GL_TEXTURE0 + pTextureState[i].stage);
+                VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
+                currentStage = pTextureState[i].stage;
+            }
+            else
+            {
+                AssertMsgFailed(("pTextureState[%d].stage=%#x name=%#x\n", i, pTextureState[i].stage, pTextureState[i].name));
+                continue;
+            }
         }
 
         switch (pTextureState[i].name)
@@ -5352,7 +6170,8 @@ int vmsvga3dSetTextureState(PVGASTATE pThis, uint32_t cid, uint32_t cTextureStat
         case SVGA3D_TS_BIND_TEXTURE:                /* SVGA3dSurfaceId */
             if (pTextureState[i].value == SVGA3D_INVALID_ID)
             {
-                Log(("SVGA3D_TS_BIND_TEXTURE: stage %d, texture surface id=%x\n", pTextureState[i].stage, pTextureState[i].value));
+                Log(("SVGA3D_TS_BIND_TEXTURE: stage %d, texture surface id=%x replacing=%x\n",
+                     currentStage, pTextureState[i].value, pContext->aSidActiveTexture[currentStage]));
 
                 pContext->aSidActiveTexture[currentStage] = SVGA3D_INVALID_ID;
                 /* Unselect the currently associated texture. */
@@ -5371,11 +6190,15 @@ int vmsvga3dSetTextureState(PVGASTATE pThis, uint32_t cid, uint32_t cTextureStat
 
                 PVMSVGA3DSURFACE pSurface = &pState->paSurface[sid];
 
-                Log(("SVGA3D_TS_BIND_TEXTURE: stage %d, texture surface id=%x (%d,%d)\n", pTextureState[i].stage, pTextureState[i].value, pSurface->pMipmapLevels[0].size.width, pSurface->pMipmapLevels[0].size.height));
+                Log(("SVGA3D_TS_BIND_TEXTURE: stage %d, texture surface id=%x (%d,%d) replacing=%x\n",
+                     currentStage, pTextureState[i].value, pSurface->pMipmapLevels[0].size.width,
+                     pSurface->pMipmapLevels[0].size.height, pContext->aSidActiveTexture[currentStage]));
 
                 if (pSurface->oglId.texture == OPENGL_INVALID_ID)
                 {
+#ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
                     Assert(pSurface->idAssociatedContext == SVGA3D_INVALID_ID);
+#endif
                     Log(("CreateTexture (%d,%d) level=%d\n", pSurface->pMipmapLevels[0].size.width, pSurface->pMipmapLevels[0].size.height, pSurface->faces[0].numMipLevels));
                     int rc = vmsvga3dCreateTexture(pState, pContext, cid, pSurface);
                     AssertRCReturn(rc, rc);
@@ -5424,10 +6247,34 @@ int vmsvga3dSetTextureState(PVGASTATE pThis, uint32_t cid, uint32_t cTextureStat
             break;
 
         case SVGA3D_TS_MIPFILTER:                   /* SVGA3dTextureFilter */
-            //AssertFailed(); /* @todo */
-            //samplerType = D3DSAMP_MIPFILTER;
-            val = vmsvga3dTextureFilter2OGL((SVGA3dTextureFilter)pTextureState[i].value);
+        case SVGA3D_TS_MINFILTER:                   /* SVGA3dTextureFilter */
+        {
+            uint32_t mipFilter = pContext->state.aTextureState[currentStage][SVGA3D_TS_MIPFILTER].value;
+            uint32_t minFilter = pContext->state.aTextureState[currentStage][SVGA3D_TS_MINFILTER].value;
+
+            /* If SVGA3D_TS_MIPFILTER is set to NONE, then use SVGA3D_TS_MIPFILTER, otherwise SVGA3D_TS_MIPFILTER enables mipmap minification. */
+            textureType = GL_TEXTURE_MIN_FILTER;
+            if (mipFilter != SVGA3D_TEX_FILTER_NONE)
+            {
+                if (minFilter == SVGA3D_TEX_FILTER_NEAREST)
+                {
+                    if (mipFilter == SVGA3D_TEX_FILTER_LINEAR)
+                        val = GL_NEAREST_MIPMAP_LINEAR;
+                    else
+                        val = GL_NEAREST_MIPMAP_NEAREST;
+                }
+                else
+                {
+                    if (mipFilter == SVGA3D_TEX_FILTER_LINEAR)
+                        val = GL_LINEAR_MIPMAP_LINEAR;
+                    else
+                        val = GL_LINEAR_MIPMAP_NEAREST;
+                }
+            }
+            else
+                val = vmsvga3dTextureFilter2OGL((SVGA3dTextureFilter)minFilter);
             break;
+        }
 
         case SVGA3D_TS_MAGFILTER:                   /* SVGA3dTextureFilter */
             textureType = GL_TEXTURE_MAG_FILTER;
@@ -5435,11 +6282,6 @@ int vmsvga3dSetTextureState(PVGASTATE pThis, uint32_t cid, uint32_t cTextureStat
             Assert(val == GL_NEAREST || val == GL_LINEAR);
             break;
 
-        case SVGA3D_TS_MINFILTER:                   /* SVGA3dTextureFilter */
-            textureType = GL_TEXTURE_MIN_FILTER;
-            val = vmsvga3dTextureFilter2OGL((SVGA3dTextureFilter)pTextureState[i].value);
-            break;
-
         case SVGA3D_TS_BORDERCOLOR:                 /* SVGA3dColor */
         {
             GLfloat color[4]; /* red, green, blue, alpha */
@@ -5455,18 +6297,18 @@ int vmsvga3dSetTextureState(PVGASTATE pThis, uint32_t cid, uint32_t cTextureStat
             glTexParameterf(GL_TEXTURE_2D /* @todo flexible type */, GL_TEXTURE_LOD_BIAS, pTextureState[i].value);   /* Identical; default 0.0 identical too */
             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
             break;
-            
+
         case SVGA3D_TS_TEXTURE_MIPMAP_LEVEL:        /* uint32_t */
-            textureType = GL_TEXTURE_MAX_LEVEL;
-            val = pTextureState[i].value;   /* Identical?? */
+            textureType = GL_TEXTURE_BASE_LEVEL;
+            val = pTextureState[i].value;
             break;
 
-#if 0      
+#if 0
         case SVGA3D_TS_TEXTURE_ANISOTROPIC_LEVEL:   /* uint32_t */
             samplerType = D3DSAMP_MAXANISOTROPY;
             val = pTextureState[i].value;   /* Identical?? */
             break;
-            
+
         case SVGA3D_TS_GAMMA:                       /* float */
             samplerType = D3DSAMP_SRGBTEXTURE;
             /* Boolean in D3D */
@@ -5474,7 +6316,7 @@ int vmsvga3dSetTextureState(PVGASTATE pThis, uint32_t cid, uint32_t cTextureStat
                 val = FALSE;
             else
                 val = TRUE;
-            break;           
+            break;
 #endif
         /* Internal commands, that don't map directly to the SetTextureStageState API. */
         case SVGA3D_TS_TEXCOORDGEN:                 /* SVGA3dTextureCoordGen */
@@ -5506,12 +6348,12 @@ int vmsvga3dSetMaterial(PVGASTATE pThis, uint32_t cid, SVGA3dFace face, SVGA3dMa
     Log(("vmsvga3dSetMaterial cid=%x face %d\n", cid, face));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetMaterial invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     switch (face)
@@ -5559,12 +6401,12 @@ int vmsvga3dSetLightData(PVGASTATE pThis, uint32_t cid, uint32_t index, SVGA3dLi
     Log(("vmsvga3dSetLightData cid=%x index=%d type=%d\n", cid, index, pData->type));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetLightData invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     /* Store for vm state save/restore */
@@ -5576,8 +6418,8 @@ int vmsvga3dSetLightData(PVGASTATE pThis, uint32_t cid, uint32_t index, SVGA3dLi
     else
         AssertFailed();
 
-    if (    pData->attenuation0 < 0.0f 
-        ||  pData->attenuation1 < 0.0f 
+    if (    pData->attenuation0 < 0.0f
+        ||  pData->attenuation1 < 0.0f
         ||  pData->attenuation2 < 0.0f)
     {
         Log(("vmsvga3dSetLightData: invalid negative attenuation values!!\n"));
@@ -5595,7 +6437,7 @@ int vmsvga3dSetLightData(PVGASTATE pThis, uint32_t cid, uint32_t index, SVGA3dLi
 
     if (pData->range * pData->range >= FLT_MIN)
         QuadAttenuation = 1.4f / (pData->range * pData->range);
-    else 
+    else
         QuadAttenuation = 0.0f;
 
     switch (pData->type)
@@ -5611,14 +6453,14 @@ int vmsvga3dSetLightData(PVGASTATE pThis, uint32_t cid, uint32_t index, SVGA3dLi
 
         glLightfv(GL_LIGHT0 + index, GL_POSITION, position);
         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
-        
+
         glLightf(GL_LIGHT0 + index, GL_SPOT_CUTOFF, 180.0f);
         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
-        
+
         /* Attenuation - Are these right? guessing... */
         glLightf(GL_LIGHT0 + index, GL_CONSTANT_ATTENUATION, pData->attenuation0);
         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
-        
+
         glLightf(GL_LIGHT0 + index, GL_LINEAR_ATTENUATION, pData->attenuation1);
         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
 
@@ -5666,11 +6508,11 @@ int vmsvga3dSetLightData(PVGASTATE pThis, uint32_t cid, uint32_t index, SVGA3dLi
              * rest of the rather complex calculation
              */
             exponent = 0.0f;
-        } 
-        else 
+        }
+        else
         {
             float rho = pData->theta + (pData->phi - pData->theta) / (2 * pData->falloff);
-            if (rho < 0.0001f) 
+            if (rho < 0.0001f)
                 rho = 0.0001f;
             exponent = -0.3f/log(cos(rho/2));
         }
@@ -5686,7 +6528,7 @@ int vmsvga3dSetLightData(PVGASTATE pThis, uint32_t cid, uint32_t index, SVGA3dLi
         /* Attenuation - Are these right? guessing... */
         glLightf(GL_LIGHT0 + index, GL_CONSTANT_ATTENUATION, pData->attenuation0);
         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
-        
+
         glLightf(GL_LIGHT0 + index, GL_LINEAR_ATTENUATION, pData->attenuation1);
         VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
 
@@ -5730,7 +6572,7 @@ int vmsvga3dSetLightData(PVGASTATE pThis, uint32_t cid, uint32_t index, SVGA3dLi
 }
 
 int vmsvga3dSetLightEnabled(PVGASTATE pThis, uint32_t cid, uint32_t index, uint32_t enabled)
-{    
+{
     PVMSVGA3DCONTEXT      pContext;
     PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
@@ -5738,12 +6580,12 @@ int vmsvga3dSetLightEnabled(PVGASTATE pThis, uint32_t cid, uint32_t index, uint3
     Log(("vmsvga3dSetLightEnabled cid=%x %d -> %d\n", cid, index, enabled));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetLightEnabled invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     /* Store for vm state save/restore */
@@ -5775,12 +6617,12 @@ int vmsvga3dSetViewPort(PVGASTATE pThis, uint32_t cid, SVGA3dRect *pRect)
     Log(("vmsvga3dSetViewPort cid=%x (%d,%d)(%d,%d)\n", cid, pRect->x, pRect->y, pRect->w, pRect->h));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetViewPort invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     /* Save for vm state save/restore. */
@@ -5823,12 +6665,12 @@ int vmsvga3dSetClipPlane(PVGASTATE pThis, uint32_t cid,  uint32_t index, float p
     AssertReturn(index < SVGA3D_CLIPPLANE_MAX, VERR_INVALID_PARAMETER);
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetClipPlane invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     /* Store for vm state save/restore. */
@@ -5856,12 +6698,12 @@ int vmsvga3dSetScissorRect(PVGASTATE pThis, uint32_t cid, SVGA3dRect *pRect)
     Log(("vmsvga3dSetScissorRect cid=%x (%d,%d)(%d,%d)\n", cid, pRect->x, pRect->y, pRect->w, pRect->h));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetScissorRect invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     /* Store for vm state save/restore. */
@@ -5883,7 +6725,8 @@ static void vmsvgaColor2GLFloatArray(uint32_t color, GLfloat *pRed, GLfloat *pGr
     *pBlue  = (GLfloat)(color & 0xff) / 255.0;
 }
 
-int vmsvga3dCommandClear(PVGASTATE pThis, uint32_t cid, SVGA3dClearFlag clearFlag, uint32_t color, float depth, uint32_t stencil, uint32_t cRects, SVGA3dRect *pRect)
+int vmsvga3dCommandClear(PVGASTATE pThis, uint32_t cid, SVGA3dClearFlag clearFlag, uint32_t color, float depth, uint32_t stencil,
+                         uint32_t cRects, SVGA3dRect *pRect)
 {
     GLbitfield            mask = 0;
     PVMSVGA3DCONTEXT      pContext;
@@ -5894,12 +6737,12 @@ int vmsvga3dCommandClear(PVGASTATE pThis, uint32_t cid, SVGA3dClearFlag clearFla
     Log(("vmsvga3dCommandClear cid=%x clearFlag=%x color=%x depth=%d stencil=%x cRects=%d\n", cid, clearFlag, color, (uint32_t)(depth * 100.0), stencil, cRects));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dCommandClear invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     if (clearFlag & SVGA3D_CLEAR_COLOR)
@@ -6105,6 +6948,12 @@ int vmsvga3dDrawPrimitivesProcessVertexDecls(PVMSVGA3DSTATE pState, PVMSVGA3DCON
     if (pVertexSurface->oglId.buffer == OPENGL_INVALID_ID)
     {
         Log(("vmsvga3dDrawPrimitives: create vertex buffer fDirty=%d size=%x bytes\n", pVertexSurface->fDirty, pVertexSurface->pMipmapLevels[0].cbSurface));
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+        PVMSVGA3DCONTEXT pSavedCtx = pContext;
+        pContext = &pState->SharedCtx;
+        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+#endif
+
         pState->ext.glGenBuffers(1, &pVertexSurface->oglId.buffer);
         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
 
@@ -6120,14 +6969,27 @@ int vmsvga3dDrawPrimitivesProcessVertexDecls(PVMSVGA3DSTATE pState, PVMSVGA3DCON
         pVertexSurface->fDirty = false;
 
         pVertexSurface->flags |= SVGA3D_SURFACE_HINT_VERTEXBUFFER;
+
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+        pState->ext.glBindBuffer(GL_ARRAY_BUFFER, OPENGL_INVALID_ID);
+        VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
+
+        pContext = pSavedCtx;
+        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+#endif
     }
+#ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
     else
+#endif
     {
         Assert(pVertexSurface->fDirty == false);
         pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pVertexSurface->oglId.buffer);
         VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
     }
+#ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
     pVertexSurface->idAssociatedContext = pContext->id;
+    LogFlow(("vmsvga3dDrawPrimitivesProcessVertexDecls: sid=%x idAssociatedContext %#x -> %#x\n", pVertexSurface->id, pVertexSurface->idAssociatedContext, pContext->id));
+#endif
 
     /* Setup the vertex declarations. */
     for (unsigned iVertex = 0; iVertex < numVertexDecls; iVertex++)
@@ -6228,7 +7090,7 @@ int vmsvga3dDrawPrimitivesProcessVertexDecls(PVMSVGA3DSTATE pState, PVMSVGA3DCON
             case SVGA3D_DECLUSAGE_MAX: AssertFailed(); break; /* shut up gcc */
             }
         }
-       
+
 #ifdef LOG_ENABLED
         if (pVertexDecl[iVertex].array.stride == 0)
             Log(("vmsvga3dDrawPrimitives: stride == 0! Can be valid\n"));
@@ -6325,12 +7187,12 @@ int vmsvga3dDrawPrimitives(PVGASTATE pThis, uint32_t cid, uint32_t numVertexDecl
     Assert(!cVertexDivisor);
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dDrawPrimitives invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     /* Flush any shader changes. */
@@ -6390,7 +7252,7 @@ int vmsvga3dDrawPrimitives(PVGASTATE pThis, uint32_t cid, uint32_t numVertexDecl
             AssertMsg(pRange[iPrimitive].indexWidth == sizeof(uint32_t) || pRange[iPrimitive].indexWidth == sizeof(uint16_t), ("Unsupported primitive width %d\n", pRange[iPrimitive].indexWidth));
 
             if (    sidIndex >= SVGA3D_MAX_SURFACE_IDS
-                ||  sidIndex >= pState->cSurfaces 
+                ||  sidIndex >= pState->cSurfaces
                 ||  pState->paSurface[sidIndex].id != sidIndex)
             {
                 Assert(sidIndex < SVGA3D_MAX_SURFACE_IDS);
@@ -6404,6 +7266,10 @@ int vmsvga3dDrawPrimitives(PVGASTATE pThis, uint32_t cid, uint32_t numVertexDecl
             if (pIndexSurface->oglId.buffer == OPENGL_INVALID_ID)
             {
                 Log(("vmsvga3dDrawPrimitives: create index buffer fDirty=%d size=%x bytes\n", pIndexSurface->fDirty, pIndexSurface->pMipmapLevels[0].cbSurface));
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+                pContext = &pState->SharedCtx;
+                VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+#endif
 
                 pState->ext.glGenBuffers(1, &pIndexSurface->oglId.buffer);
                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
@@ -6421,15 +7287,28 @@ int vmsvga3dDrawPrimitives(PVGASTATE pThis, uint32_t cid, uint32_t numVertexDecl
                 pIndexSurface->fDirty = false;
 
                 pIndexSurface->flags |= SVGA3D_SURFACE_HINT_INDEXBUFFER;
+
+#ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+                pState->ext.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OPENGL_INVALID_ID);
+                VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
+
+                pContext = pState->papContexts[cid];
+                VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+#endif
             }
+#ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
             else
+#endif
             {
                 Assert(pIndexSurface->fDirty == false);
 
                 pState->ext.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pIndexSurface->oglId.buffer);
                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
             }
+#ifndef VMSVGA3D_OGL_WITH_SHARED_CTX
+            LogFlow(("vmsvga3dDrawPrimitives: sid=%x idAssociatedContext %#x -> %#x\n", pIndexSurface->id, pIndexSurface->idAssociatedContext, pContext->id));
             pIndexSurface->idAssociatedContext = pContext->id;
+#endif
         }
 
         if (!pIndexSurface)
@@ -6442,18 +7321,18 @@ int vmsvga3dDrawPrimitives(PVGASTATE pThis, uint32_t cid, uint32_t numVertexDecl
         {
             Assert(pRange[iPrimitive].indexBias >= 0);  /* @todo */
             Assert(pRange[iPrimitive].indexWidth == pRange[iPrimitive].indexArray.stride);
-           
+
             /* Render with an index buffer */
             Log(("DrawIndexedPrimitive %x cPrimitives=%d cVertices=%d hint.first=%d hint.last=%d index offset=%d primitivecount=%d index width=%d index bias=%d\n", modeDraw, pRange[iPrimitive].primitiveCount, cVertices, pVertexDecl[0].rangeHint.first,  pVertexDecl[0].rangeHint.last,  pRange[iPrimitive].indexArray.offset, pRange[iPrimitive].primitiveCount,  pRange[iPrimitive].indexWidth, pRange[iPrimitive].indexBias));
             if (pRange[iPrimitive].indexBias == 0)
-                glDrawElements(modeDraw, 
+                glDrawElements(modeDraw,
                                cVertices,
-                               (pRange[iPrimitive].indexWidth == sizeof(uint16_t)) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, 
+                               (pRange[iPrimitive].indexWidth == sizeof(uint16_t)) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT,
                                (GLvoid *)(uintptr_t)pRange[iPrimitive].indexArray.offset);   /* byte offset in indices buffer */
             else
-                pState->ext.glDrawElementsBaseVertex(modeDraw, 
-                                                     cVertices, 
-                                                     (pRange[iPrimitive].indexWidth == sizeof(uint16_t)) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, 
+                pState->ext.glDrawElementsBaseVertex(modeDraw,
+                                                     cVertices,
+                                                     (pRange[iPrimitive].indexWidth == sizeof(uint16_t)) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT,
                                                      (GLvoid *)(uintptr_t)pRange[iPrimitive].indexArray.offset, /* byte offset in indices buffer */
                                                      pRange[iPrimitive].indexBias);  /* basevertex */
 
@@ -6496,11 +7375,16 @@ internal_error:
             GLint activeTextureUnit = 0;
 
             glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTextureUnit);
+            VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
             pState->ext.glActiveTexture(GL_TEXTURE0 + i);
+            VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
 
             glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
+            VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
             pState->ext.glActiveTexture(activeTextureUnit);
+            VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
 
+# if 0 /* Aren't we checking whether 'activeTexture' on texture unit 'i' matches what we expected?  This works if only one unit is active, but if both are it _will_ fail for one of them. */
             if (pContext->aSidActiveTexture[activeTextureUnit - GL_TEXTURE0] != SVGA3D_INVALID_ID)
             {
                 PVMSVGA3DSURFACE pTexture;
@@ -6508,6 +7392,13 @@ internal_error:
 
                 AssertMsg(pTexture->oglId.texture == (GLuint)activeTexture, ("%x vs %x unit %d - %d\n", pTexture->oglId.texture, activeTexture, i, activeTextureUnit - GL_TEXTURE0));
             }
+# else
+            PVMSVGA3DSURFACE pTexture = &pState->paSurface[pContext->aSidActiveTexture[i]];
+            AssertMsg(pTexture->id == pContext->aSidActiveTexture[i], ("%x vs %x\n", pTexture->id == pContext->aSidActiveTexture[i]));
+            AssertMsg(pTexture->oglId.texture == (GLuint)activeTexture,
+                      ("%x vs %x unit %d (active unit %d) sid=%x\n", pTexture->oglId.texture, activeTexture, i,
+                       activeTextureUnit - GL_TEXTURE0, pContext->aSidActiveTexture[i]));
+# endif
         }
     }
 #endif
@@ -6539,12 +7430,12 @@ int vmsvga3dShaderDefine(PVGASTATE pThis, uint32_t cid, uint32_t shid, SVGA3dSha
     Log3(("shader code:\n%.*Rhxd\n", cbData, pShaderData));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dShaderDefine invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     AssertReturn(shid < SVGA3D_MAX_SHADER_IDS, VERR_INVALID_PARAMETER);
@@ -6552,8 +7443,9 @@ int vmsvga3dShaderDefine(PVGASTATE pThis, uint32_t cid, uint32_t shid, SVGA3dSha
     {
         if (shid >= pContext->cVertexShaders)
         {
-            pContext->paVertexShader = (PVMSVGA3DSHADER)RTMemRealloc(pContext->paVertexShader, sizeof(VMSVGA3DSHADER) * (shid + 1));
-            AssertReturn(pContext->paVertexShader, VERR_NO_MEMORY);
+            void *pvNew = RTMemRealloc(pContext->paVertexShader, sizeof(VMSVGA3DSHADER) * (shid + 1));
+            AssertReturn(pvNew, VERR_NO_MEMORY);
+            pContext->paVertexShader = (PVMSVGA3DSHADER)pvNew;
             memset(&pContext->paVertexShader[pContext->cVertexShaders], 0, sizeof(VMSVGA3DSHADER) * (shid + 1 - pContext->cVertexShaders));
             for (uint32_t i = pContext->cVertexShaders; i < shid + 1; i++)
                 pContext->paVertexShader[i].id = SVGA3D_INVALID_ID;
@@ -6570,8 +7462,9 @@ int vmsvga3dShaderDefine(PVGASTATE pThis, uint32_t cid, uint32_t shid, SVGA3dSha
         Assert(type == SVGA3D_SHADERTYPE_PS);
         if (shid >= pContext->cPixelShaders)
         {
-            pContext->paPixelShader = (PVMSVGA3DSHADER)RTMemRealloc(pContext->paPixelShader, sizeof(VMSVGA3DSHADER) * (shid + 1));
-            AssertReturn(pContext->paPixelShader, VERR_NO_MEMORY);
+            void *pvNew = RTMemRealloc(pContext->paPixelShader, sizeof(VMSVGA3DSHADER) * (shid + 1));
+            AssertReturn(pvNew, VERR_NO_MEMORY);
+            pContext->paPixelShader = (PVMSVGA3DSHADER)pvNew;
             memset(&pContext->paPixelShader[pContext->cPixelShaders], 0, sizeof(VMSVGA3DSHADER) * (shid + 1 - pContext->cPixelShaders));
             for (uint32_t i = pContext->cPixelShaders; i < shid + 1; i++)
                 pContext->paPixelShader[i].id = SVGA3D_INVALID_ID;
@@ -6593,6 +7486,16 @@ int vmsvga3dShaderDefine(PVGASTATE pThis, uint32_t cid, uint32_t shid, SVGA3dSha
     AssertReturn(pShader->pShaderProgram, VERR_NO_MEMORY);
     memcpy(pShader->pShaderProgram, pShaderData, cbData);
 
+#ifdef DUMP_SHADER_DISASSEMBLY
+    LPD3DXBUFFER pDisassembly;
+    HRESULT hr = D3DXDisassembleShader((const DWORD *)pShaderData, FALSE, NULL, &pDisassembly);
+    if (hr == D3D_OK)
+    {
+        Log(("Shader disassembly:\n%s\n", pDisassembly->GetBufferPointer()));
+        pDisassembly->Release();
+    }
+#endif
+
     switch (type)
     {
     case SVGA3D_SHADERTYPE_VS:
@@ -6606,6 +7509,12 @@ int vmsvga3dShaderDefine(PVGASTATE pThis, uint32_t cid, uint32_t shid, SVGA3dSha
     default:
         AssertFailedReturn(VERR_INVALID_PARAMETER);
     }
+    if (rc != VINF_SUCCESS)
+    {
+        RTMemFree(pShader->pShaderProgram);
+        memset(pShader, 0, sizeof(*pShader));
+        pShader->id = SVGA3D_INVALID_ID;
+    }
 
     return rc;
 }
@@ -6621,12 +7530,12 @@ int vmsvga3dShaderDestroy(PVGASTATE pThis, uint32_t cid, uint32_t shid, SVGA3dSh
     Log(("vmsvga3dShaderDestroy cid=%x shid=%x type=%s\n", cid, shid, (type == SVGA3D_SHADERTYPE_VS) ? "VERTEX" : "PIXEL"));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dShaderDestroy invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     if (type == SVGA3D_SHADERTYPE_VS)
@@ -6674,12 +7583,12 @@ int vmsvga3dShaderSet(PVGASTATE pThis, uint32_t cid, SVGA3dShaderType type, uint
     Log(("vmsvga3dShaderSet cid=%x type=%s shid=%d\n", cid, (type == SVGA3D_SHADERTYPE_VS) ? "VERTEX" : "PIXEL", shid));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dShaderSet invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     if (type == SVGA3D_SHADERTYPE_VS)
@@ -6747,12 +7656,12 @@ int vmsvga3dShaderSetConst(PVGASTATE pThis, uint32_t cid, uint32_t reg, SVGA3dSh
     Log(("vmsvga3dShaderSetConst cid=%x reg=%x type=%s cregs=%d ctype=%x\n", cid, reg, (type == SVGA3D_SHADERTYPE_VS) ? "VERTEX" : "PIXEL", cRegisters, ctype));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dShaderSetConst invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
     for (uint32_t i = 0; i < cRegisters; i++)
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.cpp b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.cpp
index 0cc60c9..cb3ae4e 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.cpp
@@ -330,6 +330,9 @@ uint32_t vmsvga3dSurfaceFormatSize(SVGA3dSurfaceFormat format)
     case SVGA3D_BUFFER:
         return 1;
 
+    case SVGA3D_NV12:
+        return 1;
+
     case SVGA3D_V16U16:
         return 4;
 
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.h b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.h
index 8b31d66..d3bf200 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.h
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.h
@@ -48,10 +48,10 @@ int vmsvga3dLoadExec(PVGASTATE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32
         {
             uint32_t cPixelShaderConst, cVertexShaderConst, cPixelShaders, cVertexShaders;
 
-            rc = vmsvga3dContextDefine(pThis, cid, false /*fOtherProfile*/);
+            rc = vmsvga3dContextDefine(pThis, cid);
             AssertRCReturn(rc, rc);
 
-            pContext = &pState->paContext[i];
+            pContext = pState->papContexts[i];
             AssertReturn(pContext->id == cid, VERR_INTERNAL_ERROR);
 
             rc = SSMR3GetStructEx(pSSM, pContext, sizeof(*pContext), 0, g_aVMSVGA3DCONTEXTFields, NULL);
@@ -245,7 +245,7 @@ int vmsvga3dLoadExec(PVGASTATE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32
     /* Reinitialize all active contexts. */
     for (uint32_t i = 0; i < pState->cContexts; i++)
     {
-        PVMSVGA3DCONTEXT pContext = &pState->paContext[i];
+        PVMSVGA3DCONTEXT pContext = pState->papContexts[i];
         uint32_t cid = pContext->id;
 
         if (cid != SVGA3D_INVALID_ID)
@@ -356,7 +356,7 @@ int vmsvga3dSaveExec(PVGASTATE pThis, PSSMHANDLE pSSM)
     /* Save all active contexts. */
     for (uint32_t i = 0; i < pState->cContexts; i++)
     {
-        PVMSVGA3DCONTEXT pContext = &pState->paContext[i];
+        PVMSVGA3DCONTEXT pContext = pState->papContexts[i];
         uint32_t cid = pContext->id;
 
         /* Save the id first. */
@@ -538,12 +538,12 @@ int vmsvga3dSaveExec(PVGASTATE pThis, PSSMHANDLE pSSM)
                                         /* @todo stricter checks for associated context */
                                         uint32_t cid = pSurface->idAssociatedContext;
                                         if (    cid >= pState->cContexts
-                                            ||  pState->paContext[cid].id != cid)
+                                            ||  pState->papContexts[cid]->id != cid)
                                         {
-                                            Log(("vmsvga3dSaveExec invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->paContext[cid].id));
+                                            Log(("vmsvga3dSaveExec invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
                                             AssertFailedReturn(VERR_INVALID_PARAMETER);
                                         }
-                                        PVMSVGA3DCONTEXT pContext = &pState->paContext[cid];
+                                        PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
 
                                         hr = pSurface->bounce.pTexture->GetSurfaceLevel(i, &pDest);
                                         AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetSurfaceLevel failed with %x\n", hr), VERR_INTERNAL_ERROR);
@@ -647,16 +647,21 @@ int vmsvga3dSaveExec(PVGASTATE pThis, PSSMHANDLE pSSM)
 #elif defined(VMSVGA3D_OPENGL)
                         void *pData = NULL;
 
+# ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+                        PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;
+                        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+# else
                         /* @todo stricter checks for associated context */
                         uint32_t cid = pSurface->idAssociatedContext;
                         if (    cid >= pState->cContexts
-                            ||  pState->paContext[cid].id != cid)
+                            ||  pState->papContexts[cid]->id != cid)
                         {
-                            Log(("vmsvga3dSaveExec: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->paContext[cid].id));
+                            Log(("vmsvga3dSaveExec: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
                             AssertFailedReturn(VERR_INVALID_PARAMETER);
                         }
-                        PVMSVGA3DCONTEXT pContext = &pState->paContext[cid];
+                        PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
                         VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+# endif
 
                         Assert(pMipmapLevel->cbSurface);
 
@@ -688,6 +693,10 @@ int vmsvga3dSaveExec(PVGASTATE pThis, PSSMHANDLE pSSM)
                             glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
                             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
 
+                            /* Set row length and alignment of the output data. */
+                            VMSVGAPACKPARAMS SavedParams;
+                            vmsvga3dSetPackParams(pState, pContext, pSurface, &SavedParams);
+
                             glGetTexImage(GL_TEXTURE_2D,
                                           i,
                                           pSurface->formatGL, 
@@ -695,6 +704,8 @@ int vmsvga3dSaveExec(PVGASTATE pThis, PSSMHANDLE pSSM)
                                           pData);
                             VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
 
+                            vmsvga3dRestorePackParams(pState, pContext, pSurface, &SavedParams);
+
                             /* Data follows */
                             rc = SSMR3PutBool(pSSM, true);
                             AssertRCReturn(rc, rc);
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp
index ad7a2c5..096ebfc 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp
@@ -47,7 +47,9 @@
 #include <d3d9.h>
 
 /* Enable to disassemble defined shaders. */
-//#define DUMP_SHADER_DISASSEMBLY
+#if defined(DEBUG) && 0 /* Disabled as we don't have the DirectX SDK avaible atm. */
+#define DUMP_SHADER_DISASSEMBLY
+#endif
 
 #ifdef DUMP_SHADER_DISASSEMBLY
 #include <d3dx9shader.h>
@@ -105,10 +107,10 @@ typedef struct
     uint32_t                id;
     uint32_t                idAssociatedContext;
     uint32_t                flags;
-    SVGA3dSurfaceFormat     format; 
+    SVGA3dSurfaceFormat     format;
     SVGA3dSurfaceFace       faces[SVGA3D_MAX_SURFACE_FACES];
     uint32_t                cFaces;
-    PVMSVGA3DMIPMAPLEVEL    pMipmapLevels; 
+    PVMSVGA3DMIPMAPLEVEL    pMipmapLevels;
     uint32_t                multiSampleCount;
     SVGA3dTextureFilter     autogenFilter;
     D3DFORMAT               formatD3D;
@@ -332,7 +334,7 @@ typedef struct
 #else
     IDirect3D9Ex           *pD3D9;
 #endif
-    D3DCAPS9                caps; 
+    D3DCAPS9                caps;
 
     /** Window Thread. */
     R3PTRTYPE(RTTHREAD)     pWindowThread;
@@ -340,9 +342,11 @@ typedef struct
     /** Window request semaphore. */
     RTSEMEVENT              WndRequestSem;
 
+    /** The size of papContexts  */
     uint32_t                cContexts;
     uint32_t                cSurfaces;
-    PVMSVGA3DCONTEXT        paContext;
+    /** Contexts indexed by ID.  Grown as needed. */
+    PVMSVGA3DCONTEXT       *papContexts;
     PVMSVGA3DSURFACE        paSurface;
 
     bool                    fSupportedSurfaceINTZ;
@@ -363,7 +367,7 @@ static SSMFIELD const g_aVMSVGA3DSTATEFields[] =
 
     SSMFIELD_ENTRY(                 VMSVGA3DSTATE, cContexts),
     SSMFIELD_ENTRY(                 VMSVGA3DSTATE, cSurfaces),
-    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, paContext),
+    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, papContexts),
     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGA3DSTATE, paSurface),
     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, fSupportedSurfaceINTZ),
     SSMFIELD_ENTRY_IGNORE(          VMSVGA3DSTATE, fSupportedSurfaceNULL),
@@ -377,7 +381,7 @@ typedef struct
     SVGA3dFormatOp          FormatOp;
 } VMSVGA3DFORMATSUPPORT;
 
-VMSVGA3DFORMATSUPPORT aFormatSupport[] = 
+VMSVGA3DFORMATSUPPORT aFormatSupport[] =
 {
     {
         0,
@@ -436,7 +440,7 @@ VMSVGA3DFORMATSUPPORT aFormatSupport[] =
     }
 };
 
-VMSVGA3DFORMATSUPPORT aFeatureReject[] = 
+VMSVGA3DFORMATSUPPORT aFeatureReject[] =
 {
     {
         D3DUSAGE_QUERY_WRAPANDMIP,
@@ -452,7 +456,7 @@ VMSVGA3DFORMATSUPPORT aFeatureReject[] =
         D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
         D3DRTYPE_TEXTURE, /* ?? */
         SVGA3DFORMAT_OP_NOALPHABLEND
-    },    
+    },
 };
 
 static void vmsvgaDumpD3DCaps(D3DCAPS9 *pCaps);
@@ -517,7 +521,7 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
     vmsvgaDumpD3DCaps(&pState->caps);
 
     /* Check if INTZ is supported. */
-    hr = pState->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT, 
+    hr = pState->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT,
                                           D3DDEVTYPE_HAL,
                                           D3DFMT_X8R8G8B8,    /* assume standard 32-bit display mode */
                                           0,
@@ -532,7 +536,7 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
         pState->fSupportedSurfaceINTZ = true;
 
     /* Check if NULL is supported. */
-    hr = pState->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT, 
+    hr = pState->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT,
                                           D3DDEVTYPE_HAL,
                                           D3DFMT_X8R8G8B8,    /* assume standard 32-bit display mode */
                                           D3DUSAGE_RENDERTARGET,
@@ -548,7 +552,7 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
 
 
     /*  Check if DX9 depth stencil textures are supported */
-    hr = pState->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT, 
+    hr = pState->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT,
                                           D3DDEVTYPE_HAL,
                                           D3DFMT_X8R8G8B8,    /* assume standard 32-bit display mode */
                                           D3DUSAGE_DEPTHSTENCIL,
@@ -559,7 +563,7 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
         LogRel(("VMSVGA: texture format D3DFMT_D16 not supported\n"));
     }
 
-    hr = pState->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT, 
+    hr = pState->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT,
                                           D3DDEVTYPE_HAL,
                                           D3DFMT_X8R8G8B8,    /* assume standard 32-bit display mode */
                                           D3DUSAGE_DEPTHSTENCIL,
@@ -569,7 +573,7 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
     {
         LogRel(("VMSVGA: texture format D3DFMT_D24X8 not supported\n"));
     }
-    hr = pState->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT, 
+    hr = pState->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT,
                                           D3DDEVTYPE_HAL,
                                           D3DFMT_X8R8G8B8,    /* assume standard 32-bit display mode */
                                           D3DUSAGE_DEPTHSTENCIL,
@@ -597,8 +601,8 @@ int vmsvga3dReset(PVGASTATE pThis)
     /* Destroy all leftover contexts. */
     for (uint32_t i = 0; i < pState->cContexts; i++)
     {
-        if (pState->paContext[i].id != SVGA3D_INVALID_ID)
-            vmsvga3dContextDestroy(pThis, pState->paContext[i].id);
+        if (pState->papContexts[i]->id != SVGA3D_INVALID_ID)
+            vmsvga3dContextDestroy(pThis, pState->papContexts[i]->id);
     }
     return VINF_SUCCESS;
 }
@@ -635,7 +639,7 @@ static uint32_t vmsvga3dGetSurfaceFormatSupport(PVMSVGA3DSTATE pState3D, uint32_
     uint32_t result = 0;
 
     /* Try if the format can be used for the primary display. */
-    hr = pState3D->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT, 
+    hr = pState3D->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT,
                                             D3DDEVTYPE_HAL,
                                             format,
                                             0,
@@ -644,7 +648,7 @@ static uint32_t vmsvga3dGetSurfaceFormatSupport(PVMSVGA3DSTATE pState3D, uint32_
 
     for (unsigned i = 0; i < RT_ELEMENTS(aFormatSupport); i++)
     {
-        hr = pState3D->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT, 
+        hr = pState3D->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT,
                                                 D3DDEVTYPE_HAL,
                                                 D3DFMT_X8R8G8B8,    /* assume standard 32-bit display mode */
                                                 aFormatSupport[i].Usage,
@@ -659,7 +663,7 @@ static uint32_t vmsvga3dGetSurfaceFormatSupport(PVMSVGA3DSTATE pState3D, uint32_
     {
         for (unsigned i = 0; i < RT_ELEMENTS(aFeatureReject); i++)
         {
-            hr = pState3D->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT, 
+            hr = pState3D->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT,
                                                     D3DDEVTYPE_HAL,
                                                     D3DFMT_X8R8G8B8,    /* assume standard 32-bit display mode */
                                                     aFeatureReject[i].Usage,
@@ -671,7 +675,7 @@ static uint32_t vmsvga3dGetSurfaceFormatSupport(PVMSVGA3DSTATE pState3D, uint32_
     }
 
     /* @todo missing:
-     * 
+     *
      * SVGA3DFORMAT_OP_PIXELSIZE
      */
 
@@ -680,7 +684,7 @@ static uint32_t vmsvga3dGetSurfaceFormatSupport(PVMSVGA3DSTATE pState3D, uint32_
     case SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8:
     case SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5:
     case SVGA3D_DEVCAP_SURFACEFMT_R5G6B5:
-        result |= SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB 
+        result |= SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB
                |  SVGA3DFORMAT_OP_CONVERT_TO_ARGB
                |  SVGA3DFORMAT_OP_DISPLAYMODE           /* Should not be set for alpha formats. */
                |  SVGA3DFORMAT_OP_3DACCELERATION;       /* implies OP_DISPLAYMODE */
@@ -690,7 +694,7 @@ static uint32_t vmsvga3dGetSurfaceFormatSupport(PVMSVGA3DSTATE pState3D, uint32_
     case SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10:
     case SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5:
     case SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4:
-        result |= SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB 
+        result |= SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB
                |  SVGA3DFORMAT_OP_CONVERT_TO_ARGB
                |  SVGA3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET;
         break;
@@ -705,15 +709,15 @@ static uint32_t vmsvga3dGetDepthFormatSupport(PVMSVGA3DSTATE pState3D, uint32_t
 {
     HRESULT  hr;
     uint32_t result = 0;
-        
-    hr = pState3D->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT, 
+
+    hr = pState3D->pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT,
                                             D3DDEVTYPE_HAL,
                                             D3DFMT_X8R8G8B8,    /* assume standard 32-bit display mode */
                                             D3DUSAGE_DEPTHSTENCIL,
                                             D3DRTYPE_SURFACE,
                                             format);
     if (hr == D3D_OK)
-        result =  SVGA3DFORMAT_OP_ZSTENCIL 
+        result =  SVGA3DFORMAT_OP_ZSTENCIL
                 | SVGA3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH
                 | SVGA3DFORMAT_OP_TEXTURE /* Necessary for Ubuntu Unity */;
 
@@ -1114,13 +1118,13 @@ int vmsvga3dQueryCaps(PVGASTATE pThis, uint32_t idx3dCaps, uint32_t *pu32Val)
     /* Dump of VMWare Player caps (from their log); for debugging purposes */
     switch (idx3dCaps)
     {
-    case 0: 
+    case 0:
         *pu32Val = 0x00000001;
         break;
     case 1:
         *pu32Val = 0x0000000a;
         break;
-    case 2: 
+    case 2:
         *pu32Val = 0x00000008;
         break;
     case 3: *pu32Val = 0x00000006; break;
@@ -1383,8 +1387,8 @@ int vmsvga3dSurfaceDefine(PVGASTATE pThis, uint32_t sid, uint32_t surfaceFlags,
     PVMSVGA3DSURFACE pSurface;
     PVMSVGA3DSTATE   pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
-   
-    Log(("vmsvga3dSurfaceDefine: sid=%x surfaceFlags=%x format=%s (%x) multiSampleCount=%d autogenFilter=%d, cMipLevels=%d size=(%d,%d,%d)\n", 
+
+    Log(("vmsvga3dSurfaceDefine: sid=%x surfaceFlags=%x format=%s (%x) multiSampleCount=%d autogenFilter=%d, cMipLevels=%d size=(%d,%d,%d)\n",
          sid, surfaceFlags, vmsvgaSurfaceType2String(format), format, multisampleCount, autogenFilter, cMipLevels, pMipLevelSize->width, pMipLevelSize->height, pMipLevelSize->depth));
 
     AssertReturn(sid < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);
@@ -1395,8 +1399,9 @@ int vmsvga3dSurfaceDefine(PVGASTATE pThis, uint32_t sid, uint32_t surfaceFlags,
 
     if (sid >= pState->cSurfaces)
     {
-        pState->paSurface = (PVMSVGA3DSURFACE )RTMemRealloc(pState->paSurface, sizeof(VMSVGA3DSURFACE) * (sid + 1));
-        AssertReturn(pState->paSurface, VERR_NO_MEMORY);
+        void *pvNew = RTMemRealloc(pState->paSurface, sizeof(VMSVGA3DSURFACE) * (sid + 1));
+        AssertReturn(pvNew, VERR_NO_MEMORY);
+        pState->paSurface = (PVMSVGA3DSURFACE)pvNew;
         memset(&pState->paSurface[pState->cSurfaces], 0, sizeof(VMSVGA3DSURFACE) * (sid + 1 - pState->cSurfaces));
         for (uint32_t i = pState->cSurfaces; i < sid + 1; i++)
             pState->paSurface[i].id = SVGA3D_INVALID_ID;
@@ -1414,7 +1419,7 @@ int vmsvga3dSurfaceDefine(PVGASTATE pThis, uint32_t sid, uint32_t surfaceFlags,
     pSurface->hSharedObject         = NULL;
     pSurface->pSharedObjectTree     = NULL;
 
-    /* The surface type is sort of undefined now, even though the hints and format can help to clear that up. 
+    /* The surface type is sort of undefined now, even though the hints and format can help to clear that up.
      * In some case we'll have to wait until the surface is used to create the D3D object.
      */
     switch (format)
@@ -1551,7 +1556,7 @@ int vmsvga3dSurfaceDefine(PVGASTATE pThis, uint32_t sid, uint32_t surfaceFlags,
         /* Unknown; decide later. */
         break;
     }
-   
+
     Assert(!pSurface->u.pSurface);
 
     /* Allocate buffer to hold the surface data until we can move it into a D3D object */
@@ -1574,7 +1579,7 @@ int vmsvga3dSurfaceDefine(PVGASTATE pThis, uint32_t sid, uint32_t surfaceFlags,
 }
 
 /*
- * Release all shared surface objects. 
+ * Release all shared surface objects.
  */
 static int vmsvga3dSharedSurfaceDestroyTree(PAVLU32NODECORE pNode, void *pParam)
 {
@@ -1614,7 +1619,7 @@ int vmsvga3dSurfaceDestroy(PVGASTATE pThis, uint32_t sid)
         /* Check all contexts if this surface is used as a render target or active texture. */
         for (uint32_t cid = 0; cid < pState->cContexts; cid++)
         {
-            PVMSVGA3DCONTEXT pContext = &pState->paContext[cid];
+            PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
             if (pContext->id == cid)
             {
                 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->aSidActiveTexture); i++)
@@ -1630,7 +1635,9 @@ int vmsvga3dSurfaceDestroy(PVGASTATE pThis, uint32_t sid)
         RTAvlU32Destroy(&pSurface->pSharedObjectTree, vmsvga3dSharedSurfaceDestroyTree, pSurface);
         Assert(pSurface->pSharedObjectTree == NULL);
 
-        switch (pSurface->flags & (SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP))
+        switch (pSurface->flags & (  SVGA3D_SURFACE_HINT_INDEXBUFFER  | SVGA3D_SURFACE_HINT_VERTEXBUFFER
+                                   | SVGA3D_SURFACE_HINT_TEXTURE      | SVGA3D_SURFACE_HINT_RENDERTARGET
+                                   | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP))
         {
         case SVGA3D_SURFACE_CUBEMAP:
             AssertFailed(); /* @todo */
@@ -1705,13 +1712,13 @@ static PVMSVGA3DSHAREDSURFACE vmsvga3dSurfaceGetSharedCopy(PVGASTATE pThis, PVMS
         HRESULT hr;
         bool    ret;
 
-        Log(("vmsvga3dSurfaceGetSharedCopy: Create shared texture copy d3d (%d,%d) cMip=%d usage %x format %x.\n", 
-              pSurface->pMipmapLevels[0].size.width, 
-              pSurface->pMipmapLevels[0].size.height, 
-              pSurface->faces[0], 
+        Log(("vmsvga3dSurfaceGetSharedCopy: Create shared texture copy d3d (%d,%d) cMip=%d usage %x format %x.\n",
+              pSurface->pMipmapLevels[0].size.width,
+              pSurface->pMipmapLevels[0].size.height,
+              pSurface->faces[0],
               pSurface->fUsageD3D | D3DUSAGE_RENDERTARGET,
               pSurface->formatD3D));
-            
+
         pSharedSurface = (PVMSVGA3DSHAREDSURFACE)RTMemAllocZ(sizeof(*pSharedSurface));
         AssertReturn(pSharedSurface, NULL);
 
@@ -1720,9 +1727,9 @@ static PVMSVGA3DSHAREDSURFACE vmsvga3dSurfaceGetSharedCopy(PVGASTATE pThis, PVMS
         AssertReturn(ret, NULL);
 
         /* Create shadow copy of the original shared texture. Shared d3d resources require Vista+ and have some restrictions. */
-        hr = pContext->pDevice->CreateTexture(pSurface->pMipmapLevels[0].size.width, 
-                                              pSurface->pMipmapLevels[0].size.height, 
-                                              pSurface->faces[0].numMipLevels, 
+        hr = pContext->pDevice->CreateTexture(pSurface->pMipmapLevels[0].size.width,
+                                              pSurface->pMipmapLevels[0].size.height,
+                                              pSurface->faces[0].numMipLevels,
                                               pSurface->fUsageD3D | D3DUSAGE_RENDERTARGET /* required for use as a StretchRect destination */,
                                               pSurface->formatD3D,
                                               D3DPOOL_DEFAULT,
@@ -1737,7 +1744,7 @@ static PVMSVGA3DSHAREDSURFACE vmsvga3dSurfaceGetSharedCopy(PVGASTATE pThis, PVMS
 #define vmsvga3dSurfaceTrackUsage(a, b, c)
 #define vmsvga3dSurfaceFlush(a, b)
 #else
-/* Inject a query event into the D3D pipeline so we can check when usage of this surface has finished. 
+/* Inject a query event into the D3D pipeline so we can check when usage of this surface has finished.
  * (D3D does not synchronize shared surface usage)
  */
 static int vmsvga3dSurfaceTrackUsage(PVGASTATE pThis, PVMSVGA3DCONTEXT pContext, uint32_t sid)
@@ -1837,12 +1844,12 @@ int vmsvga3dSurfaceCopy(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3dSurfac
         /* @todo stricter checks for associated context */
         cid = pSurfaceSrc->idAssociatedContext;
         if (    cid >= pState->cContexts
-            ||  pState->paContext[cid].id != cid)
+            ||  pState->papContexts[cid]->id != cid)
         {
             Log(("vmsvga3dSurfaceCopy invalid context id!\n"));
             return VERR_INVALID_PARAMETER;
         }
-        pContext = &pState->paContext[cid];
+        pContext = pState->papContexts[cid];
 
         Log(("vmsvga3dSurfaceCopy: create texture surface id=%x type=%d format=%d -> create texture\n", sidDest, pSurfaceDest->flags, pSurfaceDest->format));
         rc = vmsvga3dCreateTexture(pContext, cid, pSurfaceDest);
@@ -1859,19 +1866,19 @@ int vmsvga3dSurfaceCopy(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3dSurfac
         /* @todo stricter checks for associated context */
         cid = pSurfaceDest->idAssociatedContext;
         if (    cid >= pState->cContexts
-            ||  pState->paContext[cid].id != cid)   
+            ||  pState->papContexts[cid]->id != cid)
         {
             Log(("vmsvga3dSurfaceCopy invalid context id!\n"));
             return VERR_INVALID_PARAMETER;
         }
-        pContext = &pState->paContext[cid];
+        pContext = pState->papContexts[cid];
 
         /* Must flush the other context's 3d pipeline to make sure all drawing is complete for the surface we're about to use. */
         vmsvga3dSurfaceFlush(pThis, pSurfaceSrc);
         vmsvga3dSurfaceFlush(pThis, pSurfaceDest);
 
 #ifndef VBOX_VMSVGA3D_WITH_OPENGL
-        if (    fSrcTexture 
+        if (    fSrcTexture
             &&  pSurfaceSrc->idAssociatedContext != cid)
         {
             Log(("vmsvga3dSurfaceCopy; using texture %x created for another context (%d vs %d)\n", sidSrc, pSurfaceSrc->idAssociatedContext, cid));
@@ -1960,7 +1967,7 @@ int vmsvga3dSurfaceCopy(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3dSurfac
         Rect.bottom = pBox[i].srcy + pBox[i].h;   /* exclusive */
 
         Log(("vmsvga3dSurfaceCopy: (manual) copy src=%x src=%x face=%d (%d,%d)(%d,%d) to dest=%x src=%x face=%d (%d,%d)\n", sidSrc, src.face, src.mipmap, Rect.left, Rect.top, Rect.right, Rect.bottom, sidDest, dest.face, dest.mipmap, pBox[i].x, pBox[i].y));
-            
+
         Assert(!pBox[i].srcz && !pBox[i].z);
 
         if (!pSurfaceSrc->u.pSurface)
@@ -2059,8 +2066,8 @@ static int vmsvga3dCreateTexture(PVMSVGA3DCONTEXT pContext, uint32_t idAssociate
     {
         Assert(pSurface->faces[0].numMipLevels == 1);
         /* Use the INTZ format for a depth/stencil surface that will be used as a texture */
-        hr = pContext->pDevice->CreateTexture(pSurface->pMipmapLevels[0].size.width, 
-                                              pSurface->pMipmapLevels[0].size.height, 
+        hr = pContext->pDevice->CreateTexture(pSurface->pMipmapLevels[0].size.width,
+                                              pSurface->pMipmapLevels[0].size.height,
                                               1,
                                               D3DUSAGE_DEPTHSTENCIL,
                                               FOURCC_INTZ,
@@ -2074,9 +2081,9 @@ static int vmsvga3dCreateTexture(PVMSVGA3DCONTEXT pContext, uint32_t idAssociate
     }
     else
     {
-        hr = pContext->pDevice->CreateTexture(pSurface->pMipmapLevels[0].size.width, 
-                                              pSurface->pMipmapLevels[0].size.height, 
-                                              pSurface->faces[0].numMipLevels, 
+        hr = pContext->pDevice->CreateTexture(pSurface->pMipmapLevels[0].size.width,
+                                              pSurface->pMipmapLevels[0].size.height,
+                                              pSurface->faces[0].numMipLevels,
                                               pSurface->fUsageD3D | D3DUSAGE_RENDERTARGET /* required for use as a StretchRect destination */,
                                               pSurface->formatD3D,
                                               D3DPOOL_DEFAULT,
@@ -2084,10 +2091,10 @@ static int vmsvga3dCreateTexture(PVMSVGA3DCONTEXT pContext, uint32_t idAssociate
                                               &pSurface->hSharedObject);
         if (hr == D3D_OK)
         {
-            /* Create another texture object to serve as a bounce buffer as the above texture surface can't be locked. */ 
-            hr = pContext->pDevice->CreateTexture(pSurface->pMipmapLevels[0].size.width, 
-                                                  pSurface->pMipmapLevels[0].size.height, 
-                                                  pSurface->faces[0].numMipLevels, 
+            /* Create another texture object to serve as a bounce buffer as the above texture surface can't be locked. */
+            hr = pContext->pDevice->CreateTexture(pSurface->pMipmapLevels[0].size.width,
+                                                  pSurface->pMipmapLevels[0].size.height,
+                                                  pSurface->faces[0].numMipLevels,
                                                   (pSurface->fUsageD3D & ~D3DUSAGE_RENDERTARGET) | D3DUSAGE_DYNAMIC /* Lockable */,
                                                   pSurface->formatD3D,
                                                   D3DPOOL_SYSTEMMEM,
@@ -2100,9 +2107,9 @@ static int vmsvga3dCreateTexture(PVMSVGA3DCONTEXT pContext, uint32_t idAssociate
         {
             Log(("Format not accepted -> try old method\n"));
             /* The format was probably not accepted; fall back to our old mode. */
-            hr = pContext->pDevice->CreateTexture(pSurface->pMipmapLevels[0].size.width, 
-                                                  pSurface->pMipmapLevels[0].size.height, 
-                                                  pSurface->faces[0].numMipLevels, 
+            hr = pContext->pDevice->CreateTexture(pSurface->pMipmapLevels[0].size.width,
+                                                  pSurface->pMipmapLevels[0].size.height,
+                                                  pSurface->faces[0].numMipLevels,
                                                   (pSurface->fUsageD3D & ~D3DUSAGE_RENDERTARGET) |  D3DUSAGE_DYNAMIC /* Lockable */,
                                                   pSurface->formatD3D,
                                                   D3DPOOL_DEFAULT,
@@ -2205,12 +2212,12 @@ int vmsvga3dSurfaceStretchBlt(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3d
         cid = pSurfaceSrc->idAssociatedContext;
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSurfaceStretchBlt invalid context id!\n"));
         AssertFailedReturn(VERR_INVALID_PARAMETER);
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
 
     if (!pSurfaceSrc->u.pSurface)
     {
@@ -2322,9 +2329,9 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
     pMipLevel = &pSurface->pMipmapLevels[host.mipmap];
 
     if (pSurface->flags & SVGA3D_SURFACE_HINT_TEXTURE)
-        Log(("vmsvga3dSurfaceDMA TEXTURE guestptr gmr=%x offset=%x pitch=%x host sid=%x face=%d mipmap=%d transfer=%x cCopyBoxes=%d\n", guest.ptr.gmrId, guest.ptr.offset, guest.pitch, host.sid, host.face, host.mipmap, transfer, cCopyBoxes));
+        Log(("vmsvga3dSurfaceDMA TEXTURE guestptr gmr=%x offset=%x pitch=%x host sid=%x face=%d mipmap=%d transfer=%s cCopyBoxes=%d\n", guest.ptr.gmrId, guest.ptr.offset, guest.pitch, host.sid, host.face, host.mipmap, (transfer == SVGA3D_WRITE_HOST_VRAM) ? "READ" : "WRITE", cCopyBoxes));
     else
-        Log(("vmsvga3dSurfaceDMA guestptr gmr=%x offset=%x pitch=%x host sid=%x face=%d mipmap=%d transfer=%x cCopyBoxes=%d\n", guest.ptr.gmrId, guest.ptr.offset, guest.pitch, host.sid, host.face, host.mipmap, transfer, cCopyBoxes));
+        Log(("vmsvga3dSurfaceDMA guestptr gmr=%x offset=%x pitch=%x host sid=%x face=%d mipmap=%d transfer=%s cCopyBoxes=%d\n", guest.ptr.gmrId, guest.ptr.offset, guest.pitch, host.sid, host.face, host.mipmap, (transfer == SVGA3D_WRITE_HOST_VRAM) ? "READ" : "WRITE", cCopyBoxes));
 
     if (!pSurface->u.pSurface)
     {
@@ -2360,10 +2367,10 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
 
             cbSrcPitch = (guest.pitch == 0) ? pBoxes[i].w * pSurface->cbBlock : guest.pitch;
 
-            rc = vmsvgaGMRTransfer(pThis, 
+            rc = vmsvgaGMRTransfer(pThis,
                                     transfer,
-                                    (uint8_t *)pMipLevel->pSurfaceData + uDestOffset, 
-                                    pMipLevel->cbSurfacePitch, 
+                                    (uint8_t *)pMipLevel->pSurfaceData + uDestOffset,
+                                    pMipLevel->cbSurfacePitch,
                                     guest.ptr,
                                     pBoxes[i].srcx * pSurface->cbBlock + (pBoxes[i].srcy + pBoxes[i].srcz * pBoxes[i].h) * cbSrcPitch,
                                     cbSrcPitch,
@@ -2452,12 +2459,12 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
                             /* @todo stricter checks for associated context */
                             uint32_t cid = pSurface->idAssociatedContext;
                             if (    cid >= pState->cContexts
-                                ||  pState->paContext[cid].id != cid)
+                                ||  pState->papContexts[cid]->id != cid)
                             {
-                                Log(("vmsvga3dSurfaceDMA invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->paContext[cid].id));
+                                Log(("vmsvga3dSurfaceDMA invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
                                 AssertFailedReturn(VERR_INVALID_PARAMETER);
                             }
-                            PVMSVGA3DCONTEXT pContext = &pState->paContext[cid];
+                            PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
 
                             /* @todo only sync when something was actually rendered (since the last sync) */
                             Log(("vmsvga3dSurfaceDMA: sync bounce buffer\n"));
@@ -2495,11 +2502,11 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
                     Log(("Lock TEXTURE (bounce=%d) memory for rectangle (%d,%d)(%d,%d)\n", !!(pSurface->bounce.pTexture), Rect.left, Rect.top, Rect.right, Rect.bottom));
                 else
                     Log(("Lock %s memory for rectangle (%d,%d)(%d,%d)\n", (pSurface->flags & SVGA3D_SURFACE_HINT_DEPTHSTENCIL) ? "DEPTH-STENCIL" : "RENDERTARGET", Rect.left, Rect.top, Rect.right, Rect.bottom));
-                
-                rc = vmsvgaGMRTransfer(pThis, 
+
+                rc = vmsvgaGMRTransfer(pThis,
                                        transfer,
-                                       (uint8_t *)LockedRect.pBits, 
-                                       LockedRect.Pitch, 
+                                       (uint8_t *)LockedRect.pBits,
+                                       LockedRect.Pitch,
                                        guest.ptr,
                                        pBoxes[i].srcx * pSurface->cbBlock + pBoxes[i].srcy * cbSrcPitch,
                                        cbSrcPitch,
@@ -2521,12 +2528,12 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
                             /* @todo stricter checks for associated context */
                             uint32_t cid = pSurface->idAssociatedContext;
                             if (    cid >= pState->cContexts
-                                ||  pState->paContext[cid].id != cid)
+                                ||  pState->papContexts[cid]->id != cid)
                             {
                                 Log(("vmsvga3dSurfaceDMA invalid context id!\n"));
                                 AssertFailedReturn(VERR_INVALID_PARAMETER);
                             }
-                            PVMSVGA3DCONTEXT pContext = &pState->paContext[cid];
+                            PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
 
                             Log(("vmsvga3dSurfaceDMA: sync texture from bounce buffer\n"));
 
@@ -2562,16 +2569,16 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
                 /** @todo lock only as much as we really need */
                 if (fVertex)
                     hr = pSurface->u.pVertexBuffer->Lock(0, 0, (void **)&pData, dwFlags);
-                else        
+                else
                     hr = pSurface->u.pIndexBuffer->Lock(0, 0, (void **)&pData, dwFlags);
                 AssertMsg(hr == D3D_OK, ("vmsvga3dSurfaceDMA: Lock %s failed with %x\n", (fVertex) ? "vertex" : "index", hr));
 
                 Log(("Lock %s memory for rectangle (%d,%d)(%d,%d)\n", (fVertex) ? "vertex" : "index", pBoxes[i].x, pBoxes[i].y, pBoxes[i].x + pBoxes[i].w, pBoxes[i].y + pBoxes[i].h));
 
-                rc = vmsvgaGMRTransfer(pThis, 
+                rc = vmsvgaGMRTransfer(pThis,
                                        transfer,
-                                       pData + uDestOffset, 
-                                       pSurface->pMipmapLevels[host.mipmap].cbSurfacePitch, 
+                                       pData + uDestOffset,
+                                       pSurface->pMipmapLevels[host.mipmap].cbSurfacePitch,
                                        guest.ptr,
                                        pBoxes[i].srcx * pSurface->cbBlock + pBoxes[i].srcy * cbSrcPitch,
                                        cbSrcPitch,
@@ -2618,7 +2625,7 @@ int vmsvga3dSurfaceBlitToScreen(PVGASTATE pThis, uint32_t dest, SVGASignedRect d
         /* easy case; no clipping */
         SVGA3dCopyBox        box;
         SVGA3dGuestImage     dest;
-       
+
         box.x       = destRect.left;
         box.y       = destRect.top;
         box.z       = 0;
@@ -2654,7 +2661,7 @@ int vmsvga3dSurfaceBlitToScreen(PVGASTATE pThis, uint32_t dest, SVGASignedRect d
 
         /* @todo merge into one SurfaceDMA call */
         for (uint32_t i = 0; i < cRects; i++)
-        {   
+        {
             /* The clipping rectangle is relative to the top-left corner of srcRect & destRect. Adjust here. */
             box.srcx = srcRect.left + pRect[i].left;
             box.srcy = srcRect.top  + pRect[i].top;
@@ -2688,12 +2695,12 @@ int vmsvga3dSurfaceBlitToScreen(PVGASTATE pThis, uint32_t dest, SVGASignedRect d
             cid = pSurface->idAssociatedContext;
 
             if (    cid >= pState->cContexts
-                ||  pState->paContext[cid].id != cid)
+                ||  pState->papContexts[cid]->id != cid)
             {
                 Log(("vmsvga3dGenerateMipmaps invalid context id!\n"));
                 return VERR_INVALID_PARAMETER;
             }
-            pContext = &pState->paContext[cid];
+            pContext = pState->papContexts[cid];
 
             if (pSurface->id == 0x5e)
             {
@@ -2742,12 +2749,12 @@ int vmsvga3dGenerateMipmaps(PVGASTATE pThis, uint32_t sid, SVGA3dTextureFilter f
         cid = pSurface->idAssociatedContext;
 
         if (    cid >= pState->cContexts
-            ||  pState->paContext[cid].id != cid)
+            ||  pState->papContexts[cid]->id != cid)
         {
             Log(("vmsvga3dGenerateMipmaps invalid context id!\n"));
             return VERR_INVALID_PARAMETER;
         }
-        pContext = &pState->paContext[cid];
+        pContext = pState->papContexts[cid];
 
         /* Unknown surface type; turn it into a texture. */
         Log(("vmsvga3dGenerateMipmaps: unknown src surface id=%x type=%d format=%d -> create texture\n", sid, pSurface->flags, pSurface->format));
@@ -2776,7 +2783,7 @@ int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3
     HRESULT             hr;
     IDirect3DSurface9  *pBackBuffer;
     IDirect3DSurface9  *pSurfaceD3D;
-    struct 
+    struct
     {
         uint32_t        x;
         uint32_t        y;
@@ -2800,12 +2807,12 @@ int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3
     }
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dCommandPresent invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
 
     hr = pContext->pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
     AssertMsgReturn(hr == D3D_OK, ("vmsvga3dCommandPresent: GetBackBuffer failed with %x\n", hr), VERR_INTERNAL_ERROR);
@@ -2813,7 +2820,7 @@ int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3
     if (pSurface->flags & SVGA3D_SURFACE_HINT_TEXTURE)
     {
         hr = pSurface->u.pTexture->GetSurfaceLevel(0, &pSurfaceD3D);
-        AssertMsgReturn(hr == D3D_OK, ("vmsvga3dCommandPresent: GetSurfaceLevel failed with %x\n", hr), VERR_INTERNAL_ERROR);        
+        AssertMsgReturn(hr == D3D_OK, ("vmsvga3dCommandPresent: GetSurfaceLevel failed with %x\n", hr), VERR_INTERNAL_ERROR);
     }
     else
         pSurfaceD3D = pSurface->u.pSurface;
@@ -2902,9 +2909,8 @@ int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3
  * @returns VBox status code.
  * @param   pThis           VGA device instance data.
  * @param   cid             Context id
- * @param   fOtherProfile   OpenGL(+darwin) specific argument, ignored.
  */
-int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fOtherProfile)
+int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid)
 {
     int                     rc;
     PVMSVGA3DCONTEXT        pContext;
@@ -2914,25 +2920,29 @@ int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fOtherProfile)
 
     AssertReturn(pState, VERR_NO_MEMORY);
     AssertReturn(cid < SVGA3D_MAX_CONTEXT_IDS, VERR_INVALID_PARAMETER);
-    NOREF(fOtherProfile);
 
     Log(("vmsvga3dContextDefine id %x\n", cid));
 
     if (cid >= pState->cContexts)
     {
-        pState->paContext = (PVMSVGA3DCONTEXT)RTMemRealloc(pState->paContext, sizeof(VMSVGA3DCONTEXT) * (cid + 1));
-        AssertReturn(pState->paContext, VERR_NO_MEMORY);
-        memset(&pState->paContext[pState->cContexts], 0, sizeof(VMSVGA3DCONTEXT) * (cid + 1 - pState->cContexts));
-        for (uint32_t i = pState->cContexts; i < cid + 1; i++)
-            pState->paContext[i].id = SVGA3D_INVALID_ID;
-
-        pState->cContexts = cid + 1;
+        /* Grow the array. */
+        uint32_t cNew = RT_ALIGN(cid + 15, 16);
+        void *pvNew = RTMemRealloc(pState->papContexts, sizeof(pState->papContexts[0]) * cNew);
+        AssertReturn(pvNew, VERR_NO_MEMORY);
+        pState->papContexts = (PVMSVGA3DCONTEXT *)pvNew;
+        while (pState->cContexts < cNew)
+        {
+            pContext = (PVMSVGA3DCONTEXT)RTMemAllocZ(sizeof(*pContext));
+            AssertReturn(pContext, VERR_NO_MEMORY);
+            pContext->id = SVGA3D_INVALID_ID;
+            pState->papContexts[pState->cContexts++] = pContext;
+        }
     }
     /* If one already exists with this id, then destroy it now. */
-    if (pState->paContext[cid].id != SVGA3D_INVALID_ID)
+    if (pState->papContexts[cid]->id != SVGA3D_INVALID_ID)
         vmsvga3dContextDestroy(pThis, cid);
 
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     memset(pContext, 0, sizeof(*pContext));
     pContext->id               = cid;
     for (uint32_t i = 0; i< RT_ELEMENTS(pContext->aSidActiveTexture); i++)
@@ -3029,9 +3039,9 @@ int vmsvga3dContextDestroy(PVGASTATE pThis, uint32_t cid)
     AssertReturn(cid < SVGA3D_MAX_CONTEXT_IDS, VERR_INVALID_PARAMETER);
 
     if (    cid < pState->cContexts
-        &&  pState->paContext[cid].id == cid)
+        &&  pState->papContexts[cid]->id == cid)
     {
-        PVMSVGA3DCONTEXT pContext = &pState->paContext[cid];
+        PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
 
         Log(("vmsvga3dContextDestroy id %x\n", cid));
 
@@ -3171,7 +3181,7 @@ int vmsvga3dChangeMode(PVGASTATE pThis)
     /* Resize all active contexts. */
     for (uint32_t i = 0; i < pState->cContexts; i++)
     {
-        PVMSVGA3DCONTEXT pContext = &pState->paContext[i];
+        PVMSVGA3DCONTEXT pContext = pState->papContexts[i];
         uint32_t cid = pContext->id;
 
         if (cid != SVGA3D_INVALID_ID)
@@ -3295,7 +3305,7 @@ int vmsvga3dChangeMode(PVGASTATE pThis)
                 }
             }
 #endif /* #ifdef VMSVGA3D_DIRECT3D9_RESET */
-            memset(&cs, 0, sizeof(cs));            
+            memset(&cs, 0, sizeof(cs));
             cs.cx = pThis->svga.uWidth;
             cs.cy = pThis->svga.uHeight;
 
@@ -3423,12 +3433,12 @@ int vmsvga3dSetTransform(PVGASTATE pThis, uint32_t cid, SVGA3dTransformType type
     Log(("vmsvga3dSetTransform %x %s\n", cid, vmsvgaTransformToString(type)));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetTransform invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
 
     switch (type)
     {
@@ -3505,12 +3515,12 @@ int vmsvga3dSetZRange(PVGASTATE pThis, uint32_t cid, SVGA3dZRange zRange)
     Log(("vmsvga3dSetZRange %x min=%d max=%d\n", cid, (uint32_t)(zRange.min * 100.0), (uint32_t)(zRange.max * 100.0)));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetZRange invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     pContext->state.zRange = zRange;
     pContext->state.u32UpdateFlags |= VMSVGA3D_UPDATE_ZRANGE;
 
@@ -3578,15 +3588,15 @@ int vmsvga3dSetRenderState(PVGASTATE pThis, uint32_t cid, uint32_t cRenderStates
     PVMSVGA3DSTATE              pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
-    Log(("vmsvga3dSetRenderState %x cRenderStates=%d\n", cid, cRenderStates));
+    Log(("vmsvga3dSetRenderState cid=%x cRenderStates=%d\n", cid, cRenderStates));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetRenderState invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
 
     for (unsigned i = 0; i < cRenderStates; i++)
     {
@@ -3599,7 +3609,7 @@ int vmsvga3dSetRenderState(PVGASTATE pThis, uint32_t cid, uint32_t cRenderStates
 
         switch (pRenderState[i].state)
         {
-        case SVGA3D_RS_ZENABLE:                /* SVGA3dBool */            
+        case SVGA3D_RS_ZENABLE:                /* SVGA3dBool */
             renderState = D3DRS_ZENABLE;
             val = pRenderState[i].uintValue;
             Assert(val == D3DZB_FALSE || val == D3DZB_TRUE);
@@ -4257,12 +4267,12 @@ int vmsvga3dSetRenderTarget(PVGASTATE pThis, uint32_t cid, SVGA3dRenderTargetTyp
     Log(("vmsvga3dSetRenderTarget cid=%x type=%x surface id=%x\n", cid, type, target.sid));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetRenderTarget invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
 
     /* Save for vm state save/restore. */
     pContext->state.aRenderTargets[type] = target.sid;
@@ -4297,13 +4307,13 @@ int vmsvga3dSetRenderTarget(PVGASTATE pThis, uint32_t cid, SVGA3dRenderTargetTyp
                  * wishing to update an actual color render target
                  */
                 IDirect3DSurface9* pDummyRenderTarget;
-                hr = pContext->pDevice->CreateRenderTarget(pThis->svga.uWidth, 
-                                                           pThis->svga.uHeight, 
+                hr = pContext->pDevice->CreateRenderTarget(pThis->svga.uWidth,
+                                                           pThis->svga.uHeight,
                                                            FOURCC_NULL,
-                                                           D3DMULTISAMPLE_NONE, 
-                                                           0, 
-                                                           FALSE, 
-                                                           &pDummyRenderTarget, 
+                                                           D3DMULTISAMPLE_NONE,
+                                                           0,
+                                                           FALSE,
+                                                           &pDummyRenderTarget,
                                                            NULL);
 
                 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSetRenderTarget: CreateRenderTarget failed with %x\n", hr), VERR_INTERNAL_ERROR);
@@ -4356,11 +4366,11 @@ int vmsvga3dSetRenderTarget(PVGASTATE pThis, uint32_t cid, SVGA3dRenderTargetTyp
                 int rc = vmsvga3dCreateTexture(pContext, cid, pRenderTarget);
                 AssertRC(rc);   /* non-fatal */
             }
-            
+
             if (!pRenderTarget->fStencilAsTexture)
             {
                 Log(("vmsvga3dSetRenderTarget DEPTH/STENCIL; cQualityLevels=%d\n", cQualityLevels));
-                hr = pContext->pDevice->CreateDepthStencilSurface(pRenderTarget->pMipmapLevels[0].size.width, 
+                hr = pContext->pDevice->CreateDepthStencilSurface(pRenderTarget->pMipmapLevels[0].size.width,
                                                                   pRenderTarget->pMipmapLevels[0].size.height,
                                                                   pRenderTarget->formatD3D,
                                                                   pRenderTarget->multiSampleTypeD3D,
@@ -4509,8 +4519,8 @@ int vmsvga3dSetRenderTarget(PVGASTATE pThis, uint32_t cid, SVGA3dRenderTargetTyp
                 Log(("vmsvga3dSetRenderTarget COLOR; cQualityLevels=%d\n", cQualityLevels));
                 Log(("Create rendertarget (%d,%d) format=%x multisample=%x\n", pRenderTarget->pMipmapLevels[0].size.width, pRenderTarget->pMipmapLevels[0].size.height, pRenderTarget->formatD3D, pRenderTarget->multiSampleTypeD3D));
 
-                hr = pContext->pDevice->CreateRenderTarget(pRenderTarget->pMipmapLevels[0].size.width, 
-                                                           pRenderTarget->pMipmapLevels[0].size.height, 
+                hr = pContext->pDevice->CreateRenderTarget(pRenderTarget->pMipmapLevels[0].size.width,
+                                                           pRenderTarget->pMipmapLevels[0].size.height,
                                                            pRenderTarget->formatD3D,
                                                            pRenderTarget->multiSampleTypeD3D,
                                                            ((cQualityLevels >= 1) ? cQualityLevels - 1 : 0),   /* 0 - (levels-1) */
@@ -4544,6 +4554,9 @@ int vmsvga3dSetRenderTarget(PVGASTATE pThis, uint32_t cid, SVGA3dRenderTargetTyp
         /* Changing the render target resets the viewport; restore it here. */
         if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_VIEWPORT)
             vmsvga3dSetViewPort(pThis, cid, &pContext->state.RectViewPort);
+        /* Changing the render target also resets the scissor rectangle; restore it as well. */
+        if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_SCISSORRECT)
+            vmsvga3dSetScissorRect(pThis, cid, &pContext->state.RectScissor);
 
         break;
     }
@@ -4680,24 +4693,34 @@ int vmsvga3dSetTextureState(PVGASTATE pThis, uint32_t cid, uint32_t cTextureStat
     Log(("vmsvga3dSetTextureState %x cTextureState=%d\n", cid, cTextureStates));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetTextureState invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
 
     for (unsigned i = 0; i < cTextureStates; i++)
     {
         D3DTEXTURESTAGESTATETYPE textureType = D3DTSS_FORCE_DWORD;
         D3DSAMPLERSTATETYPE      samplerType = D3DSAMP_FORCE_DWORD;
+        uint32_t                 currentStage = pTextureState[i].stage;
+
+        Log(("vmsvga3dSetTextureState: cid=%x stage=%d type=%s (%x) val=%x\n", cid, currentStage, vmsvga3dTextureStateToString(pTextureState[i].name), pTextureState[i].name, pTextureState[i].value));
+
+        /** @todo Is this the appropriate limit for all kinds of textures?  It is the
+         * size of aSidActiveTexture and for binding/unbinding we cannot exceed it. */
+        if (RT_UNLIKELY(currentStage >= SVGA3D_MAX_TEXTURE_STAGE))
+        {
+            AssertMsgFailed(("pTextureState[%d].stage=%#x name=%#x\n", i, pTextureState[i].stage, pTextureState[i].name));
+            continue;
+        }
 
-        Log(("vmsvga3dSetTextureState: cid=%x stage=%d type=%s (%x) val=%x\n", cid, pTextureState[i].stage, vmsvga3dTextureStateToString(pTextureState[i].name), pTextureState[i].name, pTextureState[i].value));
         /* Record the texture state for vm state saving. */
-        if (    pTextureState[i].stage < SVGA3D_MAX_TEXTURE_STAGE
+        if (    currentStage < SVGA3D_MAX_TEXTURE_STAGE
             &&  pTextureState[i].name < SVGA3D_TS_MAX)
         {
-            pContext->state.aTextureState[pTextureState[i].stage][pTextureState[i].name] = pTextureState[i];
+            pContext->state.aTextureState[currentStage][pTextureState[i].name] = pTextureState[i];
         }
 
         switch (pTextureState[i].name)
@@ -4785,12 +4808,11 @@ int vmsvga3dSetTextureState(PVGASTATE pThis, uint32_t cid, uint32_t cTextureStat
         case SVGA3D_TS_BIND_TEXTURE:                /* SVGA3dSurfaceId */
             if (pTextureState[i].value == SVGA3D_INVALID_ID)
             {
-                Log(("SVGA3D_TS_BIND_TEXTURE: stage %d, texture surface id=%x\n", pTextureState[i].stage, pTextureState[i].value));
+                Log(("SVGA3D_TS_BIND_TEXTURE: stage %d, texture surface id=%x\n", currentStage, pTextureState[i].value));
 
-                pContext->aSidActiveTexture[pTextureState[i].stage] = SVGA3D_INVALID_ID;
+                pContext->aSidActiveTexture[currentStage] = SVGA3D_INVALID_ID;
                 /* Unselect the currently associated texture. */
-                hr = pContext->pDevice->SetTexture(pTextureState[i].stage,
-                                                   NULL);
+                hr = pContext->pDevice->SetTexture(currentStage, NULL);
                 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSetTextureState: SetTexture failed with %x\n", hr), VERR_INTERNAL_ERROR);
             }
             else
@@ -4803,7 +4825,7 @@ int vmsvga3dSetTextureState(PVGASTATE pThis, uint32_t cid, uint32_t cTextureStat
 
                 PVMSVGA3DSURFACE pSurface = &pState->paSurface[sid];
 
-                Log(("SVGA3D_TS_BIND_TEXTURE: stage %d, texture surface id=%x (%d,%d)\n", pTextureState[i].stage, pTextureState[i].value, pSurface->pMipmapLevels[0].size.width, pSurface->pMipmapLevels[0].size.height));
+                Log(("SVGA3D_TS_BIND_TEXTURE: stage %d, texture surface id=%x (%d,%d)\n", currentStage, pTextureState[i].value, pSurface->pMipmapLevels[0].size.width, pSurface->pMipmapLevels[0].size.height));
 
                 if (!pSurface->u.pTexture)
                 {
@@ -4822,21 +4844,19 @@ int vmsvga3dSetTextureState(PVGASTATE pThis, uint32_t cid, uint32_t cTextureStat
                 if (pSurface->idAssociatedContext != cid)
                 {
                     Log(("vmsvga3dSetTextureState; using texture %x created for another context (%d vs %d)\n", sid, pSurface->idAssociatedContext, cid));
-    
+
                     PVMSVGA3DSHAREDSURFACE pSharedSurface = vmsvga3dSurfaceGetSharedCopy(pThis, pContext, pSurface);
                     AssertReturn(pSharedSurface, VERR_INTERNAL_ERROR);
 
-                    hr = pContext->pDevice->SetTexture(pTextureState[i].stage,
-                                                       pSharedSurface->u.pTexture);
+                    hr = pContext->pDevice->SetTexture(currentStage, pSharedSurface->u.pTexture);
                 }
                 else
 #endif
-                    hr = pContext->pDevice->SetTexture(pTextureState[i].stage,
-                                                       pSurface->u.pTexture);
+                    hr = pContext->pDevice->SetTexture(currentStage, pSurface->u.pTexture);
 
                 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSetTextureState: SetTexture failed with %x\n", hr), VERR_INTERNAL_ERROR);
 
-                pContext->aSidActiveTexture[pTextureState[i].stage] = sid;
+                pContext->aSidActiveTexture[currentStage] = sid;
             }
             /* Finished; continue with the next one. */
             continue;
@@ -4884,22 +4904,22 @@ int vmsvga3dSetTextureState(PVGASTATE pThis, uint32_t cid, uint32_t cTextureStat
             samplerType = D3DSAMP_BORDERCOLOR;
             val = pTextureState[i].value;   /* Identical */
             break;
-            
+
         case SVGA3D_TS_TEXTURE_LOD_BIAS:            /* float */
             samplerType = D3DSAMP_MIPMAPLODBIAS;
             val = pTextureState[i].value;   /* Identical */
             break;
-            
+
         case SVGA3D_TS_TEXTURE_MIPMAP_LEVEL:        /* uint32_t */
             samplerType = D3DSAMP_MAXMIPLEVEL;
             val = pTextureState[i].value;   /* Identical?? */
             break;
-            
+
         case SVGA3D_TS_TEXTURE_ANISOTROPIC_LEVEL:   /* uint32_t */
             samplerType = D3DSAMP_MAXANISOTROPY;
             val = pTextureState[i].value;   /* Identical?? */
             break;
-            
+
         case SVGA3D_TS_GAMMA:                       /* float */
             samplerType = D3DSAMP_SRGBTEXTURE;
             /* Boolean in D3D */
@@ -4907,7 +4927,7 @@ int vmsvga3dSetTextureState(PVGASTATE pThis, uint32_t cid, uint32_t cTextureStat
                 val = FALSE;
             else
                 val = TRUE;
-            break;           
+            break;
 
         /* Internal commands, that don't map directly to the SetTextureStageState API. */
         case SVGA3D_TS_TEXCOORDGEN:                 /* SVGA3dTextureCoordGen */
@@ -4917,12 +4937,12 @@ int vmsvga3dSetTextureState(PVGASTATE pThis, uint32_t cid, uint32_t cTextureStat
 
         if (textureType != D3DTSS_FORCE_DWORD)
         {
-            hr = pContext->pDevice->SetTextureStageState(pTextureState[i].stage, textureType, val);
+            hr = pContext->pDevice->SetTextureStageState(currentStage, textureType, val);
         }
         else
         {
             Assert(samplerType != D3DSAMP_FORCE_DWORD);
-            hr = pContext->pDevice->SetSamplerState(pTextureState[i].stage, samplerType, val);
+            hr = pContext->pDevice->SetSamplerState(currentStage, samplerType, val);
         }
 
         AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSetTextureState: SetTextureStageState failed with %x\n", hr), VERR_INTERNAL_ERROR);
@@ -4942,12 +4962,12 @@ int vmsvga3dSetMaterial(PVGASTATE pThis, uint32_t cid, SVGA3dFace face, SVGA3dMa
     Log(("vmsvga3dSetMaterial %x face %d\n", cid, face));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetMaterial invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
 
     AssertReturn(face < SVGA3D_FACE_MAX, VERR_INVALID_PARAMETER);
 
@@ -4997,12 +5017,12 @@ int vmsvga3dSetLightData(PVGASTATE pThis, uint32_t cid, uint32_t index, SVGA3dLi
     Log(("vmsvga3dSetLightData %x index=%d\n", cid, index));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetLightData invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
 
     switch (pData->type)
     {
@@ -5075,12 +5095,12 @@ int vmsvga3dSetLightEnabled(PVGASTATE pThis, uint32_t cid, uint32_t index, uint3
     Log(("vmsvga3dSetLightEnabled %x %d -> %d\n", cid, index, enabled));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetLightEnabled invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
 
     /* Store for vm state save/restore */
     if (index < SVGA3D_MAX_LIGHTS)
@@ -5105,13 +5125,13 @@ int vmsvga3dSetViewPort(PVGASTATE pThis, uint32_t cid, SVGA3dRect *pRect)
     Log(("vmsvga3dSetViewPort %x (%d,%d)(%d,%d)\n", cid, pRect->x, pRect->y, pRect->w, pRect->h));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetViewPort invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
     /* Save for vm state save/restore. */
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
     pContext->state.RectViewPort = *pRect;
     pContext->state.u32UpdateFlags |= VMSVGA3D_UPDATE_VIEWPORT;
 
@@ -5141,12 +5161,12 @@ int vmsvga3dSetClipPlane(PVGASTATE pThis, uint32_t cid,  uint32_t index, float p
     AssertReturn(index < SVGA3D_CLIPPLANE_MAX, VERR_INVALID_PARAMETER);
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetClipPlane invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
 
     /* Store for vm state save/restore. */
     pContext->state.aClipPlane[index].fValid = true;
@@ -5169,12 +5189,12 @@ int vmsvga3dCommandClear(PVGASTATE pThis, uint32_t cid, SVGA3dClearFlag clearFla
     Log(("vmsvga3dCommandClear %x clearFlag=%x color=%x depth=%d stencil=%x cRects=%d\n", cid, clearFlag, color, (uint32_t)(depth * 100.0), stencil, cRects));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dCommandClear invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
 
     if (clearFlag & SVGA3D_CLEAR_COLOR)
         clearFlagD3D |= D3DCLEAR_TARGET;
@@ -5308,6 +5328,8 @@ int vmsvga3dDrawPrimitivesProcessVertexDecls(PVMSVGA3DSTATE pState, PVMSVGA3DCON
                                                        NULL);
             AssertMsgReturn(hr == D3D_OK, ("vmsvga3dDrawPrimitives: CreateVertexBuffer failed with %x\n", hr), VERR_INTERNAL_ERROR);
 
+            pVertexSurface->idAssociatedContext = pContext->id;
+
             if (pVertexSurface->fDirty)
             {
                 void *pData;
@@ -5379,13 +5401,13 @@ int vmsvga3dDrawPrimitives(PVGASTATE pThis, uint32_t cid, uint32_t numVertexDecl
     Assert(!cVertexDivisor);
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dDrawPrimitives invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
 
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
 
     /* Begin a scene before rendering anything. */
     hr = pContext->pDevice->BeginScene();
@@ -5481,7 +5503,7 @@ int vmsvga3dDrawPrimitives(PVGASTATE pThis, uint32_t cid, uint32_t numVertexDecl
             AssertMsg(pRange[iPrimitive].indexWidth == sizeof(uint32_t) || pRange[iPrimitive].indexWidth == sizeof(uint16_t), ("Unsupported primitive width %d\n", pRange[iPrimitive].indexWidth));
 
             if (    sidIndex >= SVGA3D_MAX_SURFACE_IDS
-                ||  sidIndex >= pState->cSurfaces 
+                ||  sidIndex >= pState->cSurfaces
                 ||  pState->paSurface[sidIndex].id != sidIndex)
             {
                 Assert(sidIndex < SVGA3D_MAX_SURFACE_IDS);
@@ -5567,7 +5589,7 @@ int vmsvga3dDrawPrimitives(PVGASTATE pThis, uint32_t cid, uint32_t numVertexDecl
 
             UINT numVertices;
 
-            if (pVertexDecl[0].rangeHint.last) 
+            if (pVertexDecl[0].rangeHint.last)
                 numVertices = pVertexDecl[0].rangeHint.last - pVertexDecl[0].rangeHint.first + 1;
             else
                 numVertices = pVertexSurface->pMipmapLevels[0].cbSurface / strideVertex - pVertexDecl[0].array.offset / strideVertex - pVertexDecl[0].rangeHint.first - pRange[iPrimitive].indexBias;
@@ -5667,12 +5689,12 @@ int vmsvga3dSetScissorRect(PVGASTATE pThis, uint32_t cid, SVGA3dRect *pRect)
     Log(("vmsvga3dSetScissorRect %x (%d,%d)(%d,%d)\n", cid, pRect->x, pRect->y, pRect->w, pRect->h));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dSetScissorRect invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
 
     /* Store for vm state save/restore. */
     pContext->state.u32UpdateFlags |= VMSVGA3D_UPDATE_SCISSORRECT;
@@ -5702,20 +5724,21 @@ int vmsvga3dShaderDefine(PVGASTATE pThis, uint32_t cid, uint32_t shid, SVGA3dSha
     Log3(("shader code:\n%.*Rhxd\n", cbData, pShaderData));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dShaderDefine invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
 
     AssertReturn(shid < SVGA3D_MAX_SHADER_IDS, VERR_INVALID_PARAMETER);
     if (type == SVGA3D_SHADERTYPE_VS)
     {
         if (shid >= pContext->cVertexShaders)
         {
-            pContext->paVertexShader = (PVMSVGA3DSHADER)RTMemRealloc(pContext->paVertexShader, sizeof(VMSVGA3DSHADER) * (shid + 1));
-            AssertReturn(pContext->paVertexShader, VERR_NO_MEMORY);
+            void *pvNew = RTMemRealloc(pContext->paVertexShader, sizeof(VMSVGA3DSHADER) * (shid + 1));
+            AssertReturn(pvNew, VERR_NO_MEMORY);
+            pContext->paVertexShader = (PVMSVGA3DSHADER)pvNew;
             memset(&pContext->paVertexShader[pContext->cVertexShaders], 0, sizeof(VMSVGA3DSHADER) * (shid + 1 - pContext->cVertexShaders));
             for (uint32_t i = pContext->cVertexShaders; i < shid + 1; i++)
                 pContext->paVertexShader[i].id = SVGA3D_INVALID_ID;
@@ -5732,8 +5755,9 @@ int vmsvga3dShaderDefine(PVGASTATE pThis, uint32_t cid, uint32_t shid, SVGA3dSha
         Assert(type == SVGA3D_SHADERTYPE_PS);
         if (shid >= pContext->cPixelShaders)
         {
-            pContext->paPixelShader = (PVMSVGA3DSHADER)RTMemRealloc(pContext->paPixelShader, sizeof(VMSVGA3DSHADER) * (shid + 1));
-            AssertReturn(pContext->paPixelShader, VERR_NO_MEMORY);
+            void *pvNew = RTMemRealloc(pContext->paPixelShader, sizeof(VMSVGA3DSHADER) * (shid + 1));
+            AssertReturn(pvNew, VERR_NO_MEMORY);
+            pContext->paPixelShader = (PVMSVGA3DSHADER)pvNew;
             memset(&pContext->paPixelShader[pContext->cPixelShaders], 0, sizeof(VMSVGA3DSHADER) * (shid + 1 - pContext->cPixelShaders));
             for (uint32_t i = pContext->cPixelShaders; i < shid + 1; i++)
                 pContext->paPixelShader[i].id = SVGA3D_INVALID_ID;
@@ -5755,6 +5779,16 @@ int vmsvga3dShaderDefine(PVGASTATE pThis, uint32_t cid, uint32_t shid, SVGA3dSha
     AssertReturn(pShader->pShaderProgram, VERR_NO_MEMORY);
     memcpy(pShader->pShaderProgram, pShaderData, cbData);
 
+#ifdef DUMP_SHADER_DISASSEMBLY
+    LPD3DXBUFFER pDisassembly;
+    hr = D3DXDisassembleShader((const DWORD *)pShaderData, FALSE, NULL, &pDisassembly);
+    if (hr == D3D_OK)
+    {
+        Log(("Shader disassembly:\n%s\n", pDisassembly->GetBufferPointer()));
+        pDisassembly->Release();
+    }
+#endif
+
     switch (type)
     {
     case SVGA3D_SHADERTYPE_VS:
@@ -5768,16 +5802,6 @@ int vmsvga3dShaderDefine(PVGASTATE pThis, uint32_t cid, uint32_t shid, SVGA3dSha
     default:
         AssertFailedReturn(VERR_INVALID_PARAMETER);
     }
-#ifdef DUMP_SHADER_DISASSEMBLY
-    LPD3DXBUFFER pDisassembly;
-
-    hr = D3DXDisassembleShader((const DWORD *)pShaderData, FALSE, NULL, &pDisassembly);
-    if (hr == D3D_OK)
-    {
-        Log(("Shader disassembly:\n%s\n", pDisassembly->GetBufferPointer()));
-        pDisassembly->Release();
-    }
-#endif
     if (hr != D3D_OK)
     {
         RTMemFree(pShader->pShaderProgram);
@@ -5799,12 +5823,12 @@ int vmsvga3dShaderDestroy(PVGASTATE pThis, uint32_t cid, uint32_t shid, SVGA3dSh
     Log(("vmsvga3dShaderDestroy %x shid=%x type=%s\n", cid, shid, (type == SVGA3D_SHADERTYPE_VS) ? "VERTEX" : "PIXEL"));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dShaderDestroy invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
 
     if (type == SVGA3D_SHADERTYPE_VS)
     {
@@ -5850,12 +5874,12 @@ int vmsvga3dShaderSet(PVGASTATE pThis, uint32_t cid, SVGA3dShaderType type, uint
     Log(("vmsvga3dShaderSet %x type=%s shid=%d\n", cid, (type == SVGA3D_SHADERTYPE_VS) ? "VERTEX" : "PIXEL", shid));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dShaderSet invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
 
     if (type == SVGA3D_SHADERTYPE_VS)
     {
@@ -5922,12 +5946,12 @@ int vmsvga3dShaderSetConst(PVGASTATE pThis, uint32_t cid, uint32_t reg, SVGA3dSh
     Log(("vmsvga3dShaderSetConst %x reg=%x type=%s ctype=%x\n", cid, reg, (type == SVGA3D_SHADERTYPE_VS) ? "VERTEX" : "PIXEL", ctype));
 
     if (    cid >= pState->cContexts
-        ||  pState->paContext[cid].id != cid)
+        ||  pState->papContexts[cid]->id != cid)
     {
         Log(("vmsvga3dShaderSetConst invalid context id!\n"));
         return VERR_INVALID_PARAMETER;
     }
-    pContext = &pState->paContext[cid];
+    pContext = pState->papContexts[cid];
 
     for (uint32_t i = 0; i < cRegisters; i++)
     {
@@ -6294,6 +6318,7 @@ static void vmsvgaDumpD3DCaps(D3DCAPS9 *pCaps)
     if (pCaps->TextureOpCaps & D3DTEXOPCAPS_LERP)
         LogRel((" - D3DTEXOPCAPS_LERP\n"));
 
+
     LogRel(("\n"));
     LogRel(("PixelShaderVersion:  %#x (%u.%u)\n", pCaps->PixelShaderVersion,
             D3DSHADER_VERSION_MAJOR(pCaps->PixelShaderVersion), D3DSHADER_VERSION_MINOR(pCaps->PixelShaderVersion)));
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h b/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h
index 2ea3767..72a4978 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h
@@ -37,7 +37,7 @@ int vmsvga3dSendThreadMessage(RTTHREAD pWindowThread, RTSEMEVENT WndRequestSem,
 #endif
 
 /** Arbitrary limit */
-#define SVGA3D_MAX_SHADER_IDS                   0x100
+#define SVGA3D_MAX_SHADER_IDS                   0x800
 /** D3D allows up to 8 texture stages. */
 #define SVGA3D_MAX_TEXTURE_STAGE                8
 /** Arbitrary upper limit; seen 8 so far. */
@@ -62,7 +62,7 @@ int vmsvga3dSurfaceStretchBlt(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3d
 int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceImageId host, SVGA3dTransferType transfer, uint32_t cCopyBoxes, SVGA3dCopyBox *pBoxes);
 int vmsvga3dSurfaceBlitToScreen(PVGASTATE pThis, uint32_t dest, SVGASignedRect destRect, SVGA3dSurfaceImageId src, SVGASignedRect srcRect, uint32_t cRects, SVGASignedRect *pRect);
 
-int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fOtherProfile);
+int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid);
 int vmsvga3dContextDestroy(PVGASTATE pThis, uint32_t cid);
 
 int vmsvga3dChangeMode(PVGASTATE pThis);
diff --git a/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp b/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
index 71b0385..b9a1f37 100644
--- a/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
@@ -2717,7 +2717,7 @@ int VBVAInit (PVGASTATE pVGAState)
              VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext (pVGAState->pHGSMI);
              pCtx->cViews = pVGAState->cMonitors;
              pCtx->fPaused = true;
-             memset(pCtx->aModeHints, ~0, sizeof(*pCtx->aModeHints));
+             memset(pCtx->aModeHints, ~0, sizeof(pCtx->aModeHints));
              pVGAState->fHostCursorCapabilities = 0;
          }
      }
diff --git a/src/VBox/Devices/Graphics/shaderlib/glsl_shader.c b/src/VBox/Devices/Graphics/shaderlib/glsl_shader.c
index 9438429..05e3634 100644
--- a/src/VBox/Devices/Graphics/shaderlib/glsl_shader.c
+++ b/src/VBox/Devices/Graphics/shaderlib/glsl_shader.c
@@ -1317,6 +1317,9 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
     /* Temporary variables for matrix operations */
     shader_addline(buffer, "vec4 tmp0;\n");
     shader_addline(buffer, "vec4 tmp1;\n");
+#ifdef VBOX_WITH_VMSVGA
+    shader_addline(buffer, "bool p0[4];\n");
+#endif
 
     /* Local constants use a different name so they can be loaded once at shader link time
      * They can't be hardcoded into the shader text via LC = {x, y, z, w}; because the
@@ -1629,6 +1632,12 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
             }
             break;
 
+#ifdef VBOX_WITH_VMSVGA
+        case WINED3DSPR_PREDICATE:
+            sprintf(register_name, "p0");
+            break;
+#endif
+
         default:
             FIXME("Unhandled register name Type(%d)\n", reg->type);
             sprintf(register_name, "unrecognized_register");
@@ -1658,6 +1667,22 @@ static DWORD shader_glsl_get_write_mask(const struct wined3d_shader_dst_param *p
     }
     else
     {
+#ifdef VBOX_WITH_VMSVGA
+        if (param->reg.type == WINED3DSPR_PREDICATE)
+        {
+            *write_mask++ = '[';
+            if (mask & WINED3DSP_WRITEMASK_0) *write_mask++ = '0';
+            else
+            if (mask & WINED3DSP_WRITEMASK_1) *write_mask++ = '1';
+            else
+            if (mask & WINED3DSP_WRITEMASK_2) *write_mask++ = '2';
+            else
+            if (mask & WINED3DSP_WRITEMASK_3) *write_mask++ = '3';
+            *write_mask++ = ']';
+            *write_mask = '\0';
+        }
+        else
+#endif
         shader_glsl_write_mask_to_str(mask, write_mask);
     }
 
@@ -2160,14 +2185,53 @@ static void shader_glsl_arith(const struct wined3d_shader_instruction *ins)
     shader_addline(buffer, "%s %c %s);\n", src0_param.param_str, op, src1_param.param_str);
 }
 
+#ifdef VBOX_WITH_VMSVGA
+static void shader_glsl_mov_impl(const struct wined3d_shader_instruction *ins, int p0_idx);
+
 /* Process the WINED3DSIO_MOV opcode using GLSL (dst = src) */
 static void shader_glsl_mov(const struct wined3d_shader_instruction *ins)
 {
+    if (ins->predicate)
+    {
+        int i;
+        DWORD dst_mask = ins->dst[0].write_mask;
+        struct wined3d_shader_dst_param *dst = (struct wined3d_shader_dst_param *)&ins->dst[0];
+
+        for (i = 0; i < 4; i++)
+        {
+            if (dst_mask & RT_BIT(i))
+            {
+                dst->write_mask = RT_BIT(i);
+
+                shader_glsl_mov_impl(ins, i);
+            }
+        }
+        dst->write_mask = dst_mask;
+    }
+    else
+        shader_glsl_mov_impl(ins, 0);
+}
+
+/* Process the WINED3DSIO_MOV opcode using GLSL (dst = src) */
+static void shader_glsl_mov_impl(const struct wined3d_shader_instruction *ins, int p0_idx)
+
+#else
+/* Process the WINED3DSIO_MOV opcode using GLSL (dst = src) */
+static void shader_glsl_mov(const struct wined3d_shader_instruction *ins)
+#endif
+{
     const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     glsl_src_param_t src0_param;
     DWORD write_mask;
 
+#ifdef VBOX_WITH_VMSVGA
+    if (ins->predicate)
+    {
+        shader_addline(buffer, "if (p0[%d]) {\n", p0_idx);
+    }
+#endif
+
     write_mask = shader_glsl_append_dst(buffer, ins);
     shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
 
@@ -2211,6 +2275,12 @@ static void shader_glsl_mov(const struct wined3d_shader_instruction *ins)
     {
         shader_addline(buffer, "%s);\n", src0_param.param_str);
     }
+#ifdef VBOX_WITH_VMSVGA
+    if (ins->predicate)
+    {
+        shader_addline(buffer, "}\n");
+    }
+#endif
 }
 
 /* Process the dot product operators DP3 and DP4 in GLSL (dst = dot(src0, src1)) */
@@ -2468,6 +2538,37 @@ static void shader_glsl_rsq(const struct wined3d_shader_instruction *ins)
     }
 }
 
+#ifdef VBOX_WITH_VMSVGA
+static void shader_glsl_setp(const struct wined3d_shader_instruction *ins)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    glsl_src_param_t src_param1, src_param2;
+    DWORD write_mask;
+
+    int i;
+    DWORD dst_mask = ins->dst[0].write_mask;
+    struct wined3d_shader_dst_param dst = ins->dst[0];
+
+    /* Cycle through all source0 channels */
+    for (i=0; i<4; i++) {
+        if (dst_mask & RT_BIT(i))
+        {
+            write_mask = WINED3DSP_WRITEMASK_0 << i;
+            dst.write_mask = dst_mask & write_mask;
+
+            write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &dst);
+            Assert(write_mask);
+
+            shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param1);
+            shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src_param2);
+
+            shader_addline(buffer, "%s %s %s);\n",
+                    src_param1.param_str, shader_get_comp_op(ins->flags), src_param2.param_str);
+        }
+    }
+}
+#endif
+
 /** Process signed comparison opcodes in GLSL. */
 static void shader_glsl_compare(const struct wined3d_shader_instruction *ins)
 {
@@ -5313,7 +5414,11 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_REP           */ shader_glsl_rep,
     /* WINED3DSIH_RET           */ shader_glsl_ret,
     /* WINED3DSIH_RSQ           */ shader_glsl_rsq,
+#ifdef VBOX_WITH_VMSVGA
+    /* WINED3DSIH_SETP          */ shader_glsl_setp,
+#else
     /* WINED3DSIH_SETP          */ NULL,
+#endif
     /* WINED3DSIH_SGE           */ shader_glsl_compare,
     /* WINED3DSIH_SGN           */ shader_glsl_sgn,
     /* WINED3DSIH_SINCOS        */ shader_glsl_sincos,
diff --git a/src/VBox/Devices/Graphics/shaderlib/shader.c b/src/VBox/Devices/Graphics/shaderlib/shader.c
index f197074..c1415e8 100644
--- a/src/VBox/Devices/Graphics/shaderlib/shader.c
+++ b/src/VBox/Devices/Graphics/shaderlib/shader.c
@@ -1162,7 +1162,9 @@ void shader_generate_main(IWineD3DBaseShader *iface, struct wined3d_shader_buffe
         /* Predication token */
         if (ins.predicate)
         {
+#ifndef VBOX_WITH_VMSVGA
             FIXME("Predicates not implemented.\n");
+#endif
             ins.predicate = *ptr++;
         }
 
diff --git a/src/VBox/Devices/Graphics/shaderlib/shader_sm1.c b/src/VBox/Devices/Graphics/shaderlib/shader_sm1.c
index aed014d..b8cb550 100644
--- a/src/VBox/Devices/Graphics/shaderlib/shader_sm1.c
+++ b/src/VBox/Devices/Graphics/shaderlib/shader_sm1.c
@@ -245,8 +245,12 @@ static const struct wined3d_sm1_opcode_info vs_opcode_table[] =
     {WINED3D_SM1_OP_FRC,      1, 2, WINED3DSIH_FRC,          0,                           0                          },
     {WINED3D_SM1_OP_POW,      1, 3, WINED3DSIH_POW,          0,                           0                          },
     {WINED3D_SM1_OP_CRS,      1, 3, WINED3DSIH_CRS,          0,                           0                          },
+#ifdef VBOX_WITH_VMSVGA /* appears incorrect */
+    {WINED3D_SM1_OP_SGN,      1, 4, WINED3DSIH_SGN,          0,                           0                          },
+#else
     {WINED3D_SM1_OP_SGN,      1, 4, WINED3DSIH_SGN,          WINED3D_SHADER_VERSION(2,0), WINED3D_SHADER_VERSION(2,1)},
     {WINED3D_SM1_OP_SGN,      1, 2, WINED3DSIH_SGN,          WINED3D_SHADER_VERSION(3,0), -1                         },
+#endif
     {WINED3D_SM1_OP_NRM,      1, 2, WINED3DSIH_NRM,          0,                           0                          },
     {WINED3D_SM1_OP_SINCOS,   1, 4, WINED3DSIH_SINCOS,       WINED3D_SHADER_VERSION(2,0), WINED3D_SHADER_VERSION(2,1)},
     {WINED3D_SM1_OP_SINCOS,   1, 2, WINED3DSIH_SINCOS,       WINED3D_SHADER_VERSION(3,0), -1                         },
diff --git a/src/VBox/Devices/Graphics/shaderlib/wined3d_private.h b/src/VBox/Devices/Graphics/shaderlib/wined3d_private.h
index ca1bd61..948057c 100644
--- a/src/VBox/Devices/Graphics/shaderlib/wined3d_private.h
+++ b/src/VBox/Devices/Graphics/shaderlib/wined3d_private.h
@@ -3196,8 +3196,14 @@ static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg)
         case WINED3DSPR_DEPTHOUT:   /* oDepth */
         case WINED3DSPR_CONSTBOOL:  /* b# */
         case WINED3DSPR_LOOP:       /* aL */
+#ifndef VBOX_WITH_VMSVGA
         case WINED3DSPR_PREDICATE:  /* p0 */
             return TRUE;
+#else
+            return TRUE;
+        case WINED3DSPR_PREDICATE:  /* p0 */
+            return FALSE;
+#endif
 
         case WINED3DSPR_MISCTYPE:
             switch(reg->idx)
diff --git a/src/VBox/Devices/Graphics/testcase/dump-vmwgfx.c b/src/VBox/Devices/Graphics/testcase/dump-vmwgfx.c
new file mode 100644
index 0000000..cbd04a7
--- /dev/null
+++ b/src/VBox/Devices/Graphics/testcase/dump-vmwgfx.c
@@ -0,0 +1,629 @@
+/* $Id: dump-vmwgfx.c $ */
+/** @file
+ * dump-vmwgfx.c - Dumps parameters and capabilities of vmwgfx.ko.
+ */
+
+/*
+ * Copyright (C) 2013-2015 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.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include <assert.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+
+/*******************************************************************************
+*   Defined Constants And Macros                                               *
+*******************************************************************************/
+#define DRM_IOCTL_BASE              'd'
+#define DRM_COMMAND_BASE            0x40
+#define DRM_VMW_GET_PARAM           0
+#define DRM_VMW_GET_3D_CAP          13
+#define DRM_IOCTL_VMW_GET_PARAM     _IOWR(DRM_IOCTL_BASE, DRM_COMMAND_BASE + DRM_VMW_GET_PARAM, struct drm_vmw_getparam_arg)
+#define DRM_IOCTL_VMW_GET_3D_CAP    _IOW(DRM_IOCTL_BASE, DRM_COMMAND_BASE + DRM_VMW_GET_3D_CAP, struct drm_vmw_get_3d_cap_arg)
+
+#define SVGA3DCAPS_RECORD_DEVCAPS   0x100
+
+#define DRM_VMW_PARAM_NUM_STREAMS       0
+#define DRM_VMW_PARAM_FREE_STREAMS      1
+#define DRM_VMW_PARAM_3D                2
+#define DRM_VMW_PARAM_HW_CAPS           3
+#define DRM_VMW_PARAM_FIFO_CAPS         4
+#define DRM_VMW_PARAM_MAX_FB_SIZE       5
+#define DRM_VMW_PARAM_FIFO_HW_VERSION   6
+#define DRM_VMW_PARAM_MAX_SURF_MEMORY   7
+#define DRM_VMW_PARAM_3D_CAP_SIZE       8
+#define DRM_VMW_PARAM_MAX_MOB_MEMORY    9
+#define DRM_VMW_PARAM_MAX_MOB_SIZE     10
+
+
+/*******************************************************************************
+*   Structures and Typedefs                                                    *
+*******************************************************************************/
+struct drm_vmw_get_3d_cap_arg
+{
+    uint64_t buffer;
+    uint32_t max_size;
+    uint32_t pad64;
+};
+
+
+struct SVGA3dCapsRecordHeader
+{
+    uint32_t length;
+    uint32_t type;
+};
+
+struct SVGA3dCapsRecord
+{
+    /* Skipped if DRM_VMW_PARAM_MAX_MOB_MEMORY is read. */
+    struct SVGA3dCapsRecordHeader header;
+    uint32_t data[1];    
+};
+
+struct drm_vmw_getparam_arg
+{
+    uint64_t value;
+    uint32_t param;
+    uint32_t pad64;
+};
+
+
+typedef struct FLAGDESC
+{
+    uint32_t fMask;
+    const char *pszName;
+} FLAGDESC;
+typedef FLAGDESC const *PCFLAGDESC;
+
+
+/*******************************************************************************
+*   Global Variables                                                           *
+*******************************************************************************/
+/** The size of the 3D capabilities. */
+static uint32_t     g_cb3dCaps;
+/** Set if the driver will return the new 3D capability format. */
+static int          g_fNew3dCapFormat = 0;
+/** The SVGA_CAP_XXX mask for the card. */
+static uint64_t     g_fHwCaps = 0;
+
+/** Names for the vmsvga 3d capabilities, prefixed with format type hint char. (Copied from DevSVGA.cpp.) */
+static const char * const g_apszVmSvgaDevCapNames[] =
+{
+    "x3D",                           /* = 0 */
+    "xMAX_LIGHTS",
+    "xMAX_TEXTURES",
+    "xMAX_CLIP_PLANES",
+    "xVERTEX_SHADER_VERSION",
+    "xVERTEX_SHADER",
+    "xFRAGMENT_SHADER_VERSION",
+    "xFRAGMENT_SHADER",
+    "xMAX_RENDER_TARGETS",
+    "xS23E8_TEXTURES",
+    "xS10E5_TEXTURES",
+    "xMAX_FIXED_VERTEXBLEND",
+    "xD16_BUFFER_FORMAT",
+    "xD24S8_BUFFER_FORMAT",
+    "xD24X8_BUFFER_FORMAT",
+    "xQUERY_TYPES",
+    "xTEXTURE_GRADIENT_SAMPLING",
+    "rMAX_POINT_SIZE",
+    "xMAX_SHADER_TEXTURES",
+    "xMAX_TEXTURE_WIDTH",
+    "xMAX_TEXTURE_HEIGHT",
+    "xMAX_VOLUME_EXTENT",
+    "xMAX_TEXTURE_REPEAT",
+    "xMAX_TEXTURE_ASPECT_RATIO",
+    "xMAX_TEXTURE_ANISOTROPY",
+    "xMAX_PRIMITIVE_COUNT",
+    "xMAX_VERTEX_INDEX",
+    "xMAX_VERTEX_SHADER_INSTRUCTIONS",
+    "xMAX_FRAGMENT_SHADER_INSTRUCTIONS",
+    "xMAX_VERTEX_SHADER_TEMPS",
+    "xMAX_FRAGMENT_SHADER_TEMPS",
+    "xTEXTURE_OPS",
+    "xSURFACEFMT_X8R8G8B8",
+    "xSURFACEFMT_A8R8G8B8",
+    "xSURFACEFMT_A2R10G10B10",
+    "xSURFACEFMT_X1R5G5B5",
+    "xSURFACEFMT_A1R5G5B5",
+    "xSURFACEFMT_A4R4G4B4",
+    "xSURFACEFMT_R5G6B5",
+    "xSURFACEFMT_LUMINANCE16",
+    "xSURFACEFMT_LUMINANCE8_ALPHA8",
+    "xSURFACEFMT_ALPHA8",
+    "xSURFACEFMT_LUMINANCE8",
+    "xSURFACEFMT_Z_D16",
+    "xSURFACEFMT_Z_D24S8",
+    "xSURFACEFMT_Z_D24X8",
+    "xSURFACEFMT_DXT1",
+    "xSURFACEFMT_DXT2",
+    "xSURFACEFMT_DXT3",
+    "xSURFACEFMT_DXT4",
+    "xSURFACEFMT_DXT5",
+    "xSURFACEFMT_BUMPX8L8V8U8",
+    "xSURFACEFMT_A2W10V10U10",
+    "xSURFACEFMT_BUMPU8V8",
+    "xSURFACEFMT_Q8W8V8U8",
+    "xSURFACEFMT_CxV8U8",
+    "xSURFACEFMT_R_S10E5",
+    "xSURFACEFMT_R_S23E8",
+    "xSURFACEFMT_RG_S10E5",
+    "xSURFACEFMT_RG_S23E8",
+    "xSURFACEFMT_ARGB_S10E5",
+    "xSURFACEFMT_ARGB_S23E8",
+    "xMISSING62",
+    "xMAX_VERTEX_SHADER_TEXTURES",
+    "xMAX_SIMULTANEOUS_RENDER_TARGETS",
+    "xSURFACEFMT_V16U16",
+    "xSURFACEFMT_G16R16",
+    "xSURFACEFMT_A16B16G16R16",
+    "xSURFACEFMT_UYVY",
+    "xSURFACEFMT_YUY2",
+    "xMULTISAMPLE_NONMASKABLESAMPLES",
+    "xMULTISAMPLE_MASKABLESAMPLES",
+    "xALPHATOCOVERAGE",
+    "xSUPERSAMPLE",
+    "xAUTOGENMIPMAPS",
+    "xSURFACEFMT_NV12",
+    "xSURFACEFMT_AYUV",
+    "xMAX_CONTEXT_IDS",
+    "xMAX_SURFACE_IDS",
+    "xSURFACEFMT_Z_DF16",
+    "xSURFACEFMT_Z_DF24",
+    "xSURFACEFMT_Z_D24S8_INT",
+    "xSURFACEFMT_BC4_UNORM",
+    "xSURFACEFMT_BC5_UNORM", /* 83 */
+    "xVGPU10",
+    "xVIDEO_DECODE",
+    "xVIDEO_PROCESS",
+    "xLINE_AA",
+    "xLINE_STRIPPLE",
+    "fMAX_LINE_WIDTH",
+    "fMAX_AA_LINE_WIDTH",   /* 90 */
+    "xSURFACEFMT_YV12",
+    "xLOGICOPS",
+    "xSCREENTARGETS",
+    "xTS_COLOR_KEY",
+    "xDX",                  /* 95 */
+};
+
+/** SVGA_CAP flag descriptors. */
+static FLAGDESC const g_aVmSvgaCapFlags[] =
+{
+    { UINT32_C(0x00000001), "unknown-bit-0" },
+    { UINT32_C(0x00000002), "SVGA_CAP_RECT_COPY" },
+    { UINT32_C(0x00000004), "unknown-bit-2" },
+    { UINT32_C(0x00000008), "unknown-bit-3" },
+    { UINT32_C(0x00000010), "unknown-bit-4" },
+    { UINT32_C(0x00000020), "SVGA_CAP_CURSOR" },
+    { UINT32_C(0x00000040), "SVGA_CAP_CURSOR_BYPASS" },
+    { UINT32_C(0x00000080), "SVGA_CAP_CURSOR_BYPASS_2" },
+    { UINT32_C(0x00000100), "SVGA_CAP_8BIT_EMULATION" },
+    { UINT32_C(0x00000200), "SVGA_CAP_ALPHA_CURSOR" },
+    { UINT32_C(0x00000400), "unknown-bit-10" },
+    { UINT32_C(0x00000800), "unknown-bit-11" },
+    { UINT32_C(0x00001000), "unknown-bit-12" },
+    { UINT32_C(0x00002000), "unknown-bit-13" },
+    { UINT32_C(0x00004000), "SVGA_CAP_3D" },
+    { UINT32_C(0x00008000), "SVGA_CAP_EXTENDED_FIFO" },
+    { UINT32_C(0x00010000), "SVGA_CAP_MULTIMON" },
+    { UINT32_C(0x00020000), "SVGA_CAP_PITCHLOCK" },
+    { UINT32_C(0x00040000), "SVGA_CAP_IRQMASK" },
+    { UINT32_C(0x00080000), "SVGA_CAP_DISPLAY_TOPOLOGY" },
+    { UINT32_C(0x00100000), "SVGA_CAP_GMR" },
+    { UINT32_C(0x00200000), "SVGA_CAP_TRACES" },
+    { UINT32_C(0x00400000), "SVGA_CAP_GMR2" },
+    { UINT32_C(0x00800000), "SVGA_CAP_SCREEN_OBJECT_2" },
+    { UINT32_C(0x01000000), "SVGA_CAP_COMMAND_BUFFERS" },
+    { UINT32_C(0x02000000), "SVGA_CAP_DEAD1" },
+    { UINT32_C(0x04000000), "SVGA_CAP_CMD_BUFFERS_2" },
+    { UINT32_C(0x08000000), "SVGA_CAP_GBOBJECTS" },
+    { UINT32_C(0x10000000), "unknown-bit-28" },
+    { UINT32_C(0x20000000), "unknown-bit-29" },
+    { UINT32_C(0x40000000), "unknown-bit-30" },
+    { UINT32_C(0x80000000), "unknown-bit-31" },
+};
+
+/** SVGA_FIFO_CAP flag descriptors. */
+static FLAGDESC const g_aVmSvgaFifoCapFlags[] =
+{
+    { UINT32_C(0x00000001), "SVGA_FIFO_CAP_FENCE" },
+    { UINT32_C(0x00000002), "SVGA_FIFO_CAP_ACCELFRONT" },
+    { UINT32_C(0x00000004), "SVGA_FIFO_CAP_PITCHLOCK" },
+    { UINT32_C(0x00000008), "SVGA_FIFO_CAP_VIDEO" },
+    { UINT32_C(0x00000010), "SVGA_FIFO_CAP_CURSOR_BYPASS_3" },
+    { UINT32_C(0x00000020), "SVGA_FIFO_CAP_ESCAPE" },
+    { UINT32_C(0x00000040), "SVGA_FIFO_CAP_RESERVE" },
+    { UINT32_C(0x00000080), "SVGA_FIFO_CAP_SCREEN_OBJECT" },
+    { UINT32_C(0x00000100), "SVGA_FIFO_CAP_GMR2/SVGA_FIFO_CAP_3D_HWVERSION_REVISED" },
+    { UINT32_C(0x00000200), "SVGA_FIFO_CAP_SCREEN_OBJECT_2" },
+    { UINT32_C(0x00000400), "SVGA_FIFO_CAP_DEAD" },
+    { UINT32_C(0x00000800), "unknown-bit-11" },
+    { UINT32_C(0x00001000), "unknown-bit-12" },
+    { UINT32_C(0x00002000), "unknown-bit-13" },
+    { UINT32_C(0x00004000), "unknown-bit-14" },
+    { UINT32_C(0x00008000), "unknown-bit-15" },
+    { UINT32_C(0x00010000), "unknown-bit-16" },
+    { UINT32_C(0x00020000), "unknown-bit-17" },
+    { UINT32_C(0x00040000), "unknown-bit-18" },
+    { UINT32_C(0x00080000), "unknown-bit-19" },
+    { UINT32_C(0x00100000), "unknown-bit-20" },
+    { UINT32_C(0x00200000), "unknown-bit-21" },
+    { UINT32_C(0x00400000), "unknown-bit-22" },
+    { UINT32_C(0x00800000), "unknown-bit-23" },
+    { UINT32_C(0x01000000), "unknown-bit-24" },
+    { UINT32_C(0x02000000), "unknown-bit-25" },
+    { UINT32_C(0x04000000), "unknown-bit-26" },
+    { UINT32_C(0x08000000), "unknown-bit-27" },
+    { UINT32_C(0x10000000), "unknown-bit-28" },
+    { UINT32_C(0x20000000), "unknown-bit-29" },
+    { UINT32_C(0x40000000), "unknown-bit-30" },
+    { UINT32_C(0x80000000), "unknown-bit-31" },
+};
+
+
+static void DisplayFlags(PCFLAGDESC paFlagDescs, uint32_t fFlags, unsigned cchIndent)
+{
+    uint32_t i;
+    for (i = 0; i < 32; i++)
+    {
+        assert(paFlagDescs[i].fMask == (UINT32_C(1) << i));
+        if (paFlagDescs[i].fMask & fFlags)
+            printf("%*s%s\n", cchIndent, "", paFlagDescs[i].pszName);
+    }
+}
+
+
+static int QueryParam(int fd, uint32_t uParam, const char *pszParam)
+{
+    struct drm_vmw_getparam_arg Arg;
+    int rc;
+
+    Arg.value = 0;
+    Arg.param = uParam;
+    Arg.pad64 = 0;
+    rc = ioctl(fd, DRM_IOCTL_VMW_GET_PARAM, &Arg);
+    if (rc >= 0)
+    {
+        switch (uParam)
+        {
+            case DRM_VMW_PARAM_3D:
+                printf("%30s: %#llx -- enabled: %s\n", pszParam, Arg.value,
+                       Arg.value == 0 ? "no" : Arg.value == 1 ? "yes" : "huh?");
+                break;
+
+            case DRM_VMW_PARAM_FIFO_HW_VERSION:
+                printf("%30s: %#llx -- major=%llu minor=%llu\n", pszParam, Arg.value, Arg.value >> 16, Arg.value & 0xffff);
+                break;
+
+            case DRM_VMW_PARAM_HW_CAPS:
+                printf("%30s: %#llx\n", pszParam, Arg.value);
+                DisplayFlags(g_aVmSvgaCapFlags, (uint32_t)Arg.value, 32);
+                g_fHwCaps = Arg.value;
+                break;
+
+            case DRM_VMW_PARAM_FIFO_CAPS:
+                printf("%30s: %#llx\n", pszParam, Arg.value);
+                DisplayFlags(g_aVmSvgaFifoCapFlags, (uint32_t)Arg.value, 32);
+                break;
+
+            case DRM_VMW_PARAM_3D_CAP_SIZE:
+                printf("%30s: %#llx (%lld) [bytes]\n", pszParam, Arg.value, Arg.value);
+                g_cb3dCaps = (uint32_t)Arg.value;
+                break;
+
+            default:
+                printf("%30s: %#llx (%lld)\n", pszParam, Arg.value, Arg.value);
+                break;
+        }
+    }
+    else
+        printf("%32s: failed: rc=%d errno=%d (%s)\n", pszParam, rc, errno, strerror(errno));    
+    return rc;
+}
+
+
+static int Dump3DParameters(int fd, int rcExit)
+{
+    int rc;
+    printf("\n**** vmwgfx parameters *****\n");
+#define QUERY_PARAM(nm) QueryParam(fd, nm, #nm)
+    rc = QUERY_PARAM(DRM_VMW_PARAM_HW_CAPS);
+    if (rc < 0)
+        rcExit = 1;
+    QUERY_PARAM(DRM_VMW_PARAM_FIFO_CAPS);
+    QUERY_PARAM(DRM_VMW_PARAM_FIFO_HW_VERSION);
+    QUERY_PARAM(DRM_VMW_PARAM_3D);
+    QUERY_PARAM(DRM_VMW_PARAM_NUM_STREAMS);
+    QUERY_PARAM(DRM_VMW_PARAM_FREE_STREAMS);
+    QUERY_PARAM(DRM_VMW_PARAM_MAX_FB_SIZE);
+    QUERY_PARAM(DRM_VMW_PARAM_MAX_SURF_MEMORY);
+    QUERY_PARAM(DRM_VMW_PARAM_3D_CAP_SIZE);
+    rc = QUERY_PARAM(DRM_VMW_PARAM_MAX_MOB_MEMORY);
+    if (rc >= 0)
+        g_fNew3dCapFormat = g_fHwCaps & UINT32_C(0x08000000) /*SVGA_CAP_GBOBJECTS */;
+    QUERY_PARAM(DRM_VMW_PARAM_MAX_MOB_SIZE);
+    return rcExit;
+}
+
+
+static void PrintOne3DCapability(uint32_t iCap, uint32_t uValue)
+{
+    union
+    {
+        float       rValue;
+        uint32_t    u32Value;
+    } u;
+    u.u32Value = uValue;
+    if (iCap < sizeof(g_apszVmSvgaDevCapNames) / sizeof(g_apszVmSvgaDevCapNames[0]))
+    {
+        const char *pszName = g_apszVmSvgaDevCapNames[iCap];
+        if (pszName[0] == 'x')
+            printf("    cap[%u]=%#010x {%s}\n", iCap, u.u32Value, pszName + 1);
+        else
+            printf("    cap[%u]=%d.%04u {%s}\n", iCap, (int)u.rValue, (unsigned)(u.rValue * 1000) % 10000, pszName + 1);
+    }
+    else
+        printf("    cap[%u]=%#010x\n", iCap, u.u32Value);
+}
+
+
+static void DumpOld3dCapabilityRecords(struct SVGA3dCapsRecord *pCur)
+{
+    for (;;)
+    {
+        printf("    SVGA3dCapsRecordHeader: length=%#x (%d) type=%d\n",
+               pCur->header.length, pCur->header.length, pCur->header.type);
+        if (pCur->header.length == 0)
+            break;
+
+        uint32_t i;
+        for (i = 0; i < pCur->header.length - 2; i += 2)
+            PrintOne3DCapability(pCur->data[i], pCur->data[i + 1]);
+        pCur = (struct SVGA3dCapsRecord *)((uint32_t *)pCur + pCur->header.length);
+    }
+}
+
+
+static int Dump3DCapabilities(int fd, int rcExit)
+{
+    struct SVGA3dCapsRecord        *pBuf;
+    struct drm_vmw_get_3d_cap_arg   Caps3D;
+    int rc;
+
+
+    printf("\n**** 3D capabilities *****\n");
+    Caps3D.pad64    = 0;
+    Caps3D.max_size = 1024 * sizeof(uint32_t);
+    pBuf = (struct SVGA3dCapsRecord *)calloc(Caps3D.max_size, 1);
+    Caps3D.buffer   = (uintptr_t)pBuf;
+
+    errno = 0;
+    rc = ioctl(fd, DRM_IOCTL_VMW_GET_3D_CAP, &Caps3D);
+    if (rc >= 0)
+    {
+        printf("DRM_IOCTL_VMW_GET_3D_CAP: rc=%d\n", rc);
+        if (!g_fNew3dCapFormat)
+            DumpOld3dCapabilityRecords(pBuf);
+        else
+        {
+            uint32_t const *pau32Data = (uint32_t const *)pBuf;
+            uint32_t cCaps = g_cb3dCaps / sizeof(uint32_t);
+            uint32_t iCap;
+            for (iCap = 0; iCap < cCaps; iCap++)
+                PrintOne3DCapability(iCap, pau32Data[iCap]);
+        }
+    }
+    else
+    {
+        fprintf(stderr, "DRM_IOCTL_VMW_GET_3D_CAP failed: %d - %s\n", errno, strerror(errno));
+        rcExit = 1;
+    }
+
+    free(pBuf);
+    return rcExit;
+}
+
+
+static int FindAndMapFifo(uint32_t const **ppau32Fifo, uint32_t *pcbFifo, int rcExit)
+{
+    const char g_szDir[] = "/sys/bus/pci/devices";
+    DIR *pDir = opendir(g_szDir);
+    if (pDir)
+    {
+        struct dirent  *pEntry;
+        char            szPath[4096];
+        size_t          offPath = sizeof(g_szDir);
+        memcpy(szPath, g_szDir, sizeof(g_szDir));
+        szPath[offPath - 1] = '/';
+
+        while ((pEntry = readdir(pDir)) != NULL)
+        {
+            struct stat st;
+            size_t cchName = strlen(pEntry->d_name);
+            memcpy(&szPath[offPath], pEntry->d_name, cchName);
+            strcpy(&szPath[offPath + cchName], "/boot_vga");
+            if (stat(szPath, &st) >= 0)
+            {
+                /* Found something that looks like the VGA device.  Try map resource2. */
+                strcpy(&szPath[offPath + cchName], "/resource2");
+                if (stat(szPath, &st) >= 0)
+                {
+                    int fdFifo = open(szPath, O_RDONLY);
+                    if (fdFifo >= 0)
+                    {
+                        *pcbFifo   = (uint32_t)st.st_size;
+                        *ppau32Fifo = (uint32_t *)mmap(NULL, *pcbFifo, PROT_READ, MAP_SHARED | MAP_FILE, fdFifo, 0);
+                        if (*ppau32Fifo != MAP_FAILED)
+                        {
+                            printf("info: Mapped %s at %p LB %#x\n", szPath, *ppau32Fifo, *pcbFifo);
+                            close(fdFifo);
+                            closedir(pDir);
+                            return rcExit;
+                        }
+
+                        fprintf(stderr, "error: failed to mmap '%s': %d (%s)\n", szPath, errno, strerror(errno));
+                        close(fdFifo);
+                    }
+                    else
+                        fprintf(stderr, "error: failed to open '%s': %d (%s)\n", g_szDir, errno, strerror(errno));
+                }
+                else
+                    fprintf(stderr, "error: boot_vga devices doesn't have '%s'. (%d [%s])\n", szPath, errno, strerror(errno));
+            }
+        } /* for each directory entry */
+
+        closedir(pDir);
+    }
+    else
+        fprintf(stderr, "error: failed to open '%s': %d (%s)\n", g_szDir, errno, strerror(errno));
+    return 1;
+}
+
+
+static int DumpFifoStuff(uint32_t const *pau32Fifo, uint32_t cbFifo, int rcExit)
+{
+    uint32_t cMax = cbFifo / sizeof(uint32_t);
+    uint32_t i, iMin, iMax;
+
+    printf("\n***** FIFO - %u bytes (%#x) *****\n", cbFifo, cbFifo);
+    if (cMax >= 4)
+    {
+        iMin = pau32Fifo[0] / sizeof(uint32_t);
+        printf("                 FIFO_MIN: %#09x --     iMin=%#08x\n", pau32Fifo[0], iMin);
+        iMax = pau32Fifo[1] / sizeof(uint32_t);
+        printf("                 FIFO_MAX: %#09x --     iMax=%#08x\n", pau32Fifo[1], iMax);
+        printf("            FIFO_NEXT_CMD: %#09x -- iNextCmd=%#08x\n", pau32Fifo[2], (uint32_t)(pau32Fifo[2] / sizeof(uint32_t)));
+        printf("                FIFO_STOP: %#09x --    iStop=%#08x\n", pau32Fifo[3], (uint32_t)(pau32Fifo[3] / sizeof(uint32_t)));
+    }
+    else
+    {
+        fprintf(stderr, "error: cbFifo=%#x is too small\n", cbFifo);
+        return 1;
+    }
+    if (iMin > 4)
+    {
+        printf("        FIFO_CAPABILITIES: %#x (%d)\n", pau32Fifo[4], pau32Fifo[4]);
+        DisplayFlags(g_aVmSvgaFifoCapFlags, pau32Fifo[4], 28);
+    }
+    if (iMin > 5)
+        printf("               FIFO_FLAGS: %#x (%d)\n", pau32Fifo[5], pau32Fifo[5]);
+    if (iMin > 6)
+        printf("               FIFO_FENCE: %#x (%d)\n", pau32Fifo[6], pau32Fifo[6]);
+    if (iMin > 7)
+        printf("          FIFO_3D_VERSION: %#x -- %u.%u\n", pau32Fifo[7], pau32Fifo[7] >> 16, pau32Fifo[7] & 0xffff);
+    if (iMin > 8)
+        printf("          FIFO_PITCH_LOCK: %#x (%d)\n", pau32Fifo[8], pau32Fifo[8]);
+    if (iMin > 9)
+        printf("           FIFO_CURSOR_ON: %#x (%d)\n", pau32Fifo[9], pau32Fifo[9]);
+    if (iMin > 10)
+        printf("            FIFO_CURSOR_X: %#x (%d)\n", pau32Fifo[10], pau32Fifo[10]);
+    if (iMin > 11)
+        printf("            FIFO_CURSOR_Y: %#x (%d)\n", pau32Fifo[11], pau32Fifo[11]);
+    if (iMin > 12)
+        printf("        FIFO_CURSOR_COUNT: %#x (%d)\n", pau32Fifo[12], pau32Fifo[12]);
+    if (iMin > 13)
+        printf(" FIFO_CURSOR_LAST_UPDATED: %#x (%d)\n", pau32Fifo[13], pau32Fifo[13]);
+    if (iMin > 14)
+        printf("            FIFO_RESERVED: %#x (%d)\n", pau32Fifo[14], pau32Fifo[14]);
+    if (iMin > 15)
+        printf("    FIFO_CURSOR_SCREEN_ID: %#x (%d)\n", pau32Fifo[15], pau32Fifo[15]);
+    if (iMin > 16)
+        printf("                FIFO_DEAD: %#x (%d)\n", pau32Fifo[16], pau32Fifo[16]);
+    if (iMin > 17)
+        printf("FIFO_3D_HWVERSION_REVISED: %#x -- %u.%u\n", pau32Fifo[17], pau32Fifo[17] >> 16, pau32Fifo[7] & 0xffff);
+
+    for (i = 18; i < 32 && i < iMin; i++)
+        if (pau32Fifo[i] != 0)
+            printf("FIFO_UNKNOWN_%u: %#x (%d)\n", i, pau32Fifo[i], pau32Fifo[i]);
+
+    if (iMin >= 32+64)
+    {
+        if (pau32Fifo[32])
+        {
+            printf("            FIFO_3D_CAPS:\n");
+            DumpOld3dCapabilityRecords((struct SVGA3dCapsRecord *)&pau32Fifo[32]);
+        }
+        else
+            printf("warning: 3D capabilities not present?\n");
+    }
+
+
+    if (iMin > 288)
+        printf("  FIFO_GUEST_3D_HWVERSION: %#x -- %u.%u\n", pau32Fifo[288], pau32Fifo[288] >> 16, pau32Fifo[288] & 0xffff);
+    if (iMin > 289)
+        printf("          FIFO_FENCE_GOAL: %#x (%d)\n", pau32Fifo[289], pau32Fifo[289]);
+    if (iMin > 290)
+        printf("                FIFO_BUSY: %#x (%d)\n", pau32Fifo[290], pau32Fifo[290]);
+
+    for (i = 291; i < iMin; i++)
+        if (pau32Fifo[i] != 0)
+            printf("FIFO_UNKNOWN_%u: %#x (%d)\n", i, pau32Fifo[i], pau32Fifo[i]);
+
+    return rcExit;
+}
+
+
+
+
+
+int main(int argc, char **argv)
+{
+    int rcExit = 0;
+    const char *pszDev = "/dev/dri/card0";
+    if (argc == 2)
+        pszDev = argv[1];
+    
+    int fd = open(pszDev, O_RDWR);
+    if (fd != -1)
+    {
+        uint32_t const *pau32Fifo = NULL;
+        uint32_t        cbFifo = 0;
+
+        /*
+         * Parameters.
+         */
+        rcExit = Dump3DParameters(fd, rcExit);
+    
+        /*
+         * 3D capabilities.
+         */
+        rcExit = Dump3DCapabilities(fd, rcExit);
+
+        /*
+         * Map and dump the FIFO registers.
+         */
+        rcExit = FindAndMapFifo(&pau32Fifo, &cbFifo, rcExit);
+        if (pau32Fifo && cbFifo)
+            rcExit = DumpFifoStuff(pau32Fifo, cbFifo, rcExit);
+    }
+    else
+    {
+        fprintf(stderr, "error opening '%s': %d\n", pszDev, errno);
+        rcExit = 1;
+    }
+    
+    return rcExit;
+}
diff --git a/src/VBox/Devices/Makefile.kmk b/src/VBox/Devices/Makefile.kmk
index 5c714e5..07b9a8d 100644
--- a/src/VBox/Devices/Makefile.kmk
+++ b/src/VBox/Devices/Makefile.kmk
@@ -1388,9 +1388,6 @@ if defined(VBOX_WITH_VMSVGA3D) && !defined(VBOX_ONLY_EXTPACKS)
  else
  VBoxSVGA3DObjC_SOURCES.darwin += \
  	../HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m \
- 	../GuestHost/OpenGL/util/vreg.cpp \
- 	../GuestHost/OpenGL/util/blitter.cpp \
- 	../GuestHost/OpenGL/util/compositor.cpp \
  	../HostServices/SharedOpenGL/OpenGLTest/OpenGLTestDarwin.cpp
  endif
 
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm
index 9cdb3cb..d8df844 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm
@@ -965,7 +965,7 @@ section CONST progbits vstart=0xb0 align=1 ; size=0xcf8 class=DATA group=DGROUP
 
 section CONST2 progbits vstart=0xda8 align=1 ; size=0x3fa class=DATA group=DGROUP
 _bios_cvs_version_string:                    ; 0xf0da8 LB 0x12
-    db  'VirtualBox 4.3.24', 000h
+    db  'VirtualBox 4.3.26', 000h
 _bios_prefix_string:                         ; 0xf0dba LB 0x8
     db  'BIOS: ', 000h, 000h
 _isotag:                                     ; 0xf0dc2 LB 0x6
@@ -16070,4 +16070,4 @@ dummy_iret:                                  ; 0xfff53 LB 0x9d
     db  'XM'
 cpu_reset:                                   ; 0xffff0 LB 0x10
     jmp far 0f000h:0e05bh                     ; ea 5b e0 00 f0
-    db  030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 0ffh
+    db  030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 0fdh
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum
index 50866d4..a4ffaa7 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum
@@ -1 +1 @@
-712c9714414476d4d2d3fe4aa37c72c1 *VBoxPcBios.rom
+126e19c1691b3429bfb98ece8fe2b511 *VBoxPcBios.rom
diff --git a/src/VBox/Devices/PC/ipxe/iPxeBiosBin.rom b/src/VBox/Devices/PC/ipxe/iPxeBiosBin.rom
index 1731e2e..ec0873e 100644
Binary files a/src/VBox/Devices/PC/ipxe/iPxeBiosBin.rom and b/src/VBox/Devices/PC/ipxe/iPxeBiosBin.rom differ
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp b/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
index f406cde..c38c9f1 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
@@ -4844,7 +4844,8 @@ bool VBoxGlobal::switchToMachine(CMachine &machine)
 bool VBoxGlobal::launchMachine(CMachine &machine, bool fHeadless /* = false */)
 {
     /* Switch to machine window(s) if possible: */
-    if (machine.CanShowConsoleWindow())
+    if (   machine.GetSessionState() == KSessionState_Locked /* precondition for CanShowConsoleWindow() */
+        && machine.CanShowConsoleWindow())
         return VBoxGlobal::switchToMachine(machine);
 
     /* Make sure machine-state is one of required: */
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp b/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp
index 40a9b3c..9bb7327 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp
@@ -202,29 +202,33 @@ public:
 
         /* Age: [date time|%1d ago|%1h ago|%1min ago|%1sec ago] */
         SnapshotAgeFormat ageFormat;
-        if (mTimestamp.daysTo (QDateTime::currentDateTime()) > 30)
+        QDateTime now = QDateTime::currentDateTime();
+        QDateTime then = mTimestamp;
+        if (then > now)
+            then = now; /* can happen if the host time is wrong */
+        if (then.daysTo (now) > 30)
         {
-            age = VBoxSnapshotsWgt::tr (" (%1)").arg (mTimestamp.toString (Qt::LocalDate));
+            age = VBoxSnapshotsWgt::tr (" (%1)").arg (then.toString (Qt::LocalDate));
             ageFormat = AgeMax;
         }
-        else if (mTimestamp.secsTo (QDateTime::currentDateTime()) > 60 * 60 * 24)
+        else if (then.secsTo (now) > 60 * 60 * 24)
         {
-            age = VBoxSnapshotsWgt::tr (" (%1 ago)").arg(VBoxGlobal::daysToString(mTimestamp.secsTo (QDateTime::currentDateTime()) / 60 / 60 / 24));
+            age = VBoxSnapshotsWgt::tr (" (%1 ago)").arg(VBoxGlobal::daysToString(then.secsTo (now) / 60 / 60 / 24));
             ageFormat = AgeInDays;
         }
-        else if (mTimestamp.secsTo (QDateTime::currentDateTime()) > 60 * 60)
+        else if (then.secsTo (now) > 60 * 60)
         {
-            age = VBoxSnapshotsWgt::tr (" (%1 ago)").arg(VBoxGlobal::hoursToString(mTimestamp.secsTo (QDateTime::currentDateTime()) / 60 / 60));
+            age = VBoxSnapshotsWgt::tr (" (%1 ago)").arg(VBoxGlobal::hoursToString(then.secsTo (now) / 60 / 60));
             ageFormat = AgeInHours;
         }
-        else if (mTimestamp.secsTo (QDateTime::currentDateTime()) > 60)
+        else if (then.secsTo (now) > 60)
         {
-            age = VBoxSnapshotsWgt::tr (" (%1 ago)").arg(VBoxGlobal::minutesToString(mTimestamp.secsTo (QDateTime::currentDateTime()) / 60));
+            age = VBoxSnapshotsWgt::tr (" (%1 ago)").arg(VBoxGlobal::minutesToString(then.secsTo (now) / 60));
             ageFormat = AgeInMinutes;
         }
         else
         {
-            age = VBoxSnapshotsWgt::tr (" (%1 ago)").arg(VBoxGlobal::secondsToString(mTimestamp.secsTo (QDateTime::currentDateTime())));
+            age = VBoxSnapshotsWgt::tr (" (%1 ago)").arg(VBoxGlobal::secondsToString(then.secsTo (now)));
             ageFormat = AgeInSeconds;
         }
 
diff --git a/src/VBox/HostDrivers/Support/SUPDrv.c b/src/VBox/HostDrivers/Support/SUPDrv.c
index faf4bdc..fa575e0 100644
--- a/src/VBox/HostDrivers/Support/SUPDrv.c
+++ b/src/VBox/HostDrivers/Support/SUPDrv.c
@@ -176,6 +176,7 @@ static SUPFUNC g_aFunctions[] =
     { "SUPR0ComponentRegisterFactory",          (void *)SUPR0ComponentRegisterFactory },
     { "SUPR0ContAlloc",                         (void *)SUPR0ContAlloc },
     { "SUPR0ContFree",                          (void *)SUPR0ContFree },
+    { "SUPR0ChangeCR4",                         (void *)SUPR0ChangeCR4 },
     { "SUPR0EnableVTx",                         (void *)SUPR0EnableVTx },
     { "SUPR0SuspendVTxOnCpu",                   (void *)SUPR0SuspendVTxOnCpu },
     { "SUPR0ResumeVTxOnCpu",                    (void *)SUPR0ResumeVTxOnCpu },
@@ -3619,6 +3620,34 @@ SUPR0DECL(SUPPAGINGMODE) SUPR0GetPagingMode(void)
 
 
 /**
+ * Change CR4 and take care of the kernel CR4 shadow if applicable.
+ *
+ * CR4 shadow handling is required for Linux >= 4.0. Calling this function
+ * instead of ASMSetCR4() is only necessary for semi-permanent CR4 changes
+ * for code with interrupts enabled.
+ *
+ * @returns the old CR4 value.
+ *
+ * @param   fOrMask         bits to be set in CR4.
+ * @param   fAndMask        bits to be cleard in CR4.
+ *
+ * @remarks Must be called with preemption/interrupts disabled.
+ */
+SUPR0DECL(RTCCUINTREG) SUPR0ChangeCR4(RTCCUINTREG fOrMask, RTCCUINTREG fAndMask)
+{
+#ifdef RT_OS_LINUX
+    return supdrvOSChangeCR4(fOrMask, fAndMask);
+#else
+    RTCCUINTREG uOld = ASMGetCR4();
+    RTCCUINTREG uNew = (uOld & fAndMask) | fOrMask;
+    if (uNew != uOld)
+        ASMSetCR4(uNew);
+    return uOld;
+#endif
+}
+
+
+/**
  * Enables or disabled hardware virtualization extensions using native OS APIs.
  *
  * @returns VBox status code.
diff --git a/src/VBox/HostDrivers/Support/SUPDrvIOC.h b/src/VBox/HostDrivers/Support/SUPDrvIOC.h
index 7bdee56..8b1c865 100644
--- a/src/VBox/HostDrivers/Support/SUPDrvIOC.h
+++ b/src/VBox/HostDrivers/Support/SUPDrvIOC.h
@@ -1,4 +1,4 @@
-/* $Revision: 98021 $ */
+/* $Revision: 98806 $ */
 /** @file
  * VirtualBox Support Driver - IOCtl definitions.
  */
@@ -210,7 +210,7 @@ typedef SUPREQHDR *PSUPREQHDR;
  * @todo Pending work on next major version change:
  *          - Remove RTSpinlockReleaseNoInts.
  */
-#define SUPDRV_IOC_VERSION                              0x001a0009
+#define SUPDRV_IOC_VERSION                              0x001a000a
 
 /** SUP_IOCTL_COOKIE. */
 typedef struct SUPCOOKIE
diff --git a/src/VBox/HostDrivers/Support/SUPDrvInternal.h b/src/VBox/HostDrivers/Support/SUPDrvInternal.h
index f7dbd28..e07bff4 100644
--- a/src/VBox/HostDrivers/Support/SUPDrvInternal.h
+++ b/src/VBox/HostDrivers/Support/SUPDrvInternal.h
@@ -687,6 +687,7 @@ void VBOXCALL   supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession)
 bool VBOXCALL   supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc);
 bool VBOXCALL   supdrvOSGetForcedAsyncTscMode(PSUPDRVDEVEXT pDevExt);
 int  VBOXCALL   supdrvOSEnableVTx(bool fEnabled);
+RTCCUINTREG VBOXCALL supdrvOSChangeCR4(RTCCUINTREG fOrMask, RTCCUINTREG fAndMask);
 bool VBOXCALL   supdrvOSSuspendVTxOnCpu(void);
 void VBOXCALL   supdrvOSResumeVTxOnCpu(bool fSuspended);
 
diff --git a/src/VBox/HostDrivers/Support/SUPLib.cpp b/src/VBox/HostDrivers/Support/SUPLib.cpp
index a032787..c019fcb 100644
--- a/src/VBox/HostDrivers/Support/SUPLib.cpp
+++ b/src/VBox/HostDrivers/Support/SUPLib.cpp
@@ -279,7 +279,7 @@ SUPR3DECL(int) SUPR3InitEx(bool fUnrestricted, PSUPDRVSESSION *ppSession)
         strcpy(CookieReq.u.In.szMagic, SUPCOOKIE_MAGIC);
         CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION;
         const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x001a0000
-                                   ? 0x001a0009
+                                   ? 0x001a000a
                                    : SUPDRV_IOC_VERSION & 0xffff0000;
         CookieReq.u.In.u32MinVersion = uMinVersion;
         rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_COOKIE, &CookieReq, SUP_IOCTL_COOKIE_SIZE);
diff --git a/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp b/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
index 2222136..e1c4dad 100644
--- a/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
+++ b/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
@@ -51,6 +51,7 @@
 #include <iprt/alloc.h>
 #include <iprt/power.h>
 #include <iprt/dbg.h>
+#include <iprt/x86.h>
 #include <VBox/err.h>
 #include <VBox/log.h>
 
@@ -99,6 +100,7 @@ static kern_return_t    VBoxDrvDarwinStop(struct kmod_info *pKModInfo, void *pvD
 static int              VBoxDrvDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess);
 static int              VBoxDrvDarwinClose(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess);
 static int              VBoxDrvDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess);
+static int              VBoxDrvDarwinIOCtlSMAP(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess);
 static int              VBoxDrvDarwinIOCtlSlow(PSUPDRVSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess);
 
 static int              VBoxDrvDarwinErr2DarwinErr(int rc);
@@ -107,6 +109,7 @@ static IOReturn         VBoxDrvDarwinSleepHandler(void *pvTarget, void *pvRefCon
 RT_C_DECLS_END
 
 static void             vboxdrvDarwinResolveSymbols(void);
+static bool             vboxdrvDarwinCpuHasSMAP(void);
 
 
 /*******************************************************************************
@@ -260,6 +263,12 @@ static kern_return_t    VBoxDrvDarwinStart(struct kmod_info *pKModInfo, void *pv
             rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvDarwin");
             if (RT_SUCCESS(rc))
             {
+                if (vboxdrvDarwinCpuHasSMAP())
+                {
+                    LogRel(("disabling SMAP for VBoxDrvDarwinIOCtl\n"));
+                    g_DevCW.d_ioctl = VBoxDrvDarwinIOCtlSMAP;
+                }
+
                 /*
                  * Registering ourselves as a character device.
                  */
@@ -564,6 +573,30 @@ static int VBoxDrvDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags,
 
 
 /**
+ * Alternative Device I/O Control entry point on hosts with SMAP support.
+ *
+ * @returns Darwin for slow IOCtls and VBox status code for the fast ones.
+ * @param   Dev         The device number (major+minor).
+ * @param   iCmd        The IOCtl command.
+ * @param   pData       Pointer to the data (if any it's a SUPDRVIOCTLDATA (kernel copy)).
+ * @param   fFlags      Flag saying we're a character device (like we didn't know already).
+ * @param   pProcess    The process issuing this request.
+ */
+static int VBoxDrvDarwinIOCtlSMAP(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess)
+{
+    /*
+     * Allow VBox R0 code to touch R3 memory. Setting the AC bit disables the
+     * SMAP check.
+     */
+    RTCCUINTREG uFlags = ASMGetFlags();
+    ASMSetAC();
+    int rc = VBoxDrvDarwinIOCtl(Dev, iCmd, pData, fFlags, pProcess);
+    ASMSetFlags(uFlags);
+    return rc;
+}
+
+
+/**
  * Worker for VBoxDrvDarwinIOCtl that takes the slow IOCtl functions.
  *
  * @returns Darwin errno.
@@ -1065,6 +1098,22 @@ static int VBoxDrvDarwinErr2DarwinErr(int rc)
     return EPERM;
 }
 
+/**
+ * Check if the CPU has SMAP support.
+ */
+static bool vboxdrvDarwinCpuHasSMAP(void)
+{
+    uint32_t uMaxId, uEAX, uEBX, uECX, uEDX;
+    ASMCpuId(0, &uMaxId, &uEBX, &uECX, &uEDX);
+    if (   ASMIsValidStdRange(uMaxId)
+        && uMaxId >= 0x00000007)
+    {
+        ASMCpuId_Idx_ECX(0x00000007, 0, &uEAX, &uEBX, &uECX, &uEDX);
+        if (uEBX & X86_CPUID_STEXT_FEATURE_EBX_SMAP)
+            return true;
+    }
+    return false;
+}
 
 RTDECL(int) SUPR0Printf(const char *pszFormat, ...)
 {
diff --git a/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c b/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
index 6696d11..8663579 100644
--- a/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
+++ b/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
@@ -1,4 +1,4 @@
-/* $Rev: 98176 $ */
+/* $Rev: 98806 $ */
 /** @file
  * VBoxDrv - The VirtualBox Support Driver - Linux specifics.
  */
@@ -65,6 +65,7 @@ static inline void stac(void) { }
 #ifdef VBOX_WITH_SUSPEND_NOTIFICATION
 # include <linux/platform_device.h>
 #endif
+#include <iprt/asm-amd64-x86.h>
 
 
 /*******************************************************************************
@@ -796,6 +797,26 @@ int VBOXCALL SUPDrvLinuxIDC(uint32_t uReq, PSUPDRVIDCREQHDR pReq)
 EXPORT_SYMBOL(SUPDrvLinuxIDC);
 
 
+RTCCUINTREG VBOXCALL supdrvOSChangeCR4(RTCCUINTREG fOrMask, RTCCUINTREG fAndMask)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 20, 0)
+    RTCCUINTREG uOld = this_cpu_read(cpu_tlbstate.cr4);
+    RTCCUINTREG uNew = (uOld & fAndMask) | fOrMask;
+    if (uNew != uOld)
+    {
+        this_cpu_write(cpu_tlbstate.cr4, uNew);
+        __write_cr4(uNew);
+    }
+#else
+    RTCCUINTREG uOld = ASMGetCR4();
+    RTCCUINTREG uNew = (uOld & fAndMask) | fOrMask;
+    if (uNew != uOld)
+        ASMSetCR4(uNew);
+#endif
+    return uOld;
+}
+
+
 void VBOXCALL supdrvOSCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
 {
     NOREF(pDevExt);
diff --git a/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp b/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
index 8282562..1304494 100644
--- a/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
+++ b/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
@@ -1114,55 +1114,61 @@ static BOOLEAN _stdcall VBoxDrvNtFastIoDeviceControl(PFILE_OBJECT pFileObj, BOOL
                             RtlCopyMemory(pHdr, pvInput, cbInput);
                             if (cbInput < cbBuf)
                                 RtlZeroMemory((uint8_t *)pHdr + cbInput, cbBuf - cbInput);
-                            rcNt = STATUS_SUCCESS;
+                            if (!memcmp(pHdr, &Hdr, sizeof(Hdr)))
+                                rcNt = STATUS_SUCCESS;
+                            else
+                                rcNt = STATUS_INVALID_PARAMETER;
                         }
                         __except(EXCEPTION_EXECUTE_HANDLER)
                         {
                             rcNt = GetExceptionCode();
                         }
-                    }
-                    else
-                        rcNt = STATUS_NO_MEMORY;
-                    if (NT_SUCCESS(rcNt))
-                    {
-                        /*
-                         * Now call the common code to do the real work.
-                         */
-                        rc = supdrvIOCtl(uCmd, pDevExt, pSession, pHdr, cbBuf);
-                        if (RT_SUCCESS(rc))
+                        if (NT_SUCCESS(rcNt))
                         {
                             /*
-                             * Copy back the result.
+                             * Now call the common code to do the real work.
                              */
-                            cbOut = pHdr->cbOut;
-                            if (cbOut > cbOutput)
-                            {
-                                cbOut = cbOutput;
-                                OSDBGPRINT(("VBoxDrvNtFastIoDeviceControl: too much output! %#x > %#x; uCmd=%#x!\n",
-                                            pHdr->cbOut, cbOut, uCmd));
-                            }
-                            if (cbOut)
+                            rc = supdrvIOCtl(uCmd, pDevExt, pSession, pHdr, cbBuf);
+                            if (RT_SUCCESS(rc))
                             {
-                                __try
+                                /*
+                                 * Copy back the result.
+                                 */
+                                cbOut = pHdr->cbOut;
+                                if (cbOut > cbOutput)
                                 {
-                                    RtlCopyMemory(pvOutput, pHdr, cbOut);
-                                    rcNt = STATUS_SUCCESS;
+                                    cbOut = cbOutput;
+                                    OSDBGPRINT(("VBoxDrvNtFastIoDeviceControl: too much output! %#x > %#x; uCmd=%#x!\n",
+                                                pHdr->cbOut, cbOut, uCmd));
                                 }
-                                __except(EXCEPTION_EXECUTE_HANDLER)
+                                if (cbOut)
                                 {
-                                    rcNt = GetExceptionCode();
+                                    __try
+                                    {
+                                        RtlCopyMemory(pvOutput, pHdr, cbOut);
+                                        rcNt = STATUS_SUCCESS;
+                                    }
+                                    __except(EXCEPTION_EXECUTE_HANDLER)
+                                    {
+                                        rcNt = GetExceptionCode();
+                                    }
                                 }
+                                else
+                                    rcNt = STATUS_SUCCESS;
                             }
+                            else if (rc == VERR_INVALID_PARAMETER)
+                                rcNt = STATUS_INVALID_PARAMETER;
                             else
-                                rcNt = STATUS_SUCCESS;
+                                rcNt = STATUS_NOT_SUPPORTED;
+                            Log2(("VBoxDrvNtFastIoDeviceControl: returns %#x cbOut=%d rc=%#x\n", rcNt, cbOut, rc));
                         }
-                        else if (rc == VERR_INVALID_PARAMETER)
-                            rcNt = STATUS_INVALID_PARAMETER;
                         else
-                            rcNt = STATUS_NOT_SUPPORTED;
-                        Log2(("VBoxDrvNtFastIoDeviceControl: returns %#x cbOut=%d rc=%#x\n", rcNt, cbOut, rc));
+                            Log(("VBoxDrvNtFastIoDeviceControl: Error reading %u bytes of user memory at %p (uCmd=%#x)\n",
+                                 cbInput, pvInput, uCmd));
+                        ExFreePoolWithTag(pHdr, 'VBox');
                     }
-                    ExFreePoolWithTag(pHdr, 'VBox');
+                    else
+                        rcNt = STATUS_NO_MEMORY;
                 }
                 else
                 {
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbRt.cpp b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbRt.cpp
index ddd702e..a77122c 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbRt.cpp
+++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbRt.cpp
@@ -604,6 +604,7 @@ static NTSTATUS vboxUsbRtSetConfig(PVBOXUSBDEV_EXT pDevExt, uint8_t uConfigurati
     for (i = 0; i < pCfgDr->bNumInterfaces; i++)
     {
         pIfLe[i].InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(pCfgDr, pCfgDr, i, 0, -1, -1, -1);
+        pIfLe[i].Interface = NULL;
         if (!pIfLe[i].InterfaceDescriptor)
         {
             AssertMsgFailed((__FUNCTION__": interface %d not found\n", i));
@@ -611,6 +612,7 @@ static NTSTATUS vboxUsbRtSetConfig(PVBOXUSBDEV_EXT pDevExt, uint8_t uConfigurati
             break;
         }
     }
+    pIfLe[pCfgDr->bNumInterfaces].InterfaceDescriptor = NULL;
 
     if (NT_SUCCESS(Status))
     {
@@ -632,7 +634,7 @@ static NTSTATUS vboxUsbRtSetConfig(PVBOXUSBDEV_EXT pDevExt, uint8_t uConfigurati
                     Assert(NT_SUCCESS(Status));
                     for (i = 0; i < pDevExt->Rt.uNumInterfaces; i++)
                     {
-                        uint32_t uTotalIfaceInfoLength = sizeof (struct _URB_SELECT_INTERFACE) + ((pIfLe[i].Interface->NumberOfPipes > 0) ? (pIfLe[i].Interface->NumberOfPipes - 1) : 0) * sizeof(USBD_PIPE_INFORMATION);
+                        size_t uTotalIfaceInfoLength = RT_OFFSETOF(struct _USBD_INTERFACE_INFORMATION, Pipes[RT_MAX(pIfLe[i].Interface->NumberOfPipes, 1)]);
                         pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo = (PUSBD_INTERFACE_INFORMATION)vboxUsbMemAlloc(uTotalIfaceInfoLength);
                         if (!pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo)
                         {
@@ -656,11 +658,10 @@ static NTSTATUS vboxUsbRtSetConfig(PVBOXUSBDEV_EXT pDevExt, uint8_t uConfigurati
                             pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo = NULL;
                         }
 
-                        *pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo = *pIfLe[i].Interface;
+                        RtlCopyMemory(pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo, pIfLe[i].Interface, uTotalIfaceInfoLength);
 
                         for (ULONG j = 0; j < pIfLe[i].Interface->NumberOfPipes; j++)
                         {
-                            pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j] = pIfLe[i].Interface->Pipes[j];
                             pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo[j].EndpointAddress = pIfLe[i].Interface->Pipes[j].EndpointAddress;
                             pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo[j].NextScheduledFrame = 0;
                         }
diff --git a/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m b/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m
index bcce371..7830113 100644
--- a/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m
+++ b/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m
@@ -193,39 +193,31 @@
         glPopAttrib(); \
     } while (0)
 
-#ifdef DEBUG_poetzsch
-# define DEBUG_CHECK_GL_ERROR() do { checkGLError(__FILE__, __LINE__); } while(0);
-
-static void checkGLError(char *pszFile, int iLine)
-{
-    GLenum uGlErr = glGetError();
-    if (uGlErr != GL_NO_ERROR)
-    {
-        const char *errStr;
-        switch (uGlErr)
-        {
-            case GL_INVALID_ENUM:      errStr = "GL_INVALID_ENUM"; break;
-            case GL_INVALID_VALUE:     errStr = "GL_INVALID_VALUE"; break;
-            case GL_INVALID_OPERATION: errStr = "GL_INVALID_OPERATION"; break;
-            case GL_STACK_OVERFLOW:    errStr = "GL_STACK_OVERFLOW"; break;
-            case GL_STACK_UNDERFLOW:   errStr = "GL_STACK_UNDERFLOW"; break;
-            case GL_OUT_OF_MEMORY:     errStr = "GL_OUT_OF_MEMORY"; break;
-            case GL_TABLE_TOO_LARGE:   errStr = "GL_TABLE_TOO_LARGE"; break;
-            default:                   errStr = "UNKNOWN"; break;
-        }
-        DEBUG_MSG(("%s:%d: glError %d (%s)\n", pszFile, iLine, uGlErr, errStr));
-    }
-}
+#ifdef VBOX_STRICT
+# define DEBUG_CLEAR_GL_ERRORS() \
+    do { \
+        while (glGetError() != GL_NO_ERROR) \
+        { /* nothing */ } \
+    } while (0)
+# define DEBUG_CHECK_GL_ERROR(a_szOp) \
+    do { \
+        GLenum iGlCheckErr = glGetError(); \
+        if (RT_UNLIKELY(iGlCheckErr != GL_NO_ERROR)) \
+            AssertMsgFailed((a_szOp ": iGlCheckErr=%#x\n", iGlCheckErr)); \
+    } while (0) 
 #else
-# define DEBUG_CHECK_GL_ERROR() do {} while (0)
+# define DEBUG_CLEAR_GL_ERRORS()        do {} while (0)
+# define DEBUG_CHECK_GL_ERROR(a_szOp)   do {} while (0)
 #endif
 
 
+
 #ifdef IN_VMSVGA3D
 
 /* 
  * VMSVGA3D compatibility glue.
  */
+typedef struct WindowInfo WindowInfo;
 
 # define CR_RGB_BIT             RT_BIT_32(0)
 
@@ -242,76 +234,6 @@ static void checkGLError(char *pszFile, int iLine)
 # define VMSVGA3D_NON_DEFAULT_PROFILE_BIT RT_BIT_32(31)
 # define CR_ALL_BITS            UINT32_C(0x800003ff)
 
-typedef struct WindowInfo
-{
-    uint32_t volatile           cRefs;
-    RTCRITSECT                  CompositorLock;
-    PCVBOXVR_SCR_COMPOSITOR     pCompositor;
-
-    //NativeNSViewRef window;
-    //NativeNSViewRef nativeWindow; /**< for render_to_app_window */
-    NativeNSOpenGLContextRef   *currentCtx;
-} WindowInfo;
-
-static void vmsvga3DWinInfoDestroy(WindowInfo *pWinInfo)
-{
-    /** @todo */
-}
-
-DECLINLINE(void) renderspuWinRetain(WindowInfo *pWinInfo)
-{
-    ASMAtomicIncU32(&pWinInfo->cRefs);
-}
-
-DECLINLINE(void) renderspuWinRelease(WindowInfo *pWinInfo)
-{
-    uint32_t cRefs = ASMAtomicDecU32(&pWinInfo->cRefs);
-    if (!cRefs)
-        vmsvga3DWinInfoDestroy(pWinInfo);
-}      
-
-static int renderspuVBoxCompositorLock(WindowInfo *pWinInfo, PCVBOXVR_SCR_COMPOSITOR *ppCompositor)
-{
-    int rc = RTCritSectEnter(&pWinInfo->CompositorLock);
-    AssertRCReturn(rc, rc);
-    if (ppCompositor)
-        *ppCompositor = pWinInfo->pCompositor;
-    return VINF_SUCCESS;
-}
-
-static int renderspuVBoxCompositorUnlock(WindowInfo *pWinInfo)
-{
-    int rc = RTCritSectLeave(&pWinInfo->CompositorLock);
-    AssertRC(rc);
-    return rc;
-}
-
-static PCVBOXVR_SCR_COMPOSITOR renderspuVBoxCompositorAcquire(WindowInfo *pWinInfo)
-{
-    int rc = RTCritSectEnter(&pWinInfo->CompositorLock);
-    AssertRCReturn(rc, NULL);
-
-    PCVBOXVR_SCR_COMPOSITOR pCompositor = pWinInfo->pCompositor;
-    if (pCompositor)
-    {
-        Assert(!CrVrScrCompositorIsEmpty(pWinInfo->pCompositor));
-        return pCompositor;
-    }
-
-    /* if no compositor is set, release the lock and return */
-    RTCritSectLeave(&pWinInfo->CompositorLock);
-    return NULL;
-}
-
-static void renderspuVBoxCompositorRelease(WindowInfo *pWinInfo)
-{
-    Assert(pWinInfo->pCompositor);
-    Assert(!CrVrScrCompositorIsEmpty(pWinInfo->pCompositor));
-    int rc = RTCritSectLeave(&pWinInfo->CompositorLock);
-    AssertRC(rc);
-}
-
-
 #endif /* IN_VMSVGA3D */
 
 
@@ -388,7 +310,9 @@ static void vboxCtxEnter(NSOpenGLContext*pNewCtx, PVBOX_CR_RENDER_CTX_INFO pCtxI
         if(pOldCtx != nil)
             glFlush();
         
+        DEBUG_CLEAR_GL_ERRORS();
         [pNewCtx makeCurrentContext];
+        DEBUG_CHECK_GL_ERROR("makeCurrentContext");
         
         pCtxInfo->fIsValid = true;
         pCtxInfo->pCtx = pOldCtx;
@@ -419,10 +343,14 @@ static void vboxCtxLeave(PVBOX_CR_RENDER_CTX_INFO pCtxInfo)
              *        pOldView or fix the code. */
             if ([pOldCtx view] != pOldView)
             {
+                DEBUG_CLEAR_GL_ERRORS();
                 [pOldCtx setView: pOldView];
+                DEBUG_CHECK_GL_ERROR("setView");
             }
         
+            DEBUG_CLEAR_GL_ERRORS();
             [pOldCtx makeCurrentContext];
+            DEBUG_CHECK_GL_ERROR("makeCurrentContext");
             
 #ifdef VBOX_STRICT
             {
@@ -811,7 +739,9 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
 
 @end
 
+#ifndef IN_VMSVGA3D
 @class DockOverlayView;
+#endif
 
 /** 
  * The custom view class.
@@ -835,6 +765,7 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
 
     GLuint           m_FBOId;
 
+#ifndef IN_VMSVGA3D
     /** The corresponding dock tile view of this OpenGL view & all helper
      * members. */
     DockOverlayView *m_DockTileView;
@@ -842,6 +773,7 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
     GLfloat          m_FBOThumbScaleX;
     GLfloat          m_FBOThumbScaleY;
     uint64_t            m_msDockUpdateTS;
+#endif
 
     /** @name For clipping
      * @remarks appears to be unused and a complete waste of time + heap.
@@ -860,13 +792,15 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
     NSRect           m_RootRect;
     float            m_yInvRootOffset;
     
-    CR_BLITTER *m_pBlitter;
-    WindowInfo *m_pWinInfo;
-    bool m_fNeedViewportUpdate;
-    bool m_fNeedCtxUpdate;
-    bool m_fDataVisible;
-    bool m_fCleanupNeeded;
-    bool m_fEverSized;
+#ifndef IN_VMSVGA3D
+    CR_BLITTER         *m_pBlitter;
+    WindowInfo         *m_pWinInfo;
+#endif
+    bool                m_fNeedViewportUpdate;
+    bool                m_fNeedCtxUpdate;
+    bool                m_fDataVisible;
+    bool                m_fCleanupNeeded;
+    bool                m_fEverSized;
 }
 - (id)initWithFrame:(NSRect)frame thread:(RTTHREAD)aThread parentView:(NSView*)pParentView winInfo:(WindowInfo*)pWinInfo;
 - (void)setGLCtx:(NSOpenGLContext*)pCtx;
@@ -893,8 +827,10 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
 - (void)vboxReshapeOnResizePerform;
 - (void)vboxReshapeOnReparentPerform;
 
+#ifndef IN_VMSVGA3D
 - (void)createDockTile;
 - (void)deleteDockTile;
+#endif
 
 - (void)makeCurrentFBO;
 - (void)swapFBO;
@@ -907,17 +843,23 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
 - (void)vboxReparentUI:(NSView*)pParentView;
 - (void)vboxPresent:(const VBOXVR_SCR_COMPOSITOR*)pCompositor;
 - (void)vboxPresentCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor;
+#ifndef IN_VMSVGA3D
 - (void)vboxPresentToDockTileCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor;
+#endif
 - (void)vboxPresentToViewCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor;
 - (void)presentComposition:(const VBOXVR_SCR_COMPOSITOR_ENTRY*)pChangedEntry;
+#ifndef IN_VMSVGA3D
 - (void)vboxBlitterSyncWindow;
+#endif
 
 - (void)clearVisibleRegions;
 - (void)setVisibleRegions:(GLint)cRects paRects:(const GLint*)paRects;
 - (GLboolean)vboxNeedsEmptyPresent;
 
-- (NSView*)dockTileScreen;
+#ifndef IN_VMSVGA3D
+- (NSView *)dockTileScreen;
 - (void)reshapeDockTile;
+#endif
 - (void)cleanupData;
 @end
 
@@ -959,6 +901,7 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
 @end
 
 
+#ifndef IN_VMSVGA3D
 /**
  * Dock overlay view class.
  */
@@ -1110,6 +1053,7 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
     return m_ThumbImage;
 }
 @end
+#endif /* !IN_VMSVGA3D */
 
 /********************************************************************************
 *
@@ -1413,8 +1357,10 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
     m_Size                    = NSMakeSize(1, 1);
     m_RootRect                = NSMakeRect(0, 0, m_Size.width, m_Size.height);
     m_yInvRootOffset          = 0;
+#ifndef IN_VMSVGA3D
     m_pBlitter                = nil;
-    m_pWinInfo             	  = pWinInfo;
+    m_pWinInfo                = pWinInfo;
+#endif
     m_fNeedViewportUpdate     = true;        
     m_fNeedCtxUpdate          = true;
     m_fDataVisible            = false;
@@ -1431,8 +1377,10 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
 {
     COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
 
+#ifndef IN_VMSVGA3D
     [self deleteDockTile];
-    
+#endif
+
     [self setGLCtx:nil];
     
     if (m_pSharedGLCtx)
@@ -1444,11 +1392,14 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
 
         m_pSharedGLCtx = nil;
         
+
+#ifndef IN_VMSVGA3D
         CrBltTerm(m_pBlitter);
         
         RTMemFree(m_pBlitter);
         
         m_pBlitter = nil;
+#endif
     }
 
     [self clearVisibleRegions];
@@ -1487,16 +1438,19 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
     if (m_pGLCtx != pCtx)
     {
         /* Ensure the context drawable is cleared to avoid holding a reference to inexistent view. */
-    if (m_pGLCtx)
-    {
-        [m_pGLCtx clearDrawable];
-        [m_pGLCtx release];
-        /*[m_pGLCtx performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];*/
-    }
+        if (m_pGLCtx)
+        {
+#ifdef IN_VMSVGA3D
+            Assert(!pCtx);
+#endif
+            [m_pGLCtx clearDrawable];
+            [m_pGLCtx release];
+            /*[m_pGLCtx performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];*/
+        }
 
-    m_pGLCtx = pCtx;
-    if (pCtx)
-        [pCtx retain];
+        m_pGLCtx = pCtx;
+        if (pCtx)
+            [pCtx retain];
     }
         
     COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
@@ -1631,7 +1585,9 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
         [self performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];
     }
     
+#ifndef IN_VMSVGA3D
     renderspuWinRelease(m_pWinInfo);
+#endif
     
     COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
 }
@@ -1687,7 +1643,9 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
     /* Update the viewport for our OpenGL view. */
     [m_pSharedGLCtx update];
 
+#ifndef IN_VMSVGA3D
     [self vboxBlitterSyncWindow];
+#endif
         
     /* Clear background to transparent. */
     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@@ -1700,7 +1658,10 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
     COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
     [self vboxReshapePerform];
     
+#ifndef IN_VMSVGA3D
     [self createDockTile];
+#endif
+
     /* have to rebind GL_TEXTURE_RECTANGLE_ARB as m_FBOTexId could be changed in updateFBO call */
     m_fNeedViewportUpdate = true;
 #if 0
@@ -1723,7 +1684,9 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
 {
     COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
     [self vboxReshapePerform];
+#ifndef IN_VMSVGA3D
     [self createDockTile];
+#endif
     COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
 }
 
@@ -1775,7 +1738,11 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
 
 - (void)vboxReshapePerform
 {
+#ifndef IN_VMSVGA3D
     COCOA_LOG_FLOW(("%s: self=%p - m_DockTileView=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)m_DockTileView));
+#else
+    COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
+#endif
 
     /* NOTE: Please consider the next naming convention for variables.
      *
@@ -1842,8 +1809,10 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
     /* Set the new frame. */
     [[self window] setFrame:windowFrameSCS display:YES];
 
+#ifndef IN_VMSVGA3D
     /* Inform the dock tile view as well. */
     [self reshapeDockTile];
+#endif
 
     /* Make sure the context is updated accordingly. */
     /* [self updateViewport]; */
@@ -1859,6 +1828,8 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
     COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
 }
 
+#ifndef IN_VMSVGA3D
+
 - (void)createDockTile
 {
     COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
@@ -1891,32 +1862,55 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
     COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
 }
 
+#endif /* !IN_VMSVGA3D */
+
 - (void)makeCurrentFBO
 {
-    COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
+    COCOA_LOG_FLOW(("%s: self=%p - m_pGLCtx=%p m_fNeedCtxUpdate=%d\n", __PRETTY_FUNCTION__, (void *)self, 
+                    (void *)m_pGLCtx, m_fNeedCtxUpdate));
 
     if (m_pGLCtx)
     {
+        NSOpenGLContext *pPrevCtx = [NSOpenGLContext currentContext];
+
+#ifdef IN_VMSVGA3D
+        /* Always flush before flush. glXMakeCurrent and wglMakeCurrent does this
+           implicitly, seemingly NSOpenGLContext::makeCurrentContext doesn't. */
+        if (pPrevCtx != nil)
+        {
+            DEBUG_CLEAR_GL_ERRORS();
+            glFlush();
+            DEBUG_CHECK_GL_ERROR("glFlush");
+        }
+#endif
+
         if ([m_pGLCtx view] != self)
         {
+#ifndef IN_VMSVGA3D
             /* We change the active view, so flush first */
-            if([NSOpenGLContext currentContext] != 0)
+            if (pPrevCtx != nil)
                 glFlush();
+#endif
+            DEBUG_CLEAR_GL_ERRORS();
             [m_pGLCtx setView: self];
-            DEBUG_CHECK_GL_ERROR();
+            DEBUG_CHECK_GL_ERROR("setView");
         }
 
-        /*
-        if ([NSOpenGLContext currentContext] != m_pGLCtx)
-        */
+#if 0
+        if (pPrevCtx != m_pGLCtx)
+#endif
         {
+            DEBUG_CLEAR_GL_ERRORS();
             [m_pGLCtx makeCurrentContext];
-            DEBUG_CHECK_GL_ERROR();
-            if (m_fNeedCtxUpdate == true)
-            {
-                [m_pGLCtx update];
-                m_fNeedCtxUpdate = false;
-            }
+            DEBUG_CHECK_GL_ERROR("makeCurrentContext");
+            Assert([NSOpenGLContext currentContext] == m_pGLCtx);
+            Assert([m_pGLCtx view] == self);
+        }
+
+        if (m_fNeedCtxUpdate == true)
+        {
+            [m_pGLCtx update];
+            m_fNeedCtxUpdate = false;
         }
         
         if (!m_FBOId)
@@ -1940,6 +1934,7 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
         return true;
     }
         
+#ifndef IN_VMSVGA3D            
     Assert(!m_pBlitter);
     m_pBlitter = RTMemAlloc(sizeof(*m_pBlitter));
     if (RT_UNLIKELY(!m_pBlitter))
@@ -1950,12 +1945,7 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
     }
         
     int rc = CrBltInit(m_pBlitter, NULL, false /*fCreateNewCtx*/, false /*fForceDrawBlt*/, 
-#ifdef IN_VMSVGA3D
-                       NULL /** @todo */, NULL /** @todo */
-#else
-                       &render_spu.GlobalShaders, &render_spu.blitterDispatch
-#endif
-                       );
+                       &render_spu.GlobalShaders, &render_spu.blitterDispatch);
     if (RT_FAILURE(rc))
     {
         DEBUG_WARN(("CrBltInit failed, rc %d", rc));
@@ -1967,6 +1957,7 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
     }        
 
     COCOA_LOG_FLOW(("%s: blitter (%p) created successfully for view 0x%p\n", (void *)m_pBlitter, (void *)self));
+#endif /* !IN_VMSVGA3D */
 
     /* Create a shared context out of the main context. Use the same pixel format. */
     NSOpenGLPixelFormat *pPixelFormat = [(OverlayOpenGLContext *)m_pGLCtx openGLPixelFormat];
@@ -2091,7 +2082,8 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
     }
 #endif
     
-    const VBOXVR_SCR_COMPOSITOR *pCompositor;
+    const VBOXVR_SCR_COMPOSITOR *pCompositor = NULL;
+#ifndef IN_VMSVGA3D
     int rc = renderspuVBoxCompositorLock(m_pWinInfo, &pCompositor);
     if (RT_FAILURE(rc))
     {
@@ -2099,17 +2091,14 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
         return;
     }
 
-#ifndef IN_VMSVGA3D
     if (!pCompositor && !m_fCleanupNeeded)
     {
         renderspuVBoxCompositorUnlock(m_pWinInfo);
         COCOA_LOG_FLOW(("%s: returns - noCompositorUI\n", __PRETTY_FUNCTION__));
         return;
     }
-#endif
 
     VBOXVR_SCR_COMPOSITOR TmpCompositor;
-    
     if (pCompositor)
     {
         if (!m_pSharedGLCtx)
@@ -2138,12 +2127,12 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
     else
     {
         DEBUG_MSG(("%s: NeedCleanup\n", __PRETTY_FUNCTION__));
-#ifndef IN_VMSVGA3D /** @todo VMSVGA3 */
         Assert(m_fCleanupNeeded);
-#endif
         CrVrScrCompositorInit(&TmpCompositor, NULL);
         pCompositor = &TmpCompositor;
     }
+#endif /* !IN_VMSVGA3D */
+
     
     if ([self lockFocusIfCanDraw])
     {
@@ -2164,7 +2153,9 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
         [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(vboxTryDrawUI) userInfo:nil repeats:NO];
     }
     
+#ifndef IN_VMSVGA3D
     renderspuVBoxCompositorUnlock(m_pWinInfo);
+#endif
     COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
 }
 
@@ -2179,7 +2170,9 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
 {
     COCOA_LOG_FLOW(("%s: self=%p pCompositor=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)pCompositor));
     /*DEBUG_MSG(("OVIW(%p): renderFBOToView\n", (void *)self));*/
+#ifndef IN_VMSVGA3D
     AssertPtr(pCompositor);
+#endif
 
     VBOX_CR_RENDER_CTX_INFO CtxInfo;    
     vboxCtxEnter(m_pSharedGLCtx, &CtxInfo);
@@ -2209,8 +2202,10 @@ static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
     
     m_fCleanupNeeded = false;
     
+#ifndef IN_VMSVGA3D
     /* Render FBO content to the dock tile when necessary. */
     [self vboxPresentToDockTileCS:pCompositor];
+#endif
 
     /* change to #if 0 to see thumbnail image */            
 #if 1
@@ -2267,6 +2262,7 @@ DECLINLINE(void) vboxNSRectToRectStretched(const NSRect *pR, RTRECT *pRect, floa
     
     m_fDataVisible = false;
     
+# ifndef IN_VMSVGA3D
     float xStretch;
     float yStretch;
     CrVrScrCompositorGetStretching(pCompositor, &xStretch, &yStretch);
@@ -2320,9 +2316,9 @@ DECLINLINE(void) vboxNSRectToRectStretched(const NSRect *pR, RTRECT *pRect, floa
             else
             {
                 DEBUG_WARN(("CrBltEnter failed rc %d", rc));
-# ifndef DEBUG_VERBOSE
+#  ifndef DEBUG_VERBOSE
                 AssertMsgFailed(("CrBltEnter failed rc %Rrc", rc));
-# endif
+#  endif
             }
         }
         else
@@ -2331,6 +2327,7 @@ DECLINLINE(void) vboxNSRectToRectStretched(const NSRect *pR, RTRECT *pRect, floa
             DEBUG_MSG_1(("BlitStretched: CrVrScrCompositorEntryRegionsGet failed rc %d\n", rc));
         }
     }
+# endif /* !IN_VMSVGA3D */
 #endif
             /*
             glFinish();
@@ -2347,6 +2344,7 @@ DECLINLINE(void) vboxNSRectToRectStretched(const NSRect *pR, RTRECT *pRect, floa
     [self vboxTryDraw];
 }
 
+#ifndef IN_VMSVGA3D
 - (void)vboxBlitterSyncWindow
 {
     COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
@@ -2370,10 +2368,12 @@ DECLINLINE(void) vboxNSRectToRectStretched(const NSRect *pR, RTRECT *pRect, floa
     CrBltMuralSetCurrentInfo(m_pBlitter, &WinInfo);
     CrBltCheckUpdateViewport(m_pBlitter);
 }
+#endif /* !IN_VMSVGA3D */
 
-#ifdef VBOX_WITH_CRDUMPER_THUMBNAIL
+#ifndef IN_VMSVGA3D
+# ifdef VBOX_WITH_CRDUMPER_THUMBNAIL
 static int g_cVBoxTgaCtr = 0;
-#endif
+# endif
 - (void)vboxPresentToDockTileCS:(PCVBOXVR_SCR_COMPOSITOR)pCompositor
 {
     COCOA_LOG_FLOW(("%s: self=%p pCompositor=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)pCompositor));
@@ -2395,7 +2395,7 @@ static int g_cVBoxTgaCtr = 0;
         if (msTS - m_msDockUpdateTS > 200)
         {
             m_msDockUpdateTS = msTS;
-#if 0
+# if 0
             /* todo: check this for optimization */
             glBindTexture(GL_TEXTURE_RECTANGLE_ARB, myTextureName);
             glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_STORAGE_HINT_APPLE,
@@ -2410,7 +2410,7 @@ static int g_cVBoxTgaCtr = 0;
             /* Do other work processing here, using a double or triple buffer */
             glGetTexImage(GL_TEXTURE_RECTANGLE_ARB, 0, GL_BGRA,
                           GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
-#endif
+# endif
             glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
             glDrawBuffer(GL_BACK);
 
@@ -2472,9 +2472,9 @@ static int g_cVBoxTgaCtr = 0;
                     else
                     {
                         DEBUG_WARN(("CrBltEnter failed rc %d", rc));
-#ifndef DEBUG_VERBOSE
+# ifndef DEBUG_VERBOSE
                         AssertMsgFailed(("CrBltEnter failed rc %Rrc", rc));
-#endif
+# endif
                     }
                 }
                 else
@@ -2499,11 +2499,11 @@ static int g_cVBoxTgaCtr = 0;
                          [[m_DockTileView thumbBitmap] bitmapData]);
             [m_DockTileView unlock];
             
-#ifdef VBOX_WITH_CRDUMPER_THUMBNAIL
+# ifdef VBOX_WITH_CRDUMPER_THUMBNAIL
             ++g_cVBoxTgaCtr;
             crDumpNamedTGAF((GLint)rr.size.width, (GLint)rr.size.height, 
                 [[m_DockTileView thumbBitmap] bitmapData], "/Users/leo/vboxdumps/dump%d.tga", g_cVBoxTgaCtr);
-#endif                
+# endif                
 
             pDT = [[NSApplication sharedApplication] dockTile];
 
@@ -2512,6 +2512,7 @@ static int g_cVBoxTgaCtr = 0;
         }
     }
 }
+#endif /* !IN_VMSVGA3D */
 
 - (void)clearVisibleRegions
 {
@@ -2556,7 +2557,9 @@ static int g_cVBoxTgaCtr = 0;
     COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
 }
 
-- (NSView*)dockTileScreen
+#ifndef IN_VMSVGA3D
+
+- (NSView *)dockTileScreen
 {
     COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
     NSView *pContentView = [[[NSApplication sharedApplication] dockTile] contentView];
@@ -2603,6 +2606,8 @@ static int g_cVBoxTgaCtr = 0;
                     (int)newFrame.origin.y, (int)newFrame.size.width, (int)newFrame.size.height, (void *)pView));
 }
 
+#endif /* !IN_VMSVGA3D */
+
 @end /* @implementation OverlayView */
 
 
@@ -2715,7 +2720,7 @@ void cocoaGLCtxCreate(NativeNSOpenGLContextRef *ppCtx, GLbitfield fVisParams, Na
     }
 
     [pPool release];
-    COCOA_LOG_FLOW(("cocoaGLCtxDestroy: returns *ppCtx=%p\n", (void *)*ppCtx));
+    COCOA_LOG_FLOW(("cocoaGLCtxCreate: returns *ppCtx=%p\n", (void *)*ppCtx));
 }
 
 void cocoaGLCtxDestroy(NativeNSOpenGLContextRef pCtx)
@@ -2788,9 +2793,9 @@ void cocoaViewCreate(NativeNSViewRef *ppView, WindowInfo *pWinInfo, NativeNSView
     VBoxMainThreadTaskRunner *pRunner = [VBoxMainThreadTaskRunner globalInstance];
     [pRunner runTasksSyncIfPossible];
     
+#ifndef IN_VMSVGA3D
     renderspuWinRetain(pWinInfo);
 
-#ifndef IN_VMSVGA3D
     if (renderspuCalloutAvailable())
     {
         CR_RCD_CREATEVIEW CreateView;
@@ -2814,13 +2819,16 @@ void cocoaViewCreate(NativeNSViewRef *ppView, WindowInfo *pWinInfo, NativeNSView
 #endif
     }
     
+#ifndef IN_VMSVGA3D
     if (!*ppView)
         renderspuWinRelease(pWinInfo);
+#endif
     
     [pPool release];
     COCOA_LOG_FLOW(("cocoaViewCreate: returns *ppView=%p\n", (void *)*ppView));
 }
 
+#ifndef IN_VMSVGA3D
 void cocoaViewReparent(NativeNSViewRef pView, NativeNSViewRef pParentView)
 {
     COCOA_LOG_FLOW(("cocoaViewReparent: pView=%p pParentView=%p\n", (void *)pView, (void *)pParentView));
@@ -2833,6 +2841,7 @@ void cocoaViewReparent(NativeNSViewRef pView, NativeNSViewRef pParentView)
     [pPool release];
     COCOA_LOG_FLOW(("cocoaViewReparent: returns\n"));
 }
+#endif /* !IN_VMSVGA3D */
 
 void cocoaViewDestroy(NativeNSViewRef pView)
 {
@@ -2846,6 +2855,7 @@ void cocoaViewDestroy(NativeNSViewRef pView)
     COCOA_LOG_FLOW(("cocoaViewDestroy: returns\n"));
 }
 
+#ifndef IN_VMSVGA3D
 void cocoaViewShow(NativeNSViewRef pView, GLboolean fShowIt)
 {
     COCOA_LOG_FLOW(("cocoaViewShow: pView=%p fShowIt=%d\n", (void *)pView, fShowIt));
@@ -2856,6 +2866,7 @@ void cocoaViewShow(NativeNSViewRef pView, GLboolean fShowIt)
     [pPool release];
     COCOA_LOG_FLOW(("cocoaViewShow: returns\n"));
 }
+#endif /* IN_VMSVGA3D */
 
 void cocoaViewDisplay(NativeNSViewRef pView)
 {
@@ -2910,8 +2921,6 @@ static DECLCALLBACK(void) vboxRcdGetGeomerty(void *pvUser)
                     pGetGeometry->rect.size.width, pGetGeometry->rect.size.height));
 }
 
-#endif /* !IN_VMSVGA3D */
-
 void cocoaViewGetGeometry(NativeNSViewRef pView, int *px, int *py, int *pcx, int *pcy)
 {
     COCOA_LOG_FLOW(("cocoaViewGetGeometry: pView=%p px=%p py=%p pcx=%p pcy=%p\n", 
@@ -2953,14 +2962,15 @@ void cocoaViewPresentComposition(NativeNSViewRef pView, PCVBOXVR_SCR_COMPOSITOR_
     COCOA_LOG_FLOW(("cocoaViewPresentComposition: pView=%p pChangedEntry=%p\n", (void *)pView, (void *)pChangedEntry));
     NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
     NSOpenGLContext *pCtx;
-    
-    /* view should not necesserily have a context set */
+
+# ifdef IN_VMSVGA3D
+    Assert([(OverlayView *)pView glCtx]);
+
+# else
+    /* The view may not necesserily have a GL context set. */
     pCtx = [(OverlayView *)pView glCtx];
     if (!pCtx)
     {
-#ifdef IN_VMSVGA3D /** @todo VMSVGA3 */
-        pCtx = NULL;
-#else
         ContextInfo *pCtxInfo = renderspuDefaultSharedContextAcquire();
         if (!pCtxInfo)
         {
@@ -2972,10 +2982,10 @@ void cocoaViewPresentComposition(NativeNSViewRef pView, PCVBOXVR_SCR_COMPOSITOR_
         }
         
         pCtx = pCtxInfo->context;
-#endif
         
         [(OverlayView *)pView setGLCtx:pCtx];
     }
+# endif
     
     [(OverlayView *)pView presentComposition:pChangedEntry];
 
@@ -2983,6 +2993,8 @@ void cocoaViewPresentComposition(NativeNSViewRef pView, PCVBOXVR_SCR_COMPOSITOR_
     COCOA_LOG_FLOW(("cocoaViewPresentComposition: returns\n"));
 }
 
+#endif /* !IN_VMSVGA3D */
+
 void cocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx)
 {
     COCOA_LOG_FLOW(("cocoaViewMakeCurrentContext: pView=%p pCtx=%p\n", (void *)pView, (void *)pCtx));
@@ -2995,6 +3007,16 @@ void cocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLContextRef
     }
     else
     {
+#ifdef IN_VMSVGA3D
+        /* Always flush before flush. glXMakeCurrent and wglMakeCurrent does this
+           implicitly, seemingly NSOpenGLContext::makeCurrentContext doesn't. */
+        if ([NSOpenGLContext currentContext] != nil)
+        {
+            DEBUG_CLEAR_GL_ERRORS();
+            glFlush();
+            DEBUG_CHECK_GL_ERROR("glFlush");
+        }
+#endif
     	[NSOpenGLContext clearCurrentContext];
     }
 
@@ -3002,6 +3024,8 @@ void cocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLContextRef
     COCOA_LOG_FLOW(("cocoaViewMakeCurrentContext: returns\n"));
 }
 
+#ifndef IN_VMSVGA3D
+
 GLboolean cocoaViewNeedsEmptyPresent(NativeNSViewRef pView)
 {
     COCOA_LOG_FLOW(("cocoaViewNeedsEmptyPresent: pView=%p\n", (void *)pView));
@@ -3025,6 +3049,7 @@ void cocoaViewSetVisibleRegion(NativeNSViewRef pView, GLint cRects, const GLint
     COCOA_LOG_FLOW(("cocoaViewSetVisibleRegion: returns\n"));
 }
 
+#endif /* IN_VMSVGA3D */
 
 #ifdef IN_VMSVGA3D
 /*
@@ -3045,13 +3070,7 @@ VMSVGA3D_DECL(void) vmsvga3dCocoaDestroyContext(NativeNSOpenGLContextRef pCtx)
 
 VMSVGA3D_DECL(void) vmsvga3dCocoaCreateView(NativeNSViewRef *ppView, NativeNSViewRef pParentView)
 {
-    /** @todo share WinInfo with caller and maintain it better. */
-    WindowInfo *pWinInfo = (WindowInfo *)RTMemAllocZ(sizeof(WindowInfo));
-    AssertLogRelReturnVoid(pWinInfo);
-    pWinInfo->cRefs = 1;
-    RTCritSectInit(&pWinInfo->CompositorLock);
-
-    cocoaViewCreate(ppView, pWinInfo, pParentView, 0 /* fVisParams - ignored */);
+    cocoaViewCreate(ppView, NULL, pParentView, 0 /* fVisParams - ignored */);
 }
 
 VMSVGA3D_DECL(void) vmsvga3dCocoaDestroyView(NativeNSViewRef pView)
@@ -3071,6 +3090,7 @@ VMSVGA3D_DECL(void) vmsvga3dCocoaViewSetSize(NativeNSViewRef pView, int w, int h
 
 VMSVGA3D_DECL(void) vmsvga3dCocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx)
 {
+    Assert(!pView || [(OverlayView *)pView glCtx] == pCtx || [(OverlayView *)pView glCtx] == nil);
     cocoaViewMakeCurrentContext(pView, pCtx);
 }
 
diff --git a/src/VBox/Main/include/NetworkServiceRunner.h b/src/VBox/Main/include/NetworkServiceRunner.h
index f0ec275..0d37fb6 100644
--- a/src/VBox/Main/include/NetworkServiceRunner.h
+++ b/src/VBox/Main/include/NetworkServiceRunner.h
@@ -36,10 +36,9 @@ public:
 
     int setOption(const std::string& key, const std::string& val);
 
-    int start();
-    int stop();
+    int  start(bool aKillProcOnStop);
+    int  stop();
     bool isRunning();
-
     void detachFromServer();
 
     static const std::string kNsrKeyName;
diff --git a/src/VBox/Main/src-all/DisplayUtils.cpp b/src/VBox/Main/src-all/DisplayUtils.cpp
index 70e1555..078961a 100644
--- a/src/VBox/Main/src-all/DisplayUtils.cpp
+++ b/src/VBox/Main/src-all/DisplayUtils.cpp
@@ -162,8 +162,9 @@ int readSavedGuestScreenInfo(const Utf8Str &strStateFilePath, uint32_t u32Screen
         vrc = SSMR3Seek(pSSM, "DisplayData", 0 /*iInstance*/, &uVersion);
         if (RT_SUCCESS(vrc))
         {
-            if (   uVersion == sSSMDisplayVer2
-                || uVersion == sSSMDisplayVer3)
+            /* Starting from sSSMDisplayVer2 we have pu32Width and pu32Height.
+             * Starting from sSSMDisplayVer3 we have all the rest of parameters we need. */
+            if (uVersion >= sSSMDisplayVer2)
             {
                 uint32_t cMonitors;
                 SSMR3GetU32(pSSM, &cMonitors);
@@ -185,7 +186,6 @@ int readSavedGuestScreenInfo(const Utf8Str &strStateFilePath, uint32_t u32Screen
                     }
                     else
                     {
-                        Assert(uVersion == sSSMDisplayVer3);
                         /* Skip all previous monitors, each 8 uint32_t, and the first 3 uint32_t entries. */
                         SSMR3Skip(pSSM, u32ScreenId * 8 * sizeof(uint32_t) + 3 * sizeof(uint32_t));
                         SSMR3GetU32(pSSM, pu32Width);
diff --git a/src/VBox/Main/src-client/ConsoleImpl.cpp b/src/VBox/Main/src-client/ConsoleImpl.cpp
index f1df733..88a44c7 100644
--- a/src/VBox/Main/src-client/ConsoleImpl.cpp
+++ b/src/VBox/Main/src-client/ConsoleImpl.cpp
@@ -10625,7 +10625,10 @@ DECLCALLBACK(int) Console::drvStatus_MediumEjected(PPDMIMEDIANOTIFY pInterface,
                     ComPtr<IMediumAttachment> pNewMediumAtt;
                     rc = pThis->pConsole->mControl->EjectMedium(pMediumAtt, pNewMediumAtt.asOutParam());
                     if (SUCCEEDED(rc))
+                    {
+                        pThis->pConsole->mMachine->SaveSettings();
                         fireMediumChangedEvent(pThis->pConsole->mEventSource, pNewMediumAtt);
+                    }
 
                     alock.acquire();
                     if (pNewMediumAtt != pMediumAtt)
diff --git a/src/VBox/Main/src-client/DisplayImpl.cpp b/src/VBox/Main/src-client/DisplayImpl.cpp
index b5ab211..2aa362a 100644
--- a/src/VBox/Main/src-client/DisplayImpl.cpp
+++ b/src/VBox/Main/src-client/DisplayImpl.cpp
@@ -627,6 +627,10 @@ HRESULT Display::init(Console *aParent)
     ULONG ul;
     mParent->machine()->COMGETTER(MonitorCount)(&ul);
     mcMonitors = ul;
+    xInputMappingOrigin = 0;
+    yInputMappingOrigin = 0;
+    cxInputMapping = 0;
+    cyInputMapping = 0;
 
     for (ul = 0; ul < mcMonitors; ul++)
     {
diff --git a/src/VBox/Main/src-server/DHCPServerImpl.cpp b/src/VBox/Main/src-server/DHCPServerImpl.cpp
index 93eea8f..c9ed096 100644
--- a/src/VBox/Main/src-server/DHCPServerImpl.cpp
+++ b/src/VBox/Main/src-server/DHCPServerImpl.cpp
@@ -39,13 +39,17 @@ const std::string DHCPServerRunner::kDsrKeyUpperIp = "--upper-ip";
 
 struct DHCPServer::Data
 {
-    Data() : enabled(FALSE) {}
+    Data()
+        : enabled(FALSE)
+        , router(false)
+    {}
 
     Bstr IPAddress;
     Bstr lowerIP;
     Bstr upperIP;
 
     BOOL enabled;
+    bool router;
     DHCPServerRunner dhcp;
 
     DhcpOptionMap GlobalDhcpOptions;
@@ -54,7 +58,8 @@ struct DHCPServer::Data
 
 
 DHCPServer::DHCPServer()
-  : m(NULL), mVirtualBox(NULL)
+  : m(NULL)
+  , mVirtualBox(NULL)
 {
     m = new DHCPServer::Data();
 }
@@ -428,7 +433,10 @@ STDMETHODIMP DHCPServer::AddGlobalOption(DhcpOpt_T aOption, IN_BSTR aValue)
 
     /* Indirect way to understand that we're on NAT network */
     if (aOption == DhcpOpt_Router)
+    {
         m->dhcp.setOption(NetworkServiceRunner::kNsrKeyNeedMain, "on");
+        m->router = true;
+    }
 
     alock.release();
 
@@ -653,7 +661,7 @@ STDMETHODIMP DHCPServer::Start(IN_BSTR aNetworkName, IN_BSTR aTrunkName, IN_BSTR
     m->dhcp.setOption(DHCPServerRunner::kDsrKeyUpperIp, Utf8Str(m->upperIP).c_str());
 
     /* XXX: This parameters Dhcp Server will fetch via API */
-    return RT_FAILURE(m->dhcp.start()) ? E_FAIL : S_OK;
+    return RT_FAILURE(m->dhcp.start(!m->router /* KillProcOnExit */)) ? E_FAIL : S_OK;
     //m->dhcp.detachFromServer(); /* need to do this to avoid server shutdown on runner destruction */
 }
 
diff --git a/src/VBox/Main/src-server/HostDnsService.cpp b/src/VBox/Main/src-server/HostDnsService.cpp
index 9138762..3479694 100644
--- a/src/VBox/Main/src-server/HostDnsService.cpp
+++ b/src/VBox/Main/src-server/HostDnsService.cpp
@@ -92,13 +92,11 @@ inline static void detachVectorOfString(const std::vector<std::string>& v,
 struct HostDnsMonitor::Data
 {
     Data(bool aThreaded) :
-        fInfoModified(false),
         fThreaded(aThreaded)
     {}
 
     std::vector<PCHostDnsMonitorProxy> proxies;
     HostDnsInformation info;
-    bool fInfoModified;
     const bool fThreaded;
     RTTHREAD hMonitoringThread;
     RTSEMEVENT hDnsInitEvent;
@@ -203,30 +201,18 @@ const HostDnsInformation &HostDnsMonitor::getInfo() const
     return m->info;
 }
 
-void HostDnsMonitor::notifyAll() const
-{
-    ALock l(this);
-    if (m->fInfoModified)
-    {
-        m->fInfoModified = false;
-        std::vector<PCHostDnsMonitorProxy>::const_iterator it;
-        for (it = m->proxies.begin(); it != m->proxies.end(); ++it)
-            (*it)->notify();
-    }
-}
-
 void HostDnsMonitor::setInfo(const HostDnsInformation &info)
 {
     ALock l(this);
-    // Check for actual modifications, as the Windows specific code seems to
-    // often set the same information as before, without any change to the
-    // previous state. Here we have the previous state, so make sure we don't
-    // ever tell our clients about unchanged info.
+
     if (info.equals(m->info))
-    {
-        m->info = info;
-        m->fInfoModified = true;
-    }
+        return;
+
+    m->info = info;
+
+    std::vector<PCHostDnsMonitorProxy>::const_iterator it;
+    for (it = m->proxies.begin(); it != m->proxies.end(); ++it)
+        (*it)->notify();
 }
 
 HRESULT HostDnsMonitor::init()
@@ -299,7 +285,7 @@ HRESULT HostDnsMonitorProxy::GetNameServers(ComSafeArrayOut(BSTR, aNameServers))
         updateInfo();
 
     LogRel(("HostDnsMonitorProxy::GetNameServers:\n"));
-    dumpHostDnsStrVector("Name Server", m->info->servers);
+    dumpHostDnsStrVector("name server", m->info->servers);
 
     detachVectorOfString(m->info->servers, ComSafeArrayOutArg(aNameServers));
 
@@ -314,7 +300,8 @@ HRESULT HostDnsMonitorProxy::GetDomainName(BSTR *aDomainName)
     if (m->fModified)
         updateInfo();
 
-    LogRel(("HostDnsMonitorProxy::GetDomainName: %s\n", m->info->domain.c_str()));
+    LogRel(("HostDnsMonitorProxy::GetDomainName: %s\n",
+            m->info->domain.empty() ? "no domain set" : m->info->domain.c_str()));
 
     Utf8Str(m->info->domain.c_str()).cloneTo(aDomainName);
 
@@ -330,7 +317,7 @@ HRESULT HostDnsMonitorProxy::GetSearchStrings(ComSafeArrayOut(BSTR, aSearchStrin
         updateInfo();
 
     LogRel(("HostDnsMonitorProxy::GetSearchStrings:\n"));
-    dumpHostDnsStrVector("Search String", m->info->searchList);
+    dumpHostDnsStrVector("search string", m->info->searchList);
 
     detachVectorOfString(m->info->searchList, ComSafeArrayOutArg(aSearchStrings));
 
@@ -371,11 +358,13 @@ void HostDnsMonitorProxy::updateInfo()
 
 static void dumpHostDnsInformation(const HostDnsInformation& info)
 {
-    dumpHostDnsStrVector("DNS server", info.servers);
-    dumpHostDnsStrVector("SearchString", info.searchList);
+    dumpHostDnsStrVector("server", info.servers);
+    dumpHostDnsStrVector("search string", info.searchList);
 
     if (!info.domain.empty())
-        LogRel(("DNS domain: %s\n", info.domain.c_str()));
+        LogRel(("  domain: %s\n", info.domain.c_str()));
+    else
+        LogRel(("  no domain set\n"));
 }
 
 
@@ -385,5 +374,7 @@ static void dumpHostDnsStrVector(const std::string& prefix, const std::vector<st
     for (std::vector<std::string>::const_iterator it = v.begin();
          it != v.end();
          ++it, ++i)
-        LogRel(("%s %d: %s\n", prefix.c_str(), i, it->c_str()));
+        LogRel(("  %s %d: %s\n", prefix.c_str(), i, it->c_str()));
+    if (v.empty())
+        LogRel(("  no %s entries\n", prefix.c_str()));
 }
diff --git a/src/VBox/Main/src-server/HostDnsService.h b/src/VBox/Main/src-server/HostDnsService.h
index 48d7c62..2b3df73 100644
--- a/src/VBox/Main/src-server/HostDnsService.h
+++ b/src/VBox/Main/src-server/HostDnsService.h
@@ -83,7 +83,6 @@ class HostDnsMonitor : public Lockee
     explicit HostDnsMonitor(bool fThreaded = false);
     virtual ~HostDnsMonitor();
 
-    void notifyAll() const;
     void setInfo(const HostDnsInformation &);
 
     /* this function used only if HostDnsMonitor::HostDnsMonitor(true) */
diff --git a/src/VBox/Main/src-server/NATNetworkImpl.cpp b/src/VBox/Main/src-server/NATNetworkImpl.cpp
index 6532725..1ca6e65 100644
--- a/src/VBox/Main/src-server/NATNetworkImpl.cpp
+++ b/src/VBox/Main/src-server/NATNetworkImpl.cpp
@@ -945,7 +945,7 @@ STDMETHODIMP NATNetwork::Start(IN_BSTR aTrunkType)
         }
     }
 
-    if (RT_SUCCESS(m->NATRunner.start()))
+    if (RT_SUCCESS(m->NATRunner.start(false /* KillProcOnStop */)))
     {
         mVirtualBox->onNATNetworkStartStop(mName.raw(), TRUE);
         return S_OK;
@@ -962,14 +962,14 @@ STDMETHODIMP NATNetwork::Start(IN_BSTR aTrunkType)
 STDMETHODIMP NATNetwork::Stop()
 {
 #ifdef VBOX_WITH_NAT_SERVICE
+    mVirtualBox->onNATNetworkStartStop(mName.raw(), FALSE);
+
     if (!m->dhcpServer.isNull())
         m->dhcpServer->Stop();
 
     if (RT_SUCCESS(m->NATRunner.stop()))
-    {
-        mVirtualBox->onNATNetworkStartStop(mName.raw(), FALSE);
         return S_OK;
-    }
+
     /** @todo missing setError()! */
     return E_FAIL;
 #else
diff --git a/src/VBox/Main/src-server/NetworkServiceRunner.cpp b/src/VBox/Main/src-server/NetworkServiceRunner.cpp
index 14610e5..7cd03ca 100644
--- a/src/VBox/Main/src-server/NetworkServiceRunner.cpp
+++ b/src/VBox/Main/src-server/NetworkServiceRunner.cpp
@@ -21,29 +21,35 @@
 #include <iprt/process.h>
 #include <iprt/param.h>
 #include <iprt/env.h>
+#include <iprt/log.h>
+#include <iprt/thread.h>
 
 
-const std::string NetworkServiceRunner::kNsrKeyName = "--name";
-const std::string NetworkServiceRunner::kNsrKeyNetwork = "--network";
+const std::string NetworkServiceRunner::kNsrKeyName      = "--name";
+const std::string NetworkServiceRunner::kNsrKeyNetwork   = "--network";
 const std::string NetworkServiceRunner::kNsrKeyTrunkType = "--trunk-type";
-const std::string NetworkServiceRunner::kNsrTrunkName = "--trunk-name";
-const std::string NetworkServiceRunner::kNsrMacAddress = "--mac-address";
-const std::string NetworkServiceRunner::kNsrIpAddress = "--ip-address";
-const std::string NetworkServiceRunner::kNsrIpNetmask = "--netmask";
-const std::string NetworkServiceRunner::kNsrKeyNeedMain = "--need-main";
+const std::string NetworkServiceRunner::kNsrTrunkName    = "--trunk-name";
+const std::string NetworkServiceRunner::kNsrMacAddress   = "--mac-address";
+const std::string NetworkServiceRunner::kNsrIpAddress    = "--ip-address";
+const std::string NetworkServiceRunner::kNsrIpNetmask    = "--netmask";
+const std::string NetworkServiceRunner::kNsrKeyNeedMain  = "--need-main";
 
 struct NetworkServiceRunner::Data
 {
-    Data(const char* aProcName):mProcName(aProcName), mProcess(NIL_RTPROCESS){}
+    Data(const char* aProcName)
+        : mProcName(aProcName)
+        , mProcess(NIL_RTPROCESS)
+        , mKillProcOnStop(false)
+    {}
     const char *mProcName;
     RTPROCESS mProcess;
     std::map<std::string, std::string> mOptions;
+    bool mKillProcOnStop;
 };
 
 NetworkServiceRunner::NetworkServiceRunner(const char *aProcName)
 {
     m = new NetworkServiceRunner::Data(aProcName);
-
 }
 
 
@@ -68,7 +74,7 @@ void NetworkServiceRunner::detachFromServer()
 }
 
 
-int NetworkServiceRunner::start()
+int NetworkServiceRunner::start(bool aKillProcOnStop)
 {
     if (isRunning())
         return VINF_ALREADY_INITIALIZED;
@@ -107,19 +113,49 @@ int NetworkServiceRunner::start()
     if (RT_FAILURE(rc))
         m->mProcess = NIL_RTPROCESS;
 
+    m->mKillProcOnStop = aKillProcOnStop;
     return rc;
 }
 
 
 int NetworkServiceRunner::stop()
 {
+    /*
+     * If the process already terminated, this function will also grab the exit
+     * status and transition the process out of zombie status.
+     */
     if (!isRunning())
         return VINF_OBJECT_DESTROYED;
 
-    int rc = RTProcTerminate(m->mProcess);
-    RTProcWait(m->mProcess, RTPROCWAIT_FLAGS_BLOCK, NULL);
+    bool fDoKillProc = true;
+
+    if (!m->mKillProcOnStop)
+    {
+        /*
+         * This is a VBoxSVC Main client. Do NOT kill it but assume it was shut
+         * down politely. Wait up to 1 second until the process is killed before
+         * doing the final hard kill.
+         */
+        int rc = VINF_SUCCESS;
+        for (unsigned int i = 0; i < 100; i++)
+        {
+            rc = RTProcWait(m->mProcess, RTPROCWAIT_FLAGS_NOBLOCK, NULL);
+            if (RT_SUCCESS(rc))
+                break;
+            RTThreadSleep(10);
+        }
+        if (rc != VERR_PROCESS_RUNNING)
+            fDoKillProc = false;
+    }
+
+    if (fDoKillProc)
+    {
+        int rc = RTProcTerminate(m->mProcess);
+        rc = RTProcWait(m->mProcess, RTPROCWAIT_FLAGS_BLOCK, NULL);
+    }
+
     m->mProcess = NIL_RTPROCESS;
-    return rc;
+    return VINF_SUCCESS;
 }
 
 bool NetworkServiceRunner::isRunning()
diff --git a/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp b/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp
index dc384da..026ca96 100644
--- a/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp
+++ b/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp
@@ -78,7 +78,6 @@ void HostDnsServiceDarwin::hostDnsServiceStoreCallback(void *, void *, void *inf
 
     ALock l(pThis);
     pThis->updateInfo();
-    pThis->notifyAll();
 }
 
 
diff --git a/src/VBox/Main/src-server/linux/HostDnsServiceLinux.cpp b/src/VBox/Main/src-server/linux/HostDnsServiceLinux.cpp
index 77e8dd9..e49d9c3 100644
--- a/src/VBox/Main/src-server/linux/HostDnsServiceLinux.cpp
+++ b/src/VBox/Main/src-server/linux/HostDnsServiceLinux.cpp
@@ -152,8 +152,6 @@ int HostDnsServiceLinux::monitorWorker()
                 if (combo.e.mask & IN_CLOSE_WRITE)
                 {
                     readResolvConf();
-                    /* notifyAll() takes required locks */
-                    notifyAll();
                 }
                 else if (combo.e.mask & IN_DELETE_SELF)
                 {
@@ -213,8 +211,6 @@ int HostDnsServiceLinux::monitorWorker()
 
                         /* Notify our listeners */
                         readResolvConf();
-                        notifyAll();
-
                     }
                 }
             }
diff --git a/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp b/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp
index b6599ec..5f4bd13 100644
--- a/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp
+++ b/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp
@@ -156,7 +156,6 @@ int HostDnsServiceWin::monitorWorker()
         if (dwReady == WAIT_OBJECT_0 + DATA_DNS_UPDATE_EVENT)
         {
             updateInfo();
-            notifyAll();
 
             ResetEvent(m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
             registerNotification(m->hKeyTcpipParameters,
diff --git a/src/VBox/NetworkServices/DHCP/Config.cpp b/src/VBox/NetworkServices/DHCP/Config.cpp
index 840d3bb..8ffe2e8 100644
--- a/src/VBox/NetworkServices/DHCP/Config.cpp
+++ b/src/VBox/NetworkServices/DHCP/Config.cpp
@@ -218,7 +218,6 @@ int ConfigurationManager::loadFromFile(const com::Utf8Str& leaseStorageFileName)
     /* XXX: version check */
     xml::NodesLoop leases(*root);
 
-    bool valueExists;
     const xml::ElementNode *lease;
     while ((lease = leases.forAllNodes()))
     {
@@ -1413,28 +1412,38 @@ Lease::Lease(ClientData *pd):m(SharedPtr<ClientData>(pd)){}
 
 bool Lease::toXML(xml::ElementNode *node) const
 {
-    bool valueAddition = node->setAttribute(tagXMLLeaseAttributeMac.c_str(), com::Utf8StrFmt("%RTmac", &m->m_mac));
-    if (!valueAddition) return false;
-
-    valueAddition = node->setAttribute(tagXMLLeaseAttributeNetwork.c_str(), com::Utf8StrFmt("%RTnaipv4", m->m_network));
-    if (!valueAddition) return false;
-
-    xml::ElementNode *address = node->createChild(tagXMLLeaseAddress.c_str());
-    if (!address) return false;
-
-    valueAddition = address->setAttribute(tagXMLAddressAttributeValue.c_str(), com::Utf8StrFmt("%RTnaipv4", m->m_address));
-    if (!valueAddition) return false;
-
-    xml::ElementNode *time = node->createChild(tagXMLLeaseTime.c_str());
-    if (!time) return false;
-
-    valueAddition = time->setAttribute(tagXMLTimeAttributeIssued.c_str(),
-                                       m->u64TimestampLeasingStarted);
-    if (!valueAddition) return false;
-
-    valueAddition = time->setAttribute(tagXMLTimeAttributeExpiration.c_str(),
-                                       m->u32LeaseExpirationPeriod);
-    if (!valueAddition) return false;
+    xml::AttributeNode *pAttribNode = node->setAttribute(tagXMLLeaseAttributeMac.c_str(),
+                                                         com::Utf8StrFmt("%RTmac", &m->m_mac));
+    if (!pAttribNode)
+        return false;
+
+    pAttribNode = node->setAttribute(tagXMLLeaseAttributeNetwork.c_str(),
+                                     com::Utf8StrFmt("%RTnaipv4", m->m_network));
+    if (!pAttribNode)
+        return false;
+
+    xml::ElementNode *pLeaseAddress = node->createChild(tagXMLLeaseAddress.c_str());
+    if (!pLeaseAddress)
+        return false;
+
+    pAttribNode = pLeaseAddress->setAttribute(tagXMLAddressAttributeValue.c_str(),
+                                              com::Utf8StrFmt("%RTnaipv4", m->m_address));
+    if (!pAttribNode)
+        return false;
+
+    xml::ElementNode *pLeaseTime = node->createChild(tagXMLLeaseTime.c_str());
+    if (!pLeaseTime)
+        return false;
+
+    pAttribNode = pLeaseTime->setAttribute(tagXMLTimeAttributeIssued.c_str(),
+                                           m->u64TimestampLeasingStarted);
+    if (!pAttribNode)
+        return false;
+
+    pAttribNode = pLeaseTime->setAttribute(tagXMLTimeAttributeExpiration.c_str(),
+                                           m->u32LeaseExpirationPeriod);
+    if (!pAttribNode)
+        return false;
 
     return true;
 }
diff --git a/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp b/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp
index 4dcad96..9c91a11 100644
--- a/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp
+++ b/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp
@@ -522,6 +522,7 @@ int VBoxNetDhcp::initWithMain()
 
     ComEventTypeArray aVBoxEvents;
     aVBoxEvents.push_back(VBoxEventType_OnHostNameResolutionConfigurationChange);
+    aVBoxEvents.push_back(VBoxEventType_OnNATNetworkStartStop);
     rc = createNatListener(m_vboxListener, virtualbox, this, aVBoxEvents);
     AssertRCReturn(rc, rc);
 
@@ -599,6 +600,16 @@ HRESULT VBoxNetDhcp::HandleEvent(VBoxEventType_T aEventType, IEvent *pEvent)
         case VBoxEventType_OnHostNameResolutionConfigurationChange:
             fetchAndUpdateDnsInfo();
             break;
+
+        case VBoxEventType_OnNATNetworkStartStop:
+        {
+            ComPtr <INATNetworkStartStopEvent> pStartStopEvent = pEvent;
+            BOOL fStart = TRUE;
+            HRESULT hrc = pStartStopEvent->COMGETTER(StartEvent)(&fStart);
+            if (!fStart)
+                shutdown();
+            break;
+        }
     }
 
     return S_OK;
diff --git a/src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp b/src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp
index 01ee26e..8ce95fd 100644
--- a/src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp
+++ b/src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp
@@ -388,6 +388,16 @@ HRESULT VBoxNetLwipNAT::HandleEvent(VBoxEventType_T aEventType,
             }
             break;
         }
+
+        case VBoxEventType_OnNATNetworkStartStop:
+        {
+            ComPtr <INATNetworkStartStopEvent> pStartStopEvent = pEvent;
+            BOOL fStart = TRUE;
+            hrc = pStartStopEvent->COMGETTER(StartEvent)(&fStart);
+            if (!fStart)
+                shutdown();
+            break;
+        }
     }
     return hrc;
 }
@@ -783,6 +793,7 @@ int VBoxNetLwipNAT::init()
 
     ComEventTypeArray aVBoxEvents;
     aVBoxEvents.push_back(VBoxEventType_OnHostNameResolutionConfigurationChange);
+    aVBoxEvents.push_back(VBoxEventType_OnNATNetworkStartStop);
     rc = createNatListener(m_vboxListener, virtualbox, this, aVBoxEvents);
     AssertRCReturn(rc, rc);
 
diff --git a/src/VBox/NetworkServices/NetLib/ComHostUtils.cpp b/src/VBox/NetworkServices/NetLib/ComHostUtils.cpp
index 3345236..5b455fd 100644
--- a/src/VBox/NetworkServices/NetLib/ComHostUtils.cpp
+++ b/src/VBox/NetworkServices/NetLib/ComHostUtils.cpp
@@ -78,12 +78,12 @@ int localMappings(const ComNatPtr& nat, AddressToOffsetMapping& mapping)
     mapping.clear();
 
     ComBstrArray strs;
-    int cStrs;
+    size_t cStrs;
     HRESULT hrc = nat->COMGETTER(LocalMappings)(ComSafeArrayAsOutParam(strs));
     if (   SUCCEEDED(hrc)
         && (cStrs = strs.size()))
     {
-        for (int i = 0; i < cStrs; ++i)
+        for (size_t i = 0; i < cStrs; ++i)
         {
             char szAddr[17];
             RTNETADDRIPV4 ip4addr;
diff --git a/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp b/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
index 917547c..b12ca1f 100644
--- a/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
+++ b/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
@@ -182,7 +182,7 @@ VBoxNetBaseService::~VBoxNetBaseService()
             CloseReq.pSession = m->m_pSession;
             CloseReq.hIf = m->m_hIf;
             m->m_hIf = INTNET_HANDLE_INVALID;
-            int rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_RTCPUID, VMMR0_DO_INTNET_IF_CLOSE, 0, &CloseReq.Hdr);
+            int rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_CLOSE, 0, &CloseReq.Hdr);
             AssertRC(rc);
         }
 
@@ -455,20 +455,27 @@ int VBoxNetBaseService::tryGoOnline(void)
 void VBoxNetBaseService::shutdown(void)
 {
     syncEnter();
-    m->fShutdown = true;
-    if (m->m_hThrRecv != NIL_RTTHREAD)
+    if (! m->fShutdown)
     {
-        int rc = m->m_EventQ->interruptEventQueueProcessing();
-        if (RT_SUCCESS(rc))
+        m->fShutdown = true;
+        if (m->m_hThrRecv != NIL_RTTHREAD)
         {
-            rc = RTThreadWait(m->m_hThrRecv, 60000, NULL);
-            if (RT_FAILURE(rc))
-                LogWarningFunc(("RTThreadWait(%RTthrd) -> %Rrc\n", m->m_hThrRecv, rc));
-        }
-        else
-        {
-            AssertMsgFailed(("interruptEventQueueProcessing() failed\n"));
-            RTThreadWait(m->m_hThrRecv , 0, NULL);
+            int rc = abortWait();
+            Assert(rc == VINF_SUCCESS || rc == VERR_SEM_DESTROYED);
+            rc = m->m_EventQ->interruptEventQueueProcessing();
+#if 0 /* this will not work as long as we don't set RTTHREADFLAGS_WAITABLE */
+            if (RT_SUCCESS(rc))
+            {
+                rc = RTThreadWait(m->m_hThrRecv, 60000, NULL);
+                if (RT_FAILURE(rc))
+                    LogWarningFunc(("RTThreadWait(%RTthrd) -> %Rrc\n", m->m_hThrRecv, rc));
+            }
+            else
+            {
+                AssertMsgFailed(("interruptEventQueueProcessing() failed\n"));
+                RTThreadWait(m->m_hThrRecv , 0, NULL);
+            }
+#endif
         }
     }
     syncLeave();
@@ -489,7 +496,6 @@ int VBoxNetBaseService::syncLeave()
 
 int VBoxNetBaseService::waitForIntNetEvent(int cMillis)
 {
-    int rc = VINF_SUCCESS;
     INTNETIFWAITREQ WaitReq;
     LogFlowFunc(("ENTER:cMillis: %d\n", cMillis));
     WaitReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
@@ -498,11 +504,28 @@ int VBoxNetBaseService::waitForIntNetEvent(int cMillis)
     WaitReq.hIf = m->m_hIf;
     WaitReq.cMillies = cMillis;
 
-    rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_WAIT, 0, &WaitReq.Hdr);
+    int rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_WAIT, 0, &WaitReq.Hdr);
     LogFlowFuncLeaveRC(rc);
     return rc;
 }
 
+
+int VBoxNetBaseService::abortWait()
+{
+    INTNETIFABORTWAITREQ AbortReq;
+    LogFlowFunc(("ENTER:\n"));
+    AbortReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
+    AbortReq.Hdr.cbReq = sizeof(AbortReq);
+    AbortReq.pSession = m->m_pSession;
+    AbortReq.hIf = m->m_hIf;
+    AbortReq.fNoMoreWaits = true;
+
+    int rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_ABORT_WAIT, 0, &AbortReq.Hdr);
+    LogFlowFuncLeaveRC(rc);
+    return rc;
+}
+
+
 /* S/G API */
 int VBoxNetBaseService::sendBufferOnWire(PCINTNETSEG pcSg, int cSg, size_t cbFrame)
 {
@@ -533,13 +556,12 @@ int VBoxNetBaseService::sendBufferOnWire(PCINTNETSEG pcSg, int cSg, size_t cbFra
  */
 void VBoxNetBaseService::flushWire()
 {
-    int rc = VINF_SUCCESS;
     INTNETIFSENDREQ SendReq;
     SendReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     SendReq.Hdr.cbReq    = sizeof(SendReq);
     SendReq.pSession     = m->m_pSession;
     SendReq.hIf          = m->m_hIf;
-    rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_SEND, 0, &SendReq.Hdr);
+    int rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_SEND, 0, &SendReq.Hdr);
     AssertRCReturnVoid(rc);
     LogFlowFuncLeave();
 
@@ -671,6 +693,8 @@ void VBoxNetBaseService::doReceiveLoop()
          */
         /* 2. waiting for request for */
         rc = waitForIntNetEvent(2000);
+        if (rc == VERR_SEM_DESTROYED)
+            break;
         if (RT_FAILURE(rc))
         {
             if (rc == VERR_TIMEOUT || rc == VERR_INTERRUPTED)
@@ -732,7 +756,6 @@ void VBoxNetBaseService::doReceiveLoop()
 
         } /* loop */
     }
-
 }
 
 
diff --git a/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.h b/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.h
index a551bc8..7e98c4c 100644
--- a/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.h
+++ b/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.h
@@ -68,6 +68,7 @@ public:
     int                 syncEnter();
     int                 syncLeave();
     int                 waitForIntNetEvent(int cMillis);
+    int                 abortWait();
     int                 sendBufferOnWire(PCINTNETSEG pSg, int cSg, size_t cbBuffer);
     void                flushWire();
 
diff --git a/src/VBox/NetworkServices/NetLib/utils.h b/src/VBox/NetworkServices/NetLib/utils.h
index d96b5c0..dbf5252 100644
--- a/src/VBox/NetworkServices/NetLib/utils.h
+++ b/src/VBox/NetworkServices/NetLib/utils.h
@@ -39,7 +39,7 @@ inline bool isDhcpRequired(const ComNatPtr& nat)
     if (FAILED(nat->COMGETTER(NeedDhcpServer)(&fNeedDhcpServer)))
         return false;
 
-    return fNeedDhcpServer;
+    return RT_BOOL(fNeedDhcpServer);
 }
 
 
diff --git a/src/VBox/RDP/client/Makefile.in b/src/VBox/RDP/client/Makefile.in
index d61607b..5d0a94f 100644
--- a/src/VBox/RDP/client/Makefile.in
+++ b/src/VBox/RDP/client/Makefile.in
@@ -18,7 +18,7 @@ CC          = @CC@
 INSTALL     = @INSTALL@
 CFLAGS      = @CFLAGS@ @X_CFLAGS@ @DEFS@ -Iinclude -DKEYMAP_PATH=\"$(KEYMAP_PATH)\" -DWITH_RDPUSB=1 -DRDESKTOP -DVBOX -DIN_RING3 -DRT_OS_LINUX -DLOG_DISABLED -DRTLOG_REL_DISABLED -DVBOX_USB_WITH_SYSFS
 CXXFLAGS    = @CXXFLAGS@ @DEFS@ -Iinclude -DKEYMAP_PATH=\"$(KEYMAP_PATH)\" -DWITH_RDPUSB=1 -DRDESKTOP -DVBOX -DIN_RING3 -DRT_OS_LINUX -DLOG_DISABLED -DRTLOG_REL_DISABLED -DVBOX_USB_WITH_SYSFS
-LDFLAGS     = @LDFLAGS@ @LIBS@ @X_LIBS@ @X_EXTRA_LIBS@
+LDFLAGS     = @LDFLAGS@ @LIBS@ @X_LIBS@ @X_EXTRA_LIBS@ -lpthread -ldl
 STRIP       = @STRIP@
 
 TARGETS     = rdesktop @RDP2VNCTARGET@
@@ -28,7 +28,7 @@ VNCLINK     = @VNCLINK@
 SOUNDOBJ    = @SOUNDOBJ@
 SCARDOBJ    = @SCARDOBJ@
 
-RDPOBJ   = tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o rdp5.o channels.o rdpdr.o serial.o printer.o disk.o parallel.o printercache.o mppc.o pstcache.o lspci.o seamless.o ssl.o Runtime/common/alloc/alloc.o Runtime/common/err/errmsg.o Runtime/common/err/errmsgxpcom.o Runtime/common/err/RTErrConvertFromErrno.o Runtime/common/err/RTErrConvertToErrno.o Runtime/common/misc/sg.o Runtime/common/path/RTPathAppend.o Runtime/common/path/RTPathAppendEx.o Runtime/common/path/ [...]
+RDPOBJ   = tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o rdp5.o channels.o rdpdr.o serial.o printer.o disk.o parallel.o printercache.o mppc.o pstcache.o lspci.o seamless.o ssl.o Runtime/common/alloc/alloc.o Runtime/common/err/errmsg.o Runtime/common/err/errmsgxpcom.o Runtime/common/err/RTErrConvertFromErrno.o Runtime/common/err/RTErrConvertToErrno.o Runtime/common/misc/sg.o Runtime/common/path/RTPathAppend.o Runtime/common/path/RTPathAppendEx.o Runtime/common/path/ [...]
 X11OBJ   = rdesktop.o xwin.o xkeymap.o ewmhints.o xclip.o cliprdr.o
 VNCOBJ   = vnc/rdp2vnc.o vnc/vnc.o vnc/xkeymap.o vnc/x11stubs.o
 
diff --git a/src/VBox/RDP/client/Makefile.kmk b/src/VBox/RDP/client/Makefile.kmk
index abb1fbe..d87da24 100644
--- a/src/VBox/RDP/client/Makefile.kmk
+++ b/src/VBox/RDP/client/Makefile.kmk
@@ -350,6 +350,7 @@ rdesktop-src_SOURCES = \
 	$(PATH_ROOT)/src/VBox/Runtime/common/string/utf-8-case.cpp=>Runtime/common/string/utf-8-case.cpp \
 	$(PATH_ROOT)/src/VBox/Runtime/common/time/timesysalias.cpp=>Runtime/common/time/timesysalias.cpp \
 	$(PATH_ROOT)/src/VBox/Runtime/generic/pathhost-generic.cpp=>Runtime/generic/pathhost-generic.cpp \
+	$(PATH_ROOT)/src/VBox/Runtime/generic/RTPathAbs-generic.cpp=>Runtime/generic/RTPathAbs-generic.cpp \
 	$(PATH_ROOT)/src/VBox/Runtime/include/internal/alignmentchecks.h=>include/internal/alignmentchecks.h \
 	$(PATH_ROOT)/src/VBox/Runtime/include/internal/dir.h=>include/internal/dir.h \
 	$(PATH_ROOT)/src/VBox/Runtime/include/internal/file.h=>include/internal/file.h \
diff --git a/src/VBox/RDP/client/vrdp/rdpusb.c b/src/VBox/RDP/client/vrdp/rdpusb.c
index 0f88d64..a0886ee 100644
--- a/src/VBox/RDP/client/vrdp/rdpusb.c
+++ b/src/VBox/RDP/client/vrdp/rdpusb.c
@@ -97,6 +97,9 @@ typedef struct _DevListEntry
 } DevListEntry;
 #pragma pack ()
 
+/**
+ * @returns VBox status code.
+ */
 static inline int op_usbproxy_back_open(PUSBPROXYDEV p, const char *pszAddress)
 {
      return g_USBProxyDeviceHost.pfnOpen (p, pszAddress, NULL);
@@ -107,31 +110,49 @@ static inline void op_usbproxy_back_close(PUSBPROXYDEV pDev)
      return g_USBProxyDeviceHost.pfnClose (pDev);
 }
 
+/**
+ * @returns VBox status code.
+ */
 static inline int op_usbproxy_back_reset(PUSBPROXYDEV pDev)
 {
     return g_USBProxyDeviceHost.pfnReset (pDev, false);
 }
 
+/**
+ * @returns VBox status code.
+ */
 static inline int op_usbproxy_back_set_config(PUSBPROXYDEV pDev, int cfg)
 {
     return g_USBProxyDeviceHost.pfnSetConfig (pDev, cfg);
 }
 
+/**
+ * @returns VBox status code.
+ */
 static inline int op_usbproxy_back_claim_interface(PUSBPROXYDEV pDev, int ifnum)
 {
     return g_USBProxyDeviceHost.pfnClaimInterface (pDev, ifnum);
 }
 
+/**
+ * @returns VBox status code.
+ */
 static inline int op_usbproxy_back_release_interface(PUSBPROXYDEV pDev, int ifnum)
 {
     return g_USBProxyDeviceHost.pfnReleaseInterface (pDev, ifnum);
 }
 
+/**
+ * @returns VBox status code.
+ */
 static inline int op_usbproxy_back_interface_setting(PUSBPROXYDEV pDev, int ifnum, int setting)
 {
     return g_USBProxyDeviceHost.pfnSetInterface (pDev, ifnum, setting);
 }
 
+/**
+ * @returns VBox status code.
+ */
 static inline int op_usbproxy_back_queue_urb(PUSBPROXYDEV pDev, PVUSBURB pUrb)
 {
     return g_USBProxyDeviceHost.pfnUrbQueue(pDev, pUrb);
@@ -142,11 +163,17 @@ static inline PVUSBURB op_usbproxy_back_reap_urb(PUSBPROXYDEV pDev, unsigned cMi
     return g_USBProxyDeviceHost.pfnUrbReap (pDev, cMillies);
 }
 
-static inline bool op_usbproxy_back_clear_halted_ep(PUSBPROXYDEV pDev, unsigned EndPoint)
+/**
+ * @returns VBox status code.
+ */
+static inline int op_usbproxy_back_clear_halted_ep(PUSBPROXYDEV pDev, unsigned EndPoint)
 {
     return g_USBProxyDeviceHost.pfnClearHaltedEndpoint (pDev, EndPoint);
 }
 
+/**
+ * @returns VBox status code.
+ */
 static inline int op_usbproxy_back_cancel_urb(PUSBPROXYDEV pDev, PVUSBURB pUrb)
 {
     return g_USBProxyDeviceHost.pfnUrbCancel (pDev, pUrb);
@@ -470,6 +497,8 @@ rdpusb_process(STREAM s)
 				return;
 			}
 
+			memset (proxy, 0, sizeof (USBPROXYDEV));
+
 			proxy->pvInstanceDataR3 = xmalloc(g_USBProxyDeviceHost.cbBackend);
 			if (!proxy->pvInstanceDataR3)
 			{
@@ -477,8 +506,6 @@ rdpusb_process(STREAM s)
 				return;
 			}
 
-			memset (proxy, 0, sizeof (USBPROXYDEV));
-
 			proxy->Dev.pszName = "Remote device";
 			proxy->devid = devid;
 
@@ -550,7 +577,6 @@ rdpusb_process(STREAM s)
 			}
 
 			rc = op_usbproxy_back_reset(proxy);
-
 			if (rc != VINF_SUCCESS)
 			{
 				rdpusb_send_reply (code, vrdp_usb_status (!rc, &proxy->Dev), devid);
@@ -573,8 +599,7 @@ rdpusb_process(STREAM s)
 	        	in_uint8(s, cfg);
 
 			rc = op_usbproxy_back_set_config(proxy, cfg);
-
-			if (!rc)
+			if (RT_FAILURE(rc))
 			{
 				rdpusb_send_reply (code, vrdp_usb_status (rc, &proxy->Dev), devid);
 			}
@@ -594,10 +619,10 @@ rdpusb_process(STREAM s)
 			}
 
 	        	in_uint8(s, ifnum);
+				in_uint8(s, ifnum);
 
 			rc = op_usbproxy_back_claim_interface(proxy, ifnum);
-
-			if (!rc)
+			if (RT_FAILURE(rc))
 			{
 				rdpusb_send_reply (code, vrdp_usb_status (rc, &proxy->Dev), devid);
 			}
@@ -619,8 +644,7 @@ rdpusb_process(STREAM s)
 	        	in_uint8(s, ifnum);
 
 			rc = op_usbproxy_back_release_interface(proxy, ifnum);
-
-			if (!rc)
+			if (RT_FAILURE(rc))
 			{
 				rdpusb_send_reply (code, vrdp_usb_status (rc, &proxy->Dev), devid);
 			}
@@ -644,8 +668,7 @@ rdpusb_process(STREAM s)
 	        	in_uint8(s, setting);
 
 			rc = op_usbproxy_back_interface_setting(proxy, ifnum, setting);
-
-			if (!rc)
+			if (RT_FAILURE(rc))
 			{
 				rdpusb_send_reply (code, vrdp_usb_status (rc, &proxy->Dev), devid);
 			}
@@ -702,7 +725,7 @@ rdpusb_process(STREAM s)
 
 			/* No reply required. */
 
-			if (rc)
+			if (RT_SUCCESS(rc))
 			{
 				if (proxy->pUrbs)
 				{
@@ -739,8 +762,7 @@ rdpusb_process(STREAM s)
 	        	in_uint8(s, ep);
 
 			rc = op_usbproxy_back_clear_halted_ep(proxy, ep);
-
-			if (!rc)
+			if (RT_FAILURE(rc))
 			{
 				rdpusb_send_reply (code, vrdp_usb_status (rc, &proxy->Dev), devid);
 			}
diff --git a/src/VBox/Runtime/common/string/strformatrt.cpp b/src/VBox/Runtime/common/string/strformatrt.cpp
index 3d08799..d96ef98 100644
--- a/src/VBox/Runtime/common/string/strformatrt.cpp
+++ b/src/VBox/Runtime/common/string/strformatrt.cpp
@@ -1166,6 +1166,7 @@ DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, co
                         REG_OUT_BIT(cr4, X86_CR4_PCIDE, "PCIDE");
                         REG_OUT_BIT(cr4, X86_CR4_OSXSAVE, "OSXSAVE");
                         REG_OUT_BIT(cr4, X86_CR4_SMEP, "SMEP");
+// XXX                  REG_OUT_BIT(cr4, X86_CR4_SMAP, "SMAP");
                         REG_OUT_CLOSE(cr4);
                     }
                     else
diff --git a/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h b/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
index a1791ee..086ade0 100644
--- a/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
+++ b/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
@@ -140,6 +140,11 @@
 # include <linux/kthread.h>
 #endif
 
+/* for cr4_init_shadow() / cpu_tlbstate. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 20, 0)
+# include <asm/tlbflush.h>
+#endif
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
 # ifndef page_to_pfn
 #  define page_to_pfn(page) ((page) - mem_map)
diff --git a/src/VBox/VMM/VMMR0/HMVMXR0.cpp b/src/VBox/VMM/VMMR0/HMVMXR0.cpp
index 26e6107..714022c 100644
--- a/src/VBox/VMM/VMMR0/HMVMXR0.cpp
+++ b/src/VBox/VMM/VMMR0/HMVMXR0.cpp
@@ -759,14 +759,13 @@ static int hmR0VmxEnterRootMode(PVM pVM, RTHCPHYS HCPhysCpuPage, void *pvCpuPage
     RTCCUINTREG uEflags = ASMIntDisableFlags();
 
     /* Enable the VMX bit in CR4 if necessary. */
-    RTCCUINTREG uCr4 = ASMGetCR4();
-    if (!(uCr4 & X86_CR4_VMXE))
-        ASMSetCR4(uCr4 | X86_CR4_VMXE);
+    RTCCUINTREG uOldCr4 = SUPR0ChangeCR4(X86_CR4_VMXE, ~0);
 
     /* Enter VMX root mode. */
     int rc = VMXEnable(HCPhysCpuPage);
-    if (RT_FAILURE(rc))
-        ASMSetCR4(uCr4);
+    if (   RT_FAILURE(rc)
+        && !(uOldCr4 & X86_CR4_VMXE))
+        SUPR0ChangeCR4(0, ~X86_CR4_VMXE);
 
     /* Restore interrupts. */
     ASMSetFlags(uEflags);
@@ -794,7 +793,7 @@ static int hmR0VmxLeaveRootMode(void)
     {
         /* Exit VMX root mode and clear the VMX bit in CR4. */
         VMXDisable();
-        ASMSetCR4(uHostCR4 & ~X86_CR4_VMXE);
+        SUPR0ChangeCR4(0, ~X86_CR4_VMXE);
         rc = VINF_SUCCESS;
     }
     else
@@ -4850,7 +4849,7 @@ VMMR0DECL(int) VMXR0Execute64BitsHandler(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, H
     /* Leave VMX Root Mode. */
     VMXDisable();
 
-    ASMSetCR4(ASMGetCR4() & ~X86_CR4_VMXE);
+    SUPR0ChangeCR4(0, ~X86_CR4_VMXE);
 
     CPUMSetHyperESP(pVCpu, VMMGetStackRC(pVCpu));
     CPUMSetHyperEIP(pVCpu, enmOp);
@@ -4865,13 +4864,13 @@ VMMR0DECL(int) VMXR0Execute64BitsHandler(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, H
 
     /** @todo replace with hmR0VmxEnterRootMode() and hmR0VmxLeaveRootMode(). */
     /* Make sure the VMX instructions don't cause #UD faults. */
-    ASMSetCR4(ASMGetCR4() | X86_CR4_VMXE);
+    SUPR0ChangeCR4(X86_CR4_VMXE, ~0);
 
     /* Re-enter VMX Root Mode */
     rc2 = VMXEnable(HCPhysCpuPage);
     if (RT_FAILURE(rc2))
     {
-        ASMSetCR4(ASMGetCR4() & ~X86_CR4_VMXE);
+        SUPR0ChangeCR4(0, ~X86_CR4_VMXE);
         ASMSetFlags(uOldEflags);
         return rc2;
     }
diff --git a/src/VBox/VMM/VMMR3/CPUM.cpp b/src/VBox/VMM/VMMR3/CPUM.cpp
index 8434d25..6897764 100644
--- a/src/VBox/VMM/VMMR3/CPUM.cpp
+++ b/src/VBox/VMM/VMMR3/CPUM.cpp
@@ -3863,8 +3863,8 @@ static DECLCALLBACK(void) cpumR3CpuIdInfo(PVM pVM, PCDBGFINFOHLP pHlp, const cha
             if (uECX & RT_BIT(26))  pHlp->pfnPrintf(pHlp, " XSAVE");
             if (uECX & RT_BIT(27))  pHlp->pfnPrintf(pHlp, " OSXSAVE");
             if (uECX & RT_BIT(28))  pHlp->pfnPrintf(pHlp, " AVX");
-            if (uECX & RT_BIT(29))  pHlp->pfnPrintf(pHlp, " 29");
-            if (uECX & RT_BIT(30))  pHlp->pfnPrintf(pHlp, " 30");
+            if (uECX & RT_BIT(29))  pHlp->pfnPrintf(pHlp, " F16C");
+            if (uECX & RT_BIT(30))  pHlp->pfnPrintf(pHlp, " RDRAND");
             if (uECX & RT_BIT(31))  pHlp->pfnPrintf(pHlp, " HVP");
             pHlp->pfnPrintf(pHlp, "\n");
         }
@@ -3940,7 +3940,8 @@ static DECLCALLBACK(void) cpumR3CpuIdInfo(PVM pVM, PCDBGFINFOHLP pHlp, const cha
             pHlp->pfnPrintf(pHlp, "XSAVE/XRSTOR extended state feature    = %d (%d)\n",  EcxGuest.u1XSAVE,      EcxHost.u1XSAVE);
             pHlp->pfnPrintf(pHlp, "Supports OSXSAVE                       = %d (%d)\n",  EcxGuest.u1OSXSAVE,    EcxHost.u1OSXSAVE);
             pHlp->pfnPrintf(pHlp, "AVX instruction extensions             = %d (%d)\n",  EcxGuest.u1AVX,        EcxHost.u1AVX);
-            pHlp->pfnPrintf(pHlp, "29/30 - Reserved                       = %#x (%#x)\n",EcxGuest.u2Reserved3,  EcxHost.u2Reserved3);
+            pHlp->pfnPrintf(pHlp, "16-bit floating point conversion instr = %d (%d)\n",  EcxGuest.u1F16C,       EcxHost.u1F16C);
+            pHlp->pfnPrintf(pHlp, "RDRAND instruction                     = %d (%d)\n",  EcxGuest.u1RDRAND,     EcxHost.u1RDRAND);
             pHlp->pfnPrintf(pHlp, "Hypervisor Present (we're a guest)     = %d (%d)\n",  EcxGuest.u1HVP,        EcxHost.u1HVP);
         }
     }
diff --git a/src/VBox/VMM/VMMR3/PGMPhys.cpp b/src/VBox/VMM/VMMR3/PGMPhys.cpp
index 80b10ec..682d7ee 100644
--- a/src/VBox/VMM/VMMR3/PGMPhys.cpp
+++ b/src/VBox/VMM/VMMR3/PGMPhys.cpp
@@ -2222,7 +2222,7 @@ VMMR3DECL(int) PGMR3PhysMMIORegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb,
                 AssertLogRelMsgReturnStmt(   PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_RAM
                                           || PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_MMIO,
                                           ("%RGp-%RGp (MMIO/%s): %RGp is not a RAM or MMIO page - type=%d desc=%s\n",
-                                           GCPhys, GCPhysLast, pszDesc, PGM_PAGE_GET_TYPE(pPage), pRam->pszDesc),
+                                           GCPhys, GCPhysLast, pszDesc, pRam->GCPhys, PGM_PAGE_GET_TYPE(pPage), pRam->pszDesc),
                                           pgmUnlock(pVM),
                                           VERR_PGM_RAM_CONFLICT);
                 pPage++;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-virtualbox/virtualbox.git



More information about the Pkg-virtualbox-commits mailing list