Index: /trunk/include/VBox/Graphics/VBoxVideoGuest.h
===================================================================
--- /trunk/include/VBox/Graphics/VBoxVideoGuest.h	(revision 71145)
+++ /trunk/include/VBox/Graphics/VBoxVideoGuest.h	(revision 71146)
@@ -126,4 +126,6 @@
 
 DECLHIDDEN(uint32_t) VBoxHGSMIGetMonitorCount(PHGSMIGUESTCOMMANDCONTEXT pCtx);
+DECLHIDDEN(bool)     VBoxVGACfgAvailable(void);
+DECLHIDDEN(bool)     VBoxVGACfgQuery(uint16_t u16Id, uint32_t *pu32Value);
 DECLHIDDEN(uint32_t) VBoxVideoGetVRAMSize(void);
 DECLHIDDEN(bool)     VBoxVideoAnyWidthAllowed(void);
Index: /trunk/include/VBox/Graphics/VBoxVideoVBE.h
===================================================================
--- /trunk/include/VBox/Graphics/VBoxVideoVBE.h	(revision 71145)
+++ /trunk/include/VBox/Graphics/VBoxVideoVBE.h	(revision 71146)
@@ -50,4 +50,5 @@
 #define VBE_DISPI_IOPORT_DAC_DATA         0x03C9
 
+/* Cross reference with src/VBox/Devices/Graphics/DevVGA.h */
 #define VBE_DISPI_INDEX_ID              0x0
 #define VBE_DISPI_INDEX_XRES            0x1
@@ -62,4 +63,5 @@
 #define VBE_DISPI_INDEX_VBOX_VIDEO      0xa
 #define VBE_DISPI_INDEX_FB_BASE_HI      0xb
+#define VBE_DISPI_INDEX_CFG             0xc
 
 #define VBE_DISPI_ID0                   0xB0C0
@@ -73,4 +75,5 @@
 #define VBE_DISPI_ID_HGSMI              0xBE01
 #define VBE_DISPI_ID_ANYX               0xBE02
+#define VBE_DISPI_ID_CFG                0xBE03 /* VBE_DISPI_INDEX_CFG is available. */
 
 #define VBE_DISPI_DISABLED              0x00
@@ -83,4 +86,15 @@
 #define VBE_DISPI_NOCLEARMEM            0x80
 
+/* VBE_DISPI_INDEX_CFG content. */
+#define VBE_DISPI_CFG_MASK_ID           0x0FFF /* Identifier of a configuration value. */
+#define VBE_DISPI_CFG_MASK_SUPPORT      0x1000 /* Query whether the identifier is supported. */
+#define VBE_DISPI_CFG_MASK_RESERVED     0xE000 /* For future extensions. Must be 0. */
+
+/* VBE_DISPI_INDEX_CFG values. */
+#define VBE_DISPI_CFG_ID_VERSION        0x0000 /* Version of the configuration interface. */
+#define VBE_DISPI_CFG_ID_VRAM_SIZE      0x0001 /* VRAM size. */
+#define VBE_DISPI_CFG_ID_3D             0x0002 /* 3D support. */
+#define VBE_DISPI_CFG_ID_VMSVGA         0x0003 /* VMSVGA FIFO and ports are available. */
+
 #define VGA_PORT_HGSMI_HOST             0x3b0
 #define VGA_PORT_HGSMI_GUEST            0x3d0
Index: /trunk/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp	(revision 71145)
+++ /trunk/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp	(revision 71146)
@@ -59,4 +59,43 @@
 
 /**
+ * Query whether the virtual hardware supports VBE_DISPI_ID_CFG
+ * and set the interface.
+ *
+ * @returns Whether the interface is supported.
+ */
+DECLHIDDEN(bool) VBoxVGACfgAvailable(void)
+{
+    VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
+    VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_CFG);
+    const uint16_t DispiId = VBVO_PORT_READ_U16(VBE_DISPI_IOPORT_DATA);
+    return (DispiId == VBE_DISPI_ID_CFG);
+}
+
+
+/**
+ * Query a configuration value from the virtual hardware which supports VBE_DISPI_ID_CFG.
+ * I.e. use this function only if VBoxVGACfgAvailable returns true.
+ *
+ * @returns Whether the value is supported.
+ * @param  u16Id     Identifier of the configuration value (VBE_DISPI_CFG_ID_*).
+ * @param  pu32Value Where to store value from the host.
+ */
+DECLHIDDEN(bool) VBoxVGACfgQuery(uint16_t u16Id, uint32_t *pu32Value)
+{
+    VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_CFG);
+    VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_DATA, VBE_DISPI_CFG_MASK_SUPPORT | u16Id);
+    const uint32_t u32 = VBVO_PORT_READ_U32(VBE_DISPI_IOPORT_DATA);
+    if (u32)
+    {
+        VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_DATA, u16Id);
+        *pu32Value = VBVO_PORT_READ_U32(VBE_DISPI_IOPORT_DATA);
+        return true;
+    }
+
+    return false;
+}
+
+
+/**
  * Returns the size of the video RAM in bytes.
  *
@@ -65,5 +104,5 @@
 DECLHIDDEN(uint32_t) VBoxVideoGetVRAMSize(void)
 {
-    /** @note A 32bit read on this port returns the VRAM size. */
+    /** @note A 32bit read on this port returns the VRAM size if interface is older than VBE_DISPI_ID_CFG. */
     return VBVO_PORT_READ_U32(VBE_DISPI_IOPORT_DATA);
 }
Index: /trunk/src/VBox/Devices/Graphics/DevVGA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 71145)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 71146)
@@ -847,4 +847,26 @@
 
 #ifdef CONFIG_BOCHS_VBE
+
+static uint32_t vbe_read_cfg(PVGASTATE pThis)
+{
+    const uint16_t u16Cfg = pThis->vbe_regs[VBE_DISPI_INDEX_CFG];
+    const uint16_t u16Id = u16Cfg & VBE_DISPI_CFG_MASK_ID;
+    const bool fQuerySupport = RT_BOOL(u16Cfg & VBE_DISPI_CFG_MASK_SUPPORT);
+
+    switch (u16Id)
+    {
+        case VBE_DISPI_CFG_ID_VERSION:
+           return fQuerySupport ? 1 : 0;
+        case VBE_DISPI_CFG_ID_VRAM_SIZE: 
+           return fQuerySupport ? 1 : pThis->vram_size;
+        case VBE_DISPI_CFG_ID_3D:
+           return fQuerySupport ? 1 : pThis->f3DEnabled;
+        case VBE_DISPI_CFG_ID_VMSVGA:
+           return fQuerySupport ? 1 : pThis->fVMSVGAEnabled;
+        default:
+           return 0; /* Not supported. */
+    }
+}
+
 static uint32_t vbe_ioport_read_index(PVGASTATE pThis, uint32_t addr)
 {
@@ -883,4 +905,7 @@
               val = 1;
               break;
+          case VBE_DISPI_INDEX_CFG:
+              val = vbe_read_cfg(pThis);
+              break;
           default:
               Assert(pThis->vbe_index < VBE_DISPI_INDEX_NB);
@@ -985,17 +1010,15 @@
                 val == VBE_DISPI_ID2 ||
                 val == VBE_DISPI_ID3 ||
-                val == VBE_DISPI_ID4) {
+                val == VBE_DISPI_ID4 ||
+                /* VBox extensions. */
+                val == VBE_DISPI_ID_VBOX_VIDEO ||
+                val == VBE_DISPI_ID_ANYX       ||
+#ifdef VBOX_WITH_HGSMI
+                val == VBE_DISPI_ID_HGSMI      ||
+#endif
+                val == VBE_DISPI_ID_CFG)
+            {
                 pThis->vbe_regs[pThis->vbe_index] = val;
             }
-            if (val == VBE_DISPI_ID_VBOX_VIDEO) {
-                pThis->vbe_regs[pThis->vbe_index] = val;
-            } else if (val == VBE_DISPI_ID_ANYX) {
-                pThis->vbe_regs[pThis->vbe_index] = val;
-            }
-#ifdef VBOX_WITH_HGSMI
-            else if (val == VBE_DISPI_ID_HGSMI) {
-                pThis->vbe_regs[pThis->vbe_index] = val;
-            }
-#endif /* VBOX_WITH_HGSMI */
             break;
         case VBE_DISPI_INDEX_XRES:
@@ -1181,4 +1204,7 @@
 #endif /* IN_RING3 */
             break;
+        case VBE_DISPI_INDEX_CFG:
+            pThis->vbe_regs[pThis->vbe_index] = val;
+            break;
         default:
             break;
@@ -2753,7 +2779,8 @@
     SSMR3PutU32(pSSM, pThis->bank_offset);
 #ifdef CONFIG_BOCHS_VBE
-    SSMR3PutU8(pSSM, 1);
+    AssertCompile(RT_ELEMENTS(pThis->vbe_regs) < 256);
+    SSMR3PutU8(pSSM, (uint8_t)RT_ELEMENTS(pThis->vbe_regs));
     SSMR3PutU16(pSSM, pThis->vbe_index);
-    for(i = 0; i < VBE_DISPI_INDEX_NB_SAVED; i++)
+    for(i = 0; i < RT_ELEMENTS(pThis->vbe_regs); i++)
         SSMR3PutU16(pSSM, pThis->vbe_regs[i]);
     SSMR3PutU32(pSSM, pThis->vbe_start_addr);
@@ -2801,6 +2828,15 @@
         return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
     }
+
+    if (u8 == 1)
+        u8 = VBE_DISPI_INDEX_NB_SAVED; /* Used to save so many registers. */
+    if (u8 > RT_ELEMENTS(pThis->vbe_regs))
+    {
+        Log(("vga_load: saved %d, expected %d!!\n", u8, RT_ELEMENTS(pThis->vbe_regs)));
+        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
+    }
+
     SSMR3GetU16(pSSM, &pThis->vbe_index);
-    for(i = 0; i < VBE_DISPI_INDEX_NB_SAVED; i++)
+    for(i = 0; i < (int)u8; i++)
         SSMR3GetU16(pSSM, &pThis->vbe_regs[i]);
     if (version_id <= VGA_SAVEDSTATE_VERSION_INV_VHEIGHT)
@@ -3005,5 +3041,4 @@
     Assert(PDMCritSectIsOwner(pDevIns->CTX_SUFF(pCritSectRo)));
 
-
 #ifdef VBE_BYTEWISE_IO
     if (cb == 1)
@@ -3027,6 +3062,8 @@
     if (cb == 4)
     {
-        /* Quick hack for getting the vram size. */
-        *pu32 = pThis->vram_size;
+        if (pThis->vbe_regs[VBE_DISPI_INDEX_ID] == VBE_DISPI_ID_CFG)
+            *pu32 = vbe_ioport_read_data(pThis, Port); /* New interface. */
+        else
+            *pu32 = pThis->vram_size; /* Quick hack for getting the vram size. */
         return VINF_SUCCESS;
     }
@@ -6175,4 +6212,5 @@
 #endif
                                           "SuppressNewYearSplash\0"
+                                          "3DEnabled\0"
                                           ))
         return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
@@ -6203,4 +6241,7 @@
     AssertLogRelRCReturn(rc, rc);
     Log(("VGA: VRamSize=%#x fGCenabled=%RTbool fR0Enabled=%RTbool\n", pThis->vram_size, pThis->fGCEnabled, pThis->fR0Enabled));
+
+    rc = CFGMR3QueryBoolDef(pCfg, "3DEnabled", &pThis->f3DEnabled, false);
+    AssertLogRelRCReturn(rc, rc);
 
 #ifdef VBOX_WITH_VMSVGA
Index: /trunk/src/VBox/Devices/Graphics/DevVGA.h
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA.h	(revision 71145)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA.h	(revision 71146)
@@ -79,11 +79,11 @@
 
 /* Cross reference with <VBoxVideoVBE.h> */
-#define VBE_DISPI_INDEX_NB_SAVED        0xb /* Number of saved registers (vbe_regs array) */
-#define VBE_DISPI_INDEX_NB              0xc /* Total number of VBE registers */
+#define VBE_DISPI_INDEX_NB_SAVED        0xb /* Old number of saved registers (vbe_regs array, see vga_load) */
+#define VBE_DISPI_INDEX_NB              0xd /* Total number of VBE registers */
 
 #define VGA_STATE_COMMON_BOCHS_VBE              \
     uint16_t vbe_index;                         \
     uint16_t vbe_regs[VBE_DISPI_INDEX_NB];      \
-    uint16_t alignment[3]; /* pad to 64 bits */ \
+    uint16_t alignment[2]; /* pad to 64 bits */ \
     uint32_t vbe_start_addr;                    \
     uint32_t vbe_line_offset;                   \
@@ -338,10 +338,12 @@
     /** Whether to render the guest VRAM to the framebuffer memory. False only for some LFB modes. */
     bool                        fRenderVRAM;
+    /** Whether 3D is enabled for the VM. */
+    bool                        f3DEnabled;
 # ifdef VBOX_WITH_VMSVGA
     /* Whether the SVGA emulation is enabled or not. */
     bool                        fVMSVGAEnabled;
+    bool                        Padding4[0+4];
+# else
     bool                        Padding4[1+4];
-# else
-    bool                        Padding4[2+4];
 # endif
 
Index: /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 71145)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 71146)
@@ -3720,4 +3720,7 @@
         NOREF(fHMEnabled);
 #endif
+        BOOL f3DEnabled;
+        hrc = ptrMachine->COMGETTER(Accelerate3DEnabled)(&f3DEnabled);                      H();
+        InsertConfigInteger(pCfg,  "3DEnabled",            f3DEnabled);
 
         i_attachStatusDriver(pInst, &mapCrOglLed, 0, 0, NULL, NULL, 0);
@@ -3739,6 +3742,4 @@
                 pFramebuffer->Release();
             }
-            BOOL f3DEnabled;
-            hrc = ptrMachine->COMGETTER(Accelerate3DEnabled)(&f3DEnabled);                  H();
             InsertConfigInteger(pCfg, "VMSVGA3dEnabled", f3DEnabled);
 #else
