Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp	(revision 53754)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp	(revision 53755)
@@ -2579,5 +2579,5 @@
                         SVGA3dCmdDefineContext *pCmd = (SVGA3dCmdDefineContext *)(pHdr + 1);
 
-                        rc = vmsvga3dContextDefine(pThis, pCmd->cid, false /*fLegacy*/);
+                        rc = vmsvga3dContextDefine(pThis, pCmd->cid, false /*fOtherProfile*/);
                         break;
                     }
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.h
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.h	(revision 53754)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.h	(revision 53755)
@@ -35,5 +35,6 @@
 #endif
 
-VMSVGA3D_DECL(void) vmsvga3dCocoaCreateContext(NativeNSOpenGLContextRef *ppCtx, NativeNSOpenGLContextRef pSharedCtx, bool fLegacy);
+VMSVGA3D_DECL(void) vmsvga3dCocoaCreateContext(NativeNSOpenGLContextRef *ppCtx, NativeNSOpenGLContextRef pSharedCtx,
+                                               bool fOtherProfile);
 VMSVGA3D_DECL(void) vmsvga3dCocoaDestroyContext(NativeNSOpenGLContextRef pCtx);
 VMSVGA3D_DECL(void) vmsvga3dCocoaCreateView(NativeNSViewRef *ppView, NativeNSViewRef pParentView);
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.m
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.m	(revision 53754)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.m	(revision 53755)
@@ -623,5 +623,5 @@
 
 
-void vmsvga3dCocoaCreateContext(NativeNSOpenGLContextRef *ppCtx, NativeNSOpenGLContextRef pShareCtx, bool fLegacy)
+void vmsvga3dCocoaCreateContext(NativeNSOpenGLContextRef *ppCtx, NativeNSOpenGLContextRef pShareCtx, bool fOtherProfile)
 {
     DEBUG_FUNC_ENTER();
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp	(revision 53754)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp	(revision 53755)
@@ -88,9 +88,4 @@
 #include <float.h>
 
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
-# define VBOX_D3D9CAPS_ONLY_DEFINES
-# include "shaderlib/wine/include/d3d9caps.h" /* For some capability constants. */
-#endif
-
 
 /* Generated by VBoxDef2LazyLoad from the VBoxSVGA3D.def and VBoxSVGA3DObjC.def files. */
@@ -104,4 +99,8 @@
 *   Defined Constants And Macros                                               *
 *******************************************************************************/
+#ifndef VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE
+# define VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE 1.0
+#endif
+
 #ifdef RT_OS_WINDOWS
 # define OGLGETPROCADDRESS      wglGetProcAddress
@@ -215,17 +214,4 @@
 
 /**
- * Macro wrapping glGetIntegerv for use during initialization.
- * Uses AssertLogRelMsg.
- */
-#define VMSVGA3D_INIT_CHECKED_GL_GET_INTEGER_VALUE(a_enmGlValue, a_pDest) \
-    do \
-    { \
-        glGetIntegerv(a_enmGlValue, a_pDest); \
-        GLenum iGlError = glGetError(); \
-        AssertLogRelMsg(iGlError == GL_NO_ERROR, \
-                        ("VMSVGA3d: glGetIntegerv(" #a_enmGlValue " (%#x),) -> %#x\n", (int)a_enmGlValue, iGlError)); \
-    } while (0)
-
-/**
  * Macro for doing something and then checking for errors during initialization.
  * Uses AssertLogRelMsg.
@@ -238,4 +224,34 @@
         AssertLogRelMsg(iGlError == GL_NO_ERROR, ("VMSVGA3d: %s -> %#x\n", #a_Expr, iGlError)); \
     } while (0)
+
+/**
+ * Macro for doing something and then checking for errors during initialization,
+ * doing the same in the other context when enabled.
+ *
+ * This will try both profiles in dual profile builds.  Caller must be in the
+ * default context.
+ *
+ * Uses AssertLogRelMsg to indicate trouble.
+ */
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+# define VMSVGA3D_INIT_CHECKED_BOTH(a_pState, a_pContext, a_pOtherCtx, a_Expr) \
+    do \
+    { \
+        for (uint32_t i = 0; i < 64; i++) if (glGetError() == GL_NO_ERROR) break; Assert(glGetError() == GL_NO_ERROR); \
+        a_Expr; \
+        GLenum iGlError = glGetError(); \
+        if (iGlError != GL_NO_ERROR) \
+        { \
+            VMSVGA3D_SET_CURRENT_CONTEXT(a_pState, a_pOtherCtx); \
+            for (uint32_t i = 0; i < 64; i++) if (glGetError() == GL_NO_ERROR) break; Assert(glGetError() == GL_NO_ERROR); \
+            a_Expr; \
+            GLenum iGlError2 = glGetError(); \
+            AssertLogRelMsg(iGlError2 == GL_NO_ERROR, ("VMSVGA3d: %s -> %#x / %#x\n", #a_Expr, iGlError, iGlError2)); \
+            VMSVGA3D_SET_CURRENT_CONTEXT(a_pState, a_pContext); \
+        } \
+    } while (0)
+#else
+# define VMSVGA3D_INIT_CHECKED_BOTH(a_pState, a_pContext, a_pOtherCtx, a_Expr) VMSVGA3D_INIT_CHECKED(a_Expr)
+#endif
 
 
@@ -406,5 +422,5 @@
     NativeNSOpenGLContextRef cocoaContext;
     NativeNSViewRef          cocoaView;
-    bool                    fLegacy;
+    bool                    fOtherProfile;
 #else
     /** XGL rendering context handle */
@@ -604,9 +620,20 @@
     uint32_t                idTestContext;
 #endif
-    /** Legacy OpenGL profile GL_EXTENSIONS result (RTStrDup).
+    /** The GL_EXTENSIONS value (space padded) for the default OpenGL profile.
+     * Free with RTStrFree. */
+    R3PTRTYPE(char *)       pszExtensions;
+
+    /** The GL_EXTENSIONS value (space padded) for the other OpenGL profile.
+     * Free with RTStrFree.
+     *
      * This is used to detect shader model version since some implementations
      * (darwin) hides extensions that have made it into core and probably a
      * bunch of others when using a OpenGL core profile instead of a legacy one */
-    R3PTRTYPE(char *)       pszLegacyExtensions;
+    R3PTRTYPE(char *)       pszOtherExtensions;
+    /** The version of the other GL profile. */
+    float                   fOtherGLVersion;
+
+    /** Shader talk back interface. */
+    VBOXVMSVGASHADERIF      ShaderIf;
 } VMSVGA3DSTATE;
 /** Pointer to the VMSVGA3d state. */
@@ -670,146 +697,32 @@
  *
  * @returns true if supported, false if not.
+ * @param   pState              The VMSVGA3d state.
  * @param   fActualGLVersion    The actual OpenGL version we're working against.
  * @param   fMinGLVersion       The OpenGL version that introduced this feature
  *                              into the core.
- * @param   pszWantedExtension  The name of the OpenGL extension we want.
+ * @param   pszWantedExtension  The name of the OpenGL extension we want padded
+ *                              with one space at each end.
  * @remarks Init time only.
  */
-static bool vmsvga3dCheckGLExtension(float fActualGLVersion, float fMinGLVersion, const char *pszWantedExtension)
-{
+static bool vmsvga3dCheckGLExtension(PVMSVGA3DSTATE pState, float fMinGLVersion, const char *pszWantedExtension)
+{
+    /* check padding. */
+    Assert(pszWantedExtension[0] == ' ');
+    Assert(pszWantedExtension[1] != ' ');
+    Assert(strchr(&pszWantedExtension[1], ' ') + 1 == strchr(pszWantedExtension, '\0'));
+
+    /* Look it up. */
     bool fRet = false;
-
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
-    /*
-     * OpenGL 3.2+ core profile (glGetString(GL_EXTENSIONS) returns NULL).
-     * It also avoids listing extensions that have been promoted into the core.
-     */
-
-    /* Seems like extensions are assimilated into the OpenGL core, so we do
-       hardcoded checks for these as per gl3.h. */
-    if (0) { /*nothing*/ }
-    else if (   fActualGLVersion >= 2.0
-             && (   strcmp(pszWantedExtension, "GL_ARB_draw_buffers") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_shader_objects") == 0 /*??*/
-                 || strcmp(pszWantedExtension, "GL_ARB_vertex_shader") == 0 /*??*/
-                 || strcmp(pszWantedExtension, "GL_ARB_fragment_shader") == 0 /*??*/
-                 || strcmp(pszWantedExtension, "GL_ARB_shading_language_100") == 0 /*??*/
-                 || strcmp(pszWantedExtension, "GL_ARB_texture_non_power_of_two") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_point_sprite") == 0
-                 || strcmp(pszWantedExtension, "GL_ATI_separate_stencil") == 0
-                 || strcmp(pszWantedExtension, "GL_EXT_stencil_two_side") == 0) )
+    if (strstr(pState->pszExtensions, pszWantedExtension))
         fRet = true;
-    else if (   fActualGLVersion >= 2.1
-             && (   strcmp(pszWantedExtension, "GL_EXT_texture_sRGB") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_pixel_buffer_object") == 0) )
-        fRet = true;
-    else if (   fActualGLVersion >= 3.0
-             && (   strcmp(pszWantedExtension, "GL_ARB_framebuffer_object") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_map_buffer_range") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_vertex_array_object") == 0) )
-        fRet = true;
-    else if (   fActualGLVersion >= 3.1
-             && (   strcmp(pszWantedExtension, "GL_ARB_copy_buffer") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_uniform_buffer_object") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_vertex_array_object") == 0) )
-        fRet = true;
-    else if (   fActualGLVersion >= 3.2
-             && (   strcmp(pszWantedExtension, "GL_ARB_draw_elements_base_vertex") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_vertex_array_bgra") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_provoking_vertex") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_seamless_cube_map") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_fragment_coord_conventions") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_depth_clamp") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_sync") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_texture_multisample") == 0) )
-        fRet = true;
-    else if (   fActualGLVersion >= 3.3
-             && (   strcmp(pszWantedExtension, "GL_ARB_blend_func_extended") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_sampler_objects") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_explicit_attrib_location") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_occlusion_query2") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_shader_bit_encoding") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_texture_rgb10_a2ui") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_texture_swizzle") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_timer_query") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_vertex_type_2_10_10_10_rev") == 0) )
-        fRet = true;
-    else if (   fActualGLVersion >= 4.0
-             && (   strcmp(pszWantedExtension, "GL_ARB_texture_query_lod") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_draw_indirect") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_gpu_shader5") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_gpu_shader_fp64") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_shader_subroutine") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_tessellation_shader") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_texture_buffer_object_rgb32") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_texture_cube_map_array") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_texture_gather") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_transform_feedback2") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_transform_feedback3") == 0) )
-        fRet = true;
-    else if (   fActualGLVersion >= 4.1
-             && (   strcmp(pszWantedExtension, "GL_ARB_ES2_compatibility") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_get_program_binary") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_separate_shader_objects") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_shader_precision") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_vertex_attrib_64bit") == 0
-                 || strcmp(pszWantedExtension, "GL_ARB_viewport_array") == 0) )
-        fRet = true;
-    else
-    {
-        /* Search the GL_EXTENSIONS array. */
-        static PFNGLGETSTRINGIPROC s_pfnGlGetStringi = NULL;
-        if (!s_pfnGlGetStringi)
-        {
-             s_pfnGlGetStringi = (PFNGLGETSTRINGIPROC)OGLGETPROCADDRESS("glGetStringi");
-             AssertLogRelReturn(s_pfnGlGetStringi, false);
-        }
-
-        GLint cExtensions = 1024;
-        VMSVGA3D_INIT_CHECKED_GL_GET_INTEGER_VALUE(GL_NUM_EXTENSIONS, &cExtensions);
-
-        for (GLint idxCur = 0; idxCur < cExtensions; idxCur++)
-        {
-            const char *pszCur = (const char *)s_pfnGlGetStringi(GL_EXTENSIONS, idxCur);
-            if (pszCur && !strcmp(pszCur, pszWantedExtension))
-            {
-                fRet = true;
-                break;
-            }
-        }
-    }
-#else
-    /*
-     * Old interface.
-     */
-    char *pSupportedExtensions = (char *)glGetString(GL_EXTENSIONS);
-    char *pExtensionSupported  = pSupportedExtensions;
-    size_t cchWantedExtension  = strlen(pszWantedExtension);
-
-    while (true)
-    {
-        pExtensionSupported = strstr(pExtensionSupported, pszWantedExtension);
-        if (pExtensionSupported == NULL)
-            break;
-
-        if (    (    pExtensionSupported == pSupportedExtensions
-                 ||  pExtensionSupported[-1] == ' ')
-            &&  (    pExtensionSupported[cchWantedExtension] == ' '
-                 ||  pExtensionSupported[cchWantedExtension] == '\0')
-           )
-        {
-            fRet = true;
-            break;
-        }
-
-        pExtensionSupported += cchWantedExtension;
-    }
+
+    /* Temporarily.  Later start if (fMinGLVersion != 0.0 && fActualGLVersion >= fMinGLVersion) return true; */
+    AssertMsg(   fMinGLVersion == 0.0
+              || fRet == (pState->fGLVersion >= fMinGLVersion)
+#ifdef RT_OS_DARWIN
+              || VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE == 2.1
 #endif
-
-    /* Temporarily.  Later start if (fMinGLVersion != 0.0 && fActualGLVersion >= fMinGLVersion) return true; */
-#if defined(VBOX_VMSVGA3D_USE_OPENGL_CORE) || !defined(RT_OS_DARWIN)
-    AssertMsg(fMinGLVersion == 0.0 || fRet == (fActualGLVersion >= fMinGLVersion),
-              ("%s actual:%d min:%d\n", pszWantedExtension, (int)(fActualGLVersion * 10), (int)(fMinGLVersion * 10) ));
-#endif
+              , ("%s actual:%d min:%d fRet=%d\n",
+                 pszWantedExtension, (int)(pState->fGLVersion * 10), (int)(fMinGLVersion * 10), fRet));
     return fRet;
 }
@@ -819,30 +732,349 @@
  * Outputs GL_EXTENSIONS list to the release log.
  */
-static void vmsvga3dLogRelExtensions(void)
-{
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
+static void vmsvga3dLogRelExtensions(const char *pszPrefix, const char *pszExtensions)
+{
     /* OpenGL 3.0 interface (glGetString(GL_EXTENSIONS) return NULL). */
-    PFNGLGETSTRINGIPROC pfnGlGetStringi = (PFNGLGETSTRINGIPROC)OGLGETPROCADDRESS("glGetStringi");
-    AssertLogRelReturnVoid(pfnGlGetStringi);
-
     bool fBuffered = RTLogRelSetBuffering(true);
 
-    GLint cExtensions = 1024;
-    VMSVGA3D_INIT_CHECKED_GL_GET_INTEGER_VALUE(GL_NUM_EXTENSIONS, &cExtensions);
-    LogRel(("VMSVGA3d: OpenGL extensions (GL_NUM_EXTENSIONS=%d)", cExtensions));
-
-    for (GLint idxCur = 0; idxCur < cExtensions; idxCur++)
-    {
-        const char *pszExt = (const char *)pfnGlGetStringi(GL_EXTENSIONS, idxCur);
-        const char *pszFmt = idxCur % 3 ? " %-26s" : "\nVMSVGA3d:  %-26s";
-        LogRel((pszFmt, pszExt));
+    /*
+     * Determin the column widths first.
+     */
+    size_t   acchWidths[4] = { 1, 1, 1, 1 };
+    uint32_t i;
+    const char *psz = pszExtensions;
+    for (i = 0; ; i++)
+    {
+        while (*psz == ' ')
+            psz++;
+        if (!*psz)
+            break;
+
+        const char *pszEnd = strchr(psz, ' ');
+        AssertBreak(pszEnd);
+        size_t cch = pszEnd - psz;
+
+        uint32_t iColumn = i % RT_ELEMENTS(acchWidths);
+        if (acchWidths[iColumn] < cch)
+            acchWidths[iColumn] = cch;
+
+        psz = pszEnd;
+    }
+
+    /*
+     * Output it.
+     */
+    LogRel(("VMSVGA3d: %sOpenGL extensions (%d):", pszPrefix, i));
+    psz = pszExtensions;
+    for (i = 0; ; i++)
+    {
+        while (*psz == ' ')
+            psz++;
+        if (!*psz)
+            break;
+
+        const char *pszEnd = strchr(psz, ' ');
+        AssertBreak(pszEnd);
+        size_t cch = pszEnd - psz;
+
+        uint32_t iColumn = i % RT_ELEMENTS(acchWidths);
+        if (iColumn == 0)
+            LogRel(("\nVMSVGA3d:  %-*.*s", acchWidths[iColumn], cch, psz));
+        else if (iColumn != RT_ELEMENTS(acchWidths) - 1)
+            LogRel((" %-*.*s", acchWidths[iColumn], cch, psz));
+        else
+            LogRel((" %.*s", cch, psz));
+
+        psz = pszEnd;
     }
 
     RTLogRelSetBuffering(fBuffered);
     LogRel(("\n"));
+}
+
+/**
+ * Gathers the GL_EXTENSIONS list, storing it as a space padded list at
+ * @a ppszExtensions.
+ *
+ * @returns VINF_SUCCESS or VERR_NO_STR_MEMORY
+ * @param   ppszExtensions      Pointer to the string pointer. Free with RTStrFree.
+ * @param   fGLProfileVersion   The OpenGL profile version.
+ */
+static int vmsvga3dGatherExtensions(char **ppszExtensions, float fGLProfileVersion)
+{
+    int rc;
+    *ppszExtensions = NULL;
+
+    /*
+     * Try the old glGetString interface first.
+     */
+    const char *pszExtensions = (const char *)glGetString(GL_EXTENSIONS);
+    if (pszExtensions)
+    {
+        rc = RTStrAAppendExN(ppszExtensions, 3, " ", (size_t)1, pszExtensions, RTSTR_MAX, " ", (size_t)1);
+        AssertLogRelRCReturn(rc, rc);
+    }
+    else
+    {
+        /*
+         * The new interface where each extension string is retrieved separately.
+         * Note! Cannot use VMSVGA3D_INIT_CHECKED_GL_GET_INTEGER_VALUE here because
+         *       the above GL_EXTENSIONS error lingers on darwin. sucks.
+         */
+#ifndef GL_NUM_EXTENSIONS
+# define GL_NUM_EXTENSIONS 0x821D
+#endif
+        GLint cExtensions = 1024;
+        glGetIntegerv(GL_NUM_EXTENSIONS, &cExtensions);
+        Assert(cExtensions != 1024);
+
+        PFNGLGETSTRINGIPROC pfnGlGetStringi = (PFNGLGETSTRINGIPROC)OGLGETPROCADDRESS("glGetStringi");
+        AssertLogRelReturn(pfnGlGetStringi, VERR_NOT_SUPPORTED);
+
+        rc = RTStrAAppend(ppszExtensions, " ");
+        for (GLint i = 0; RT_SUCCESS(rc) && i < cExtensions; i++)
+        {
+            const char *pszExt = (const char *)pfnGlGetStringi(GL_EXTENSIONS, i);
+            if (pszExt)
+                rc = RTStrAAppendExN(ppszExtensions, 2, pfnGlGetStringi(GL_EXTENSIONS, i), RTSTR_MAX, " ", (size_t)1);
+        }
+        AssertRCReturn(rc, rc);
+    }
+
+#if 1
+    /*
+     * Add extensions promoted into the core OpenGL profile.
+     */
+    static const struct
+    {
+        float fGLVersion;
+        const char *pszzExtensions;
+    } s_aPromotedExtensions[] =
+    {
+        {
+            1.1,
+            " GL_EXT_vertex_array \0"
+            " GL_EXT_polygon_offset \0"
+            " GL_EXT_blend_logic_op \0"
+            " GL_EXT_texture \0"
+            " GL_EXT_copy_texture \0"
+            " GL_EXT_subtexture \0"
+            " GL_EXT_texture_object \0"
+            " GL_ARB_framebuffer_object \0"
+            " GL_ARB_map_buffer_range \0"
+            " GL_ARB_vertex_array_object \0"
+            "\0"
+        },
+        {
+            1.2,
+            " EXT_texture3D \0"
+            " EXT_bgra \0"
+            " EXT_packed_pixels \0"
+            " EXT_rescale_normal \0"
+            " EXT_separate_specular_color \0"
+            " SGIS_texture_edge_clamp \0"
+            " SGIS_texture_lod \0"
+            " EXT_draw_range_elements \0"
+            "\0"
+        },
+        {
+            1.3,
+            " GL_ARB_texture_compression \0"
+            " GL_ARB_texture_cube_map \0"
+            " GL_ARB_multisample \0"
+            " GL_ARB_multitexture \0"
+            " GL_ARB_texture_env_add \0"
+            " GL_ARB_texture_env_combine \0"
+            " GL_ARB_texture_env_dot3 \0"
+            " GL_ARB_texture_border_clamp \0"
+            " GL_ARB_transpose_matrix \0"
+            "\0"
+        },
+        {
+            1.5,
+            " GL_SGIS_generate_mipmap \0"
+            /*" GL_NV_blend_equare \0"*/
+            " GL_ARB_depth_texture \0"
+            " GL_ARB_shadow \0"
+            " GL_EXT_fog_coord \0"
+            " GL_EXT_multi_draw_arrays \0"
+            " GL_ARB_point_parameters \0"
+            " GL_EXT_secondary_color \0"
+            " GL_EXT_blend_func_separate \0"
+            " GL_EXT_stencil_wrap \0"
+            " GL_ARB_texture_env_crossbar \0"
+            " GL_EXT_texture_lod_bias \0"
+            " GL_ARB_texture_mirrored_repeat \0"
+            " GL_ARB_window_pos \0"
+            "\0"
+        },
+        {
+            1.6,
+            " GL_ARB_vertex_buffer_object \0"
+            " GL_ARB_occlusion_query \0"
+            " GL_EXT_shadow_funcs \0"
+        },
+        {
+            2.0,
+            " GL_ARB_shader_objects \0" /*??*/
+            " GL_ARB_vertex_shader \0" /*??*/
+            " GL_ARB_fragment_shader \0" /*??*/
+            " GL_ARB_shading_language_100 \0" /*??*/
+            " GL_ARB_draw_buffers \0"
+            " GL_ARB_texture_non_power_of_two \0"
+            " GL_ARB_point_sprite \0"
+            " GL_ATI_separate_stencil \0"
+            " GL_EXT_stencil_two_side \0"
+            "\0"
+        },
+        {
+            2.1,
+            " GL_ARB_pixel_buffer_object \0"
+            " GL_EXT_texture_sRGB \0"
+            "\0"
+        },
+        {
+            3.0,
+            " GL_ARB_framebuffer_object \0"
+            " GL_ARB_map_buffer_range \0"
+            " GL_ARB_vertex_array_object \0"
+            "\0"
+        },
+        {
+            3.1,
+            " GL_ARB_copy_buffer \0"
+            " GL_ARB_uniform_buffer_object \0"
+            "\0"
+        },
+        {
+            3.2,
+            " GL_ARB_vertex_array_bgra \0"
+            " GL_ARB_draw_elements_base_vertex \0"
+            " GL_ARB_fragment_coord_conventions \0"
+            " GL_ARB_provoking_vertex \0"
+            " GL_ARB_seamless_cube_map \0"
+            " GL_ARB_texture_multisample \0"
+            " GL_ARB_depth_clamp \0"
+            " GL_ARB_sync \0"
+            " GL_ARB_geometry_shader4 \0" /*??*/
+            "\0"
+        },
+        {
+            3.3,
+            " GL_ARB_blend_func_extended \0"
+            " GL_ARB_sampler_objects \0"
+            " GL_ARB_explicit_attrib_location \0"
+            " GL_ARB_occlusion_query2 \0"
+            " GL_ARB_shader_bit_encoding \0"
+            " GL_ARB_texture_rgb10_a2ui \0"
+            " GL_ARB_texture_swizzle \0"
+            " GL_ARB_timer_query \0"
+            " GL_ARB_vertex_type_2_10_10_10_rev \0"
+            "\0"
+        },
+        {
+            4.0,
+            " GL_ARB_texture_query_lod \0"
+            " GL_ARB_draw_indirect \0"
+            " GL_ARB_gpu_shader5 \0"
+            " GL_ARB_gpu_shader_fp64 \0"
+            " GL_ARB_shader_subroutine \0"
+            " GL_ARB_tessellation_shader \0"
+            " GL_ARB_texture_buffer_object_rgb32 \0"
+            " GL_ARB_texture_cube_map_array \0"
+            " GL_ARB_texture_gather \0"
+            " GL_ARB_transform_feedback2 \0"
+            " GL_ARB_transform_feedback3 \0"
+            "\0"
+        },
+        {
+            4.1,
+            " GL_ARB_ES2_compatibility \0"
+            " GL_ARB_get_program_binary \0"
+            " GL_ARB_separate_shader_objects \0"
+            " GL_ARB_shader_precision \0"
+            " GL_ARB_vertex_attrib_64bit \0"
+            " GL_ARB_viewport_array \0"
+            "\0"
+        }
+    };
+
+    uint32_t cPromoted = 0;
+    for (uint32_t i = 0; i < RT_ELEMENTS(s_aPromotedExtensions) && s_aPromotedExtensions[i].fGLVersion <= fGLProfileVersion; i++)
+    {
+        const char *pszExt = s_aPromotedExtensions[i].pszzExtensions;
+        while (*pszExt)
+        {
+            size_t cchExt = strlen(pszExt);
+            Assert(cchExt > 3);
+            Assert(pszExt[0] == ' ');
+            Assert(pszExt[1] != ' ');
+            Assert(pszExt[cchExt - 2] != ' ');
+            Assert(pszExt[cchExt - 1] == ' ');
+
+            if (strstr(*ppszExtensions, pszExt) == NULL)
+            {
+                if (cPromoted++ == 0)
+                {
+                    rc = RTStrAAppend(ppszExtensions, " <promoted-extensions:> <promoted-extensions:> <promoted-extensions:> ");
+                    AssertRCReturn(rc, rc);
+                }
+
+                rc = RTStrAAppend(ppszExtensions, pszExt);
+                AssertRCReturn(rc, rc);
+            }
+
+            pszExt = strchr(pszExt, '\0') + 1;
+        }
+    }
+#endif
+
+    return VINF_SUCCESS;
+}
+
+/**
+ * @interface_method_impl{VBOXVMSVGASHADERIF, pfnSwitchInitProfile}
+ */
+static DECLCALLBACK(void) vmsvga3dShaderIfSwitchInitProfile(PVBOXVMSVGASHADERIF pThis, bool fOtherProfile)
+{
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+    PVMSVGA3DSTATE pState = RT_FROM_MEMBER(pThis, VMSVGA3DSTATE, ShaderIf);
+    VMSVGA3D_SET_CURRENT_CONTEXT(pState, &pState->paContext[fOtherProfile ? 2 : 1]);
 #else
-    /* Old interface. */
-    LogRel(("VMSVGA3d: OpenGL extensions: %s\n\n", glGetString(GL_EXTENSIONS)));
+    NOREF(pThis);
+    NOREF(fOtherProfile);
 #endif
+}
+
+
+/**
+ * @interface_method_impl{VBOXVMSVGASHADERIF, pfnGetNextExtension}
+ */
+static DECLCALLBACK(bool) vmsvga3dShaderIfGetNextExtension(PVBOXVMSVGASHADERIF pThis, void **ppvEnumCtx,
+                                                           char *pszBuf, size_t cbBuf, bool fOtherProfile)
+{
+    PVMSVGA3DSTATE pState = RT_FROM_MEMBER(pThis, VMSVGA3DSTATE, ShaderIf);
+    const char    *pszCur = *ppvEnumCtx ? (const char *)*ppvEnumCtx
+                          : fOtherProfile ? pState->pszOtherExtensions : pState->pszExtensions;
+    while (*pszCur == ' ')
+        pszCur++;
+    if (!*pszCur)
+        return false;
+
+    const char *pszEnd = strchr(pszCur, ' ');
+    AssertReturn(pszEnd, false);
+    size_t cch = pszEnd - pszCur;
+    if (cch < cbBuf)
+    {
+        memcpy(pszBuf, pszCur, cch);
+        pszBuf[cch] = '\0';
+    }
+    else if (cbBuf > 0)
+    {
+        memcpy(pszBuf, "<overflow>", RT_MIN(sizeof("<overflow>"), cbBuf));
+        pszBuf[cbBuf - 1] = '\0';
+    }
+
+    *ppvEnumCtx = (void *)pszEnd;
+    return true;
 }
 
@@ -917,6 +1149,6 @@
     AssertReturn(pThis->svga.p3dState, VERR_NO_MEMORY);
     PVMSVGA3DCONTEXT pContext;
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
-    PVMSVGA3DCONTEXT pLegacyContext;
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+    PVMSVGA3DCONTEXT pOtherCtx;
 #endif
     int              rc;
@@ -924,24 +1156,9 @@
     if (pState->fGLVersion != 0.0)
         return VINF_SUCCESS;    /* already initialized (load state) */
-
-    /*
-     * Initialize the capabilities with sensible defaults.
-     */
-    pState->caps.maxActiveLights               = 1;
-    pState->caps.maxTextureBufferSize          = 65536;
-    pState->caps.maxTextures                   = 1;
-    pState->caps.maxClipDistances              = 4;
-    pState->caps.maxColorAttachments           = 1;
-    pState->caps.maxRectangleTextureSize       = 2048;
-    pState->caps.maxTextureAnisotropy          = 2;
-    pState->caps.maxVertexShaderInstructions   = 1024;
-    pState->caps.maxFragmentShaderInstructions = 1024;
-    pState->caps.vertexShaderVersion           = SVGA3DVSVERSION_NONE;
-    pState->caps.fragmentShaderVersion         = SVGA3DPSVERSION_NONE;
 
     /*
      * OpenGL function calls aren't possible without a valid current context, so create a fake one here.
      */
-    rc = vmsvga3dContextDefine(pThis, 1, false /*fLegacy*/);
+    rc = vmsvga3dContextDefine(pThis, 1, false /*fOtherProfile*/);
     AssertRCReturn(rc, rc);
 
@@ -949,39 +1166,51 @@
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 
-    LogRel(("VMSVGA3d: OpenGL version: %s\nOpenGL Vendor: %s\nOpenGL Renderer: %s\n", glGetString(GL_VERSION), glGetString(GL_VENDOR), glGetString(GL_RENDERER)));
-    LogRel(("VMSVGA3d: OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)));
-    vmsvga3dLogRelExtensions();
+    LogRel(("VMSVGA3d: OpenGL version: %s\n"
+            "VMSVGA3d: OpenGL Vendor: %s\n"
+            "VMSVGA3d: OpenGL Renderer: %s\n"
+            "VMSVGA3d: OpenGL shader language version: %s\n",
+            glGetString(GL_VERSION), glGetString(GL_VENDOR), glGetString(GL_RENDERER),
+            glGetString(GL_SHADING_LANGUAGE_VERSION)));
+
+    rc = vmsvga3dGatherExtensions(&pState->pszExtensions, VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE);
+    AssertRCReturn(rc, rc);
+    vmsvga3dLogRelExtensions("", pState->pszExtensions);
 
     pState->fGLVersion = atof((const char *)glGetString(GL_VERSION));
 
 
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
     /*
-     * Get the legacy extension list so we can better figure out the shader model.
-     * We add space before and after the list, so we can use strstr for locating extensions.
+     * Get the extension list for the alternative profile so we can better
+     * figure out the shader model and stuff.
      */
-    rc = vmsvga3dContextDefine(pThis, 2, true /*fLegacy*/);
+    rc = vmsvga3dContextDefine(pThis, 2, true /*fOtherProfile*/);
     AssertLogRelRCReturn(rc, rc);
     pContext = &pState->paContext[1]; /* Array may have been reallocated. */
 
-    pLegacyContext = &pState->paContext[2];
-    VMSVGA3D_SET_CURRENT_CONTEXT(pState, pLegacyContext);
-
-    pState->pszLegacyExtensions = NULL;
-    rc = RTStrAAppendExN(&pState->pszLegacyExtensions, 3,
-                         " ", (size_t)1, (const char *)glGetString(GL_EXTENSIONS), RTSTR_MAX, " ", (size_t)1);
-    AssertLogRelRCReturn(rc, rc);
-
-    LogRel(("VMSVGA3d: Legacy OpenGL version: %s\nOpenGL Vendor: %s\nOpenGL Renderer: %s\n", glGetString(GL_VERSION), glGetString(GL_VENDOR), glGetString(GL_RENDERER)));
-    LogRel(("VMSVGA3d: Legacy OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)));
-    LogRel(("VMSVGA3d: Legacy OpenGL extenions: %s\n", glGetString(GL_EXTENSIONS)));
+    pOtherCtx = &pState->paContext[2];
+    VMSVGA3D_SET_CURRENT_CONTEXT(pState, pOtherCtx);
+
+    LogRel(("VMSVGA3d: Alternative OpenGL version: %s\n"
+            "VMSVGA3d: Alternative OpenGL Vendor: %s\n"
+            "VMSVGA3d: Alternative OpenGL Renderer: %s\n"
+            "VMSVGA3d: Alternative OpenGL shader language version: %s\n",
+            glGetString(GL_VERSION), glGetString(GL_VENDOR), glGetString(GL_RENDERER),
+            glGetString(GL_SHADING_LANGUAGE_VERSION)));
+
+    rc = vmsvga3dGatherExtensions(&pState->pszOtherExtensions, VBOX_VMSVGA3D_OTHER_OGL_PROFILE);
+    AssertRCReturn(rc, rc);
+    vmsvga3dLogRelExtensions("Alternative ", pState->pszOtherExtensions);
+
+    pState->fOtherGLVersion = atof((const char *)glGetString(GL_VERSION));
 
     VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
 #else
-    pState->pszLegacyExtensions = (char *)"";
+    pState->pszOtherExtensions = (char *)"";
+    pState->fOtherGLVersion = pState->fGLVersion;
 #endif
 
 
-    if (vmsvga3dCheckGLExtension(pState->fGLVersion, 3.0, "GL_ARB_framebuffer_object"))
+    if (vmsvga3dCheckGLExtension(pState, 3.0, " GL_ARB_framebuffer_object "))
     {
         pState->ext.glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)OGLGETPROCADDRESS("glIsRenderbuffer");
@@ -1048,5 +1277,5 @@
 
     /* OpenGL 3.2 core */
-    if (vmsvga3dCheckGLExtension(pState->fGLVersion, 3.2, "GL_ARB_draw_elements_base_vertex"))
+    if (vmsvga3dCheckGLExtension(pState, 3.2, " GL_ARB_draw_elements_base_vertex "))
     {
         pState->ext.glDrawElementsBaseVertex          = (PFNGLDRAWELEMENTSBASEVERTEXPROC)OGLGETPROCADDRESS("glDrawElementsBaseVertex");
@@ -1057,5 +1286,5 @@
 
     /* OpenGL 3.2 core */
-    if (vmsvga3dCheckGLExtension(pState->fGLVersion, 3.2, "GL_ARB_provoking_vertex"))
+    if (vmsvga3dCheckGLExtension(pState, 3.2, " GL_ARB_provoking_vertex "))
     {
         pState->ext.glProvokingVertex                 = (PFNGLPROVOKINGVERTEXPROC)OGLGETPROCADDRESS("glProvokingVertex");
@@ -1065,72 +1294,56 @@
 
     /* Extension support */
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
+#if defined(RT_OS_DARWIN)
     /** @todo OpenGL version history suggest this, verify...  */
-    pState->ext.fEXT_stencil_two_side = vmsvga3dCheckGLExtension(pState->fGLVersion, 2.0, "GL_EXT_stencil_two_side");
+    pState->ext.fEXT_stencil_two_side = vmsvga3dCheckGLExtension(pState, 2.0, " GL_EXT_stencil_two_side ");
 #else
-    pState->ext.fEXT_stencil_two_side = vmsvga3dCheckGLExtension(pState->fGLVersion, 0.0, "GL_EXT_stencil_two_side");
+    pState->ext.fEXT_stencil_two_side = vmsvga3dCheckGLExtension(pState, 0.0, " GL_EXT_stencil_two_side ");
 #endif
 
-    /* Query capabilities */
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
-    glGetIntegerv(GL_MAX_LIGHTS, &pState->caps.maxActiveLights);
-    if (glGetError() != GL_NO_ERROR)
-    {
-        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pLegacyContext);
-        VMSVGA3D_INIT_CHECKED_GL_GET_INTEGER_VALUE(GL_MAX_LIGHTS, &pState->caps.maxActiveLights);
-        if (glGetError() != GL_NO_ERROR)
-            pState->caps.maxActiveLights = 1;
-        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
-    }
-#else
-    VMSVGA3D_INIT_CHECKED_GL_GET_INTEGER_VALUE(GL_MAX_LIGHTS, &pState->caps.maxActiveLights);
-#endif
-    VMSVGA3D_INIT_CHECKED_GL_GET_INTEGER_VALUE(GL_MAX_TEXTURE_BUFFER_SIZE, &pState->caps.maxTextureBufferSize);
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
-    glGetIntegerv(GL_MAX_LIGHTS, &pState->caps.maxActiveLights);
-    if (glGetError() != GL_NO_ERROR)
-        VMSVGA3D_INIT_CHECKED_GL_GET_INTEGER_VALUE(GL_MAX_TEXTURE_IMAGE_UNITS, &pState->caps.maxTextures);
-#else
-    VMSVGA3D_INIT_CHECKED_GL_GET_INTEGER_VALUE(GL_MAX_TEXTURE_UNITS_ARB, &pState->caps.maxTextures);
-#endif
-    VMSVGA3D_INIT_CHECKED_GL_GET_INTEGER_VALUE(GL_MAX_CLIP_DISTANCES, &pState->caps.maxClipDistances);
-    VMSVGA3D_INIT_CHECKED_GL_GET_INTEGER_VALUE(GL_MAX_COLOR_ATTACHMENTS, &pState->caps.maxColorAttachments);
-    VMSVGA3D_INIT_CHECKED_GL_GET_INTEGER_VALUE(GL_MAX_RECTANGLE_TEXTURE_SIZE, &pState->caps.maxRectangleTextureSize);
-    VMSVGA3D_INIT_CHECKED_GL_GET_INTEGER_VALUE(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &pState->caps.maxTextureAnisotropy);
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
-    glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pState->caps.flPointSize);
-    if (glGetError() != GL_NO_ERROR)
-    {
-        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pLegacyContext);
-        VMSVGA3D_INIT_CHECKED(glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pState->caps.flPointSize));
-        if (glGetError() != GL_NO_ERROR)
-        {
-            pState->caps.flPointSize[0] = 1;
-            pState->caps.flPointSize[1] = 1;
-        }
-        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
-    }
-#else
-    VMSVGA3D_INIT_CHECKED(glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pState->caps.flPointSize));
-#endif
+    /*
+     * Initialize the capabilities with sensible defaults.
+     */
+    pState->caps.maxActiveLights               = 1;
+    pState->caps.maxTextureBufferSize          = 65536;
+    pState->caps.maxTextures                   = 1;
+    pState->caps.maxClipDistances              = 4;
+    pState->caps.maxColorAttachments           = 1;
+    pState->caps.maxRectangleTextureSize       = 2048;
+    pState->caps.maxTextureAnisotropy          = 2;
+    pState->caps.maxVertexShaderInstructions   = 1024;
+    pState->caps.maxFragmentShaderInstructions = 1024;
+    pState->caps.vertexShaderVersion           = SVGA3DVSVERSION_NONE;
+    pState->caps.fragmentShaderVersion         = SVGA3DPSVERSION_NONE;
+    pState->caps.flPointSize[0]                = 1;
+    pState->caps.flPointSize[1]                = 1;
+
+    /*
+     * Query capabilities
+     */
+    VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx, glGetIntegerv(GL_MAX_LIGHTS, &pState->caps.maxActiveLights));
+    VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx, glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &pState->caps.maxTextureBufferSize));
+    VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx, glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &pState->caps.maxTextures));
+    VMSVGA3D_INIT_CHECKED(glGetIntegerv(GL_MAX_CLIP_DISTANCES, &pState->caps.maxClipDistances));
+    VMSVGA3D_INIT_CHECKED(glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &pState->caps.maxColorAttachments));
+    VMSVGA3D_INIT_CHECKED(glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE, &pState->caps.maxRectangleTextureSize));
+    VMSVGA3D_INIT_CHECKED(glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &pState->caps.maxTextureAnisotropy));
+    VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx, glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pState->caps.flPointSize));
 
     if (pState->ext.glGetProgramivARB)
     {
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE /* None of these queries works with the OpenGL 3.2 Core context on darwin. */
-        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pLegacyContext);
-#endif
-        VMSVGA3D_INIT_CHECKED(pState->ext.glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB,
-                                                            &pState->caps.maxFragmentShaderTemps));
-        VMSVGA3D_INIT_CHECKED(pState->ext.glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB,
-                                                            &pState->caps.maxFragmentShaderInstructions));
-        VMSVGA3D_INIT_CHECKED(pState->ext.glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB,
-                                                            &pState->caps.maxVertexShaderTemps));
-        VMSVGA3D_INIT_CHECKED(pState->ext.glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB,
-                                                            &pState->caps.maxVertexShaderInstructions));
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
-        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
-#endif
-    }
-    pState->caps.fS3TCSupported = vmsvga3dCheckGLExtension(pState->fGLVersion, 0.0, "GL_EXT_texture_compression_s3tc");
+        VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx,
+                                   pState->ext.glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB,
+                                                                 &pState->caps.maxFragmentShaderTemps));
+        VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx,
+                                   pState->ext.glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB,
+                                                                 &pState->caps.maxFragmentShaderInstructions));
+        VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx,
+                                   pState->ext.glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB,
+                                                                 &pState->caps.maxVertexShaderTemps));
+        VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx,
+                                   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 ");
 
     /* http://http://www.opengl.org/wiki/Detecting_the_Shader_Model
@@ -1144,6 +1357,6 @@
      */
     /** @todo: distinguish between vertex and pixel shaders??? */
-    if (   vmsvga3dCheckGLExtension(pState->fGLVersion, 0.0, "GL_NV_gpu_program4")
-        || strstr(pState->pszLegacyExtensions, " GL_NV_gpu_program4 "))
+    if (   vmsvga3dCheckGLExtension(pState, 0.0, " GL_NV_gpu_program4 ")
+        || strstr(pState->pszOtherExtensions, " GL_NV_gpu_program4 "))
     {
         pState->caps.vertexShaderVersion   = SVGA3DVSVERSION_40;
@@ -1151,10 +1364,8 @@
     }
     else
-    if (    vmsvga3dCheckGLExtension(pState->fGLVersion, 0.0, "GL_NV_vertex_program3")
-        || strstr(pState->pszLegacyExtensions, " GL_NV_vertex_program3 ")
-#if 0 /** @todo this is contrary to the ATI <= SM2.0. */
-        ||  vmsvga3dCheckGLExtension(pState->fGLVersion, 0.0, "GL_ARB_shader_texture_lod")  /* Wine claims this suggests SM 3.0 support */
-        || strstr(pState->pszLegacyExtensions, " GL_ARB_shader_texture_lod ")
-#endif
+    if (   vmsvga3dCheckGLExtension(pState, 0.0, " 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 */
+        || strstr(pState->pszOtherExtensions, " GL_ARB_shader_texture_lod ")
         )
     {
@@ -1163,6 +1374,6 @@
     }
     else
-    if (   vmsvga3dCheckGLExtension(pState->fGLVersion, 0.0, "GL_ARB_fragment_program")
-        || strstr(pState->pszLegacyExtensions, " GL_ARB_fragment_program "))
+    if (   vmsvga3dCheckGLExtension(pState, 0.0, " GL_ARB_fragment_program ")
+        || strstr(pState->pszOtherExtensions, " GL_ARB_fragment_program "))
     {
         pState->caps.vertexShaderVersion   = SVGA3DVSVERSION_20;
@@ -1176,5 +1387,5 @@
     }
 
-    if (!vmsvga3dCheckGLExtension(pState->fGLVersion, 3.2, "GL_ARB_vertex_array_bgra"))
+    if (!vmsvga3dCheckGLExtension(pState, 3.2, " GL_ARB_vertex_array_bgra "))
     {
         /** @todo Intel drivers don't support this extension! */
@@ -1265,5 +1476,7 @@
 
     /* Initialize the shader library. */
-    rc = ShaderInitLib();
+    pState->ShaderIf.pfnSwitchInitProfile = vmsvga3dShaderIfSwitchInitProfile;
+    pState->ShaderIf.pfnGetNextExtension  = vmsvga3dShaderIfGetNextExtension;
+    rc = ShaderInitLib(&pState->ShaderIf);
     AssertRC(rc);
 
@@ -1271,17 +1484,15 @@
     rc = vmsvga3dContextDestroy(pThis, 1);
     AssertRC(rc);
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
     rc = vmsvga3dContextDestroy(pThis, 2);
     AssertRC(rc);
 #endif
 
-#if !defined(RT_OS_DARWIN) || defined(VBOX_VMSVGA3D_USE_OPENGL_CORE)
-    /* on the Mac, OpenGL 3 came very late so we have a capable 2.1 implementation */
-    if (pState->fGLVersion < 3.0)
+    if (   pState->fGLVersion < 3.0
+        && pState->fOtherGLVersion < 3.0 /* darwin: legacy profile hack */)
     {
         LogRel(("VMSVGA3d: unsupported OpenGL version; minimum is 3.0\n"));
         return VERR_NOT_IMPLEMENTED;
     }
-#endif
     if (    !pState->ext.glIsRenderbuffer
         ||  !pState->ext.glBindRenderbuffer
@@ -1366,8 +1577,10 @@
 #endif
 
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
-    RTStrFree(pState->pszLegacyExtensions);
+    RTStrFree(pState->pszExtensions);
+    pState->pszExtensions = NULL;
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+    RTStrFree(pState->pszOtherExtensions);
 #endif
-    pState->pszLegacyExtensions = NULL;
+    pState->pszOtherExtensions = NULL;
 
     return VINF_SUCCESS;
@@ -3246,8 +3459,10 @@
  * @param   pThis           VGA device instance data.
  * @param   cid             Context id
- * @param   fLegacy         Whether to create a legacy context instead of
- *                          whatever is default.  Only used at init time.
+ * @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.
  */
-int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fLegacy)
+int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fOtherProfile)
 {
     int                     rc;
@@ -3257,6 +3472,6 @@
     AssertReturn(pState, VERR_NO_MEMORY);
     AssertReturn(cid < SVGA3D_MAX_CONTEXT_IDS, VERR_INVALID_PARAMETER);
-#if !defined(VBOX_VMSVGA3D_USE_OPENGL_CORE) || !(defined(RT_OS_DARWIN))
-    AssertReturn(!fLegacy, VERR_INTERNAL_ERROR_3);
+#if !defined(VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE) || !(defined(RT_OS_DARWIN))
+    AssertReturn(!fOtherProfile, VERR_INTERNAL_ERROR_3);
 #endif
 
@@ -3266,5 +3481,5 @@
     {
         pState->idTestContext = 207;
-        rc = vmsvga3dContextDefine(pThis, pState->idTestContext, false /*fLegacy*/);
+        rc = vmsvga3dContextDefine(pThis, pState->idTestContext, false /*fOtherProfile*/);
         AssertRCReturn(rc, rc);
     }
@@ -3386,5 +3601,5 @@
 
 #elif defined(RT_OS_DARWIN)
-    pContext->fLegacy = fLegacy;
+    pContext->fOtherProfile = fOtherProfile;
 
     /* Find the first active context to share the display list with (necessary for sharing e.g. textures between contexts). */
@@ -3394,5 +3609,5 @@
         if (    pState->paContext[i].id != SVGA3D_INVALID_ID
             &&  i != pContext->id
-            &&  pState->paContext[i].fLegacy == fLegacy)
+            &&  pState->paContext[i].fOtherProfile == fOtherProfile)
         {
             Log(("Sharing display lists between cid=%d and cid=%d\n", pContext->id, i));
@@ -3401,5 +3616,5 @@
         }
     }
-    vmsvga3dCocoaCreateContext(&pContext->cocoaContext, shareContext, fLegacy);
+    vmsvga3dCocoaCreateContext(&pContext->cocoaContext, shareContext, fOtherProfile);
     NativeNSViewRef pHostView = (NativeNSViewRef)pThis->svga.u64HostWindowId;
     vmsvga3dCocoaCreateView(&pContext->cocoaView, pHostView);
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.h
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.h	(revision 53754)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.h	(revision 53755)
@@ -49,5 +49,5 @@
             uint32_t cPixelShaderConst, cVertexShaderConst, cPixelShaders, cVertexShaders;
 
-            rc = vmsvga3dContextDefine(pThis, cid, false /*fLegacy*/);
+            rc = vmsvga3dContextDefine(pThis, cid, false /*fOtherProfile*/);
             AssertRCReturn(rc, rc);
 
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp	(revision 53754)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp	(revision 53755)
@@ -2902,7 +2902,7 @@
  * @param   pThis           VGA device instance data.
  * @param   cid             Context id
- * @param   fLegacy         OpenGL(+darwin) specific argument, ignored.
+ * @param   fOtherProfile   OpenGL(+darwin) specific argument, ignored.
  */
-int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fLegacy)
+int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fOtherProfile)
 {
     int                     rc;
@@ -2914,4 +2914,5 @@
     AssertReturn(pState, VERR_NO_MEMORY);
     AssertReturn(cid < SVGA3D_MAX_CONTEXT_IDS, VERR_INVALID_PARAMETER);
+    NOREF(fOtherProfile);
 
     Log(("vmsvga3dContextDefine id %x\n", cid));
@@ -5355,5 +5356,7 @@
 }
 
-int vmsvga3dDrawPrimitives(PVGASTATE pThis, uint32_t cid, uint32_t numVertexDecls, SVGA3dVertexDecl *pVertexDecl, uint32_t numRanges, SVGA3dPrimitiveRange *pRange, uint32_t cVertexDivisor, SVGA3dVertexDivisor *pVertexDivisor)
+int vmsvga3dDrawPrimitives(PVGASTATE pThis, uint32_t cid, uint32_t numVertexDecls, SVGA3dVertexDecl *pVertexDecl,
+                           uint32_t numRanges, SVGA3dPrimitiveRange *pRange,
+                           uint32_t cVertexDivisor, SVGA3dVertexDivisor *pVertexDivisor)
 {
     PVMSVGA3DCONTEXT             pContext;
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h	(revision 53754)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h	(revision 53755)
@@ -62,5 +62,5 @@
 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 fLegacy);
+int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fOtherProfile);
 int vmsvga3dContextDestroy(PVGASTATE pThis, uint32_t cid);
 
Index: /trunk/src/VBox/Devices/Graphics/shaderlib/directx.c
===================================================================
--- /trunk/src/VBox/Devices/Graphics/shaderlib/directx.c	(revision 53754)
+++ /trunk/src/VBox/Devices/Graphics/shaderlib/directx.c	(revision 53755)
@@ -1908,5 +1908,5 @@
 #endif
 
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
+#ifdef VBOX_WITH_VMSVGA
 /** Checks if @a pszExtension is one of the extensions we're looking for and
  *  updates @a pGlInfo->supported accordingly. */
@@ -1926,9 +1926,9 @@
 
 /* Context activation is done by the caller. */
-BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter)
+BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter, struct VBOXVMSVGASHADERIF *pVBoxShaderIf)
 {
     struct wined3d_driver_info *driver_info = &adapter->driver_info;
     struct wined3d_gl_info *gl_info = &adapter->gl_info;
-#ifndef VBOX_VMSVGA3D_USE_OPENGL_CORE
+#ifndef VBOX_WITH_VMSVGA
     const char *GL_Extensions    = NULL;
     const char *WGL_Extensions   = NULL;
@@ -2008,8 +2008,12 @@
     TRACE_(d3d_caps)("ClipPlanes support - num Planes=%d\n", gl_max);
 
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
     glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
     if (glGetError() != GL_NO_ERROR)
-        gl_max = 0;
+    {
+        pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, true /*fOtherProfile*/);
+        VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_LIGHTS, &gl_max));
+        pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, false /*fOtherProfile*/);
+    }
 #else
     VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_LIGHTS, &gl_max));
@@ -2022,10 +2026,13 @@
     TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max);
 
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
     glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, gl_floatv);
     if (glGetError() != GL_NO_ERROR)
     {
-        gl_floatv[0] = 1;
-        gl_floatv[1] = 1;
+        pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, true /*fOtherProfile*/);
+        VBOX_CHECK_GL_CALL(glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, gl_floatv));
+        if (glGetError() != GL_NO_ERROR)
+            gl_floatv[0] = gl_floatv[1] = 1;
+        pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, false /*fOtherProfile*/);
     }
 #else
@@ -2037,6 +2044,6 @@
 
     /* Parse the gl supported features, in theory enabling parts of our code appropriately. */
-#ifndef VBOX_VMSVGA3D_USE_OPENGL_CORE
-    VBOX_CHECK_GL_CALL(GL_Extensions = (const char *)glGetString(GL_EXTENSIONS));
+#ifndef VBOX_WITH_VMSVGA
+    GL_Extensions = (const char *)glGetString(GL_EXTENSIONS);
     if (!GL_Extensions)
     {
@@ -2055,163 +2062,17 @@
     gl_info->supported[VBOX_SHARED_CONTEXTS] = TRUE;
 
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
-    {
-        /* We work with OpenGL 3.2+ on darwin, so we need to handle extensions differently. */
-        GLint idxExt;
-        GLint cExtensions = 1024;
-        float fGLVersion;
-        VBOX_CHECK_GL_CALL(fGLVersion = atof((const char *)glGetString(GL_VERSION)));
-
-# define GL_NUM_EXTENSIONS 0x821D /// FIXME
-        extern const GLubyte * glGetStringi(GLenum name, GLuint index); /// FIXME
-
-        VBOX_CHECK_GL_CALL(glGetIntegerv(GL_NUM_EXTENSIONS, &cExtensions));
-        for (idxExt = 0; idxExt < cExtensions; idxExt++)
-        {
-            const char *pszExt;
-            VBOX_CHECK_GL_CALL((const char *)glGetStringi(GL_EXTENSIONS, idxExt));
-            check_gl_extension(gl_info, pszExt);
-        }
-
-        if (fGLVersion >= 1.1)
-        {
-            check_gl_extension(gl_info, "GL_EXT_vertex_array");
-            check_gl_extension(gl_info, "GL_EXT_polygon_offset");
-            check_gl_extension(gl_info, "GL_EXT_blend_logic_op");
-            check_gl_extension(gl_info, "GL_EXT_texture");
-            check_gl_extension(gl_info, "GL_EXT_copy_texture");
-            check_gl_extension(gl_info, "GL_EXT_subtexture");
-            check_gl_extension(gl_info, "GL_EXT_texture_object");
-            check_gl_extension(gl_info, "GL_ARB_framebuffer_object");
-            check_gl_extension(gl_info, "GL_ARB_map_buffer_range");
-            check_gl_extension(gl_info, "GL_ARB_vertex_array_object");
-        }
-        if (fGLVersion >= 1.2)
-        {
-            check_gl_extension(gl_info, "EXT_texture3D");
-            check_gl_extension(gl_info, "EXT_bgra");
-            check_gl_extension(gl_info, "EXT_packed_pixels");
-            check_gl_extension(gl_info, "EXT_rescale_normal");
-            check_gl_extension(gl_info, "EXT_separate_specular_color");
-            check_gl_extension(gl_info, "SGIS_texture_edge_clamp");
-            check_gl_extension(gl_info, "SGIS_texture_lod");
-            check_gl_extension(gl_info, "EXT_draw_range_elements");
-        }
-        if (fGLVersion >= 1.3)
-        {
-            check_gl_extension(gl_info, "GL_ARB_texture_compression");
-            check_gl_extension(gl_info, "GL_ARB_texture_cube_map");
-            check_gl_extension(gl_info, "GL_ARB_multisample");
-            check_gl_extension(gl_info, "GL_ARB_multitexture");
-            check_gl_extension(gl_info, "GL_ARB_texture_env_add");
-            check_gl_extension(gl_info, "GL_ARB_texture_env_combine");
-            check_gl_extension(gl_info, "GL_ARB_texture_env_dot3");
-            check_gl_extension(gl_info, "GL_ARB_texture_border_clamp");
-            check_gl_extension(gl_info, "GL_ARB_transpose_matrix");
-        }
-        if (fGLVersion >= 1.5)
-        {
-            check_gl_extension(gl_info, "GL_SGIS_generate_mipmap");
-            /*check_gl_extension(gl_info, "GL_NV_blend_equare");*/
-            check_gl_extension(gl_info, "GL_ARB_depth_texture");
-            check_gl_extension(gl_info, "GL_ARB_shadow");
-            check_gl_extension(gl_info, "GL_EXT_fog_coord");
-            check_gl_extension(gl_info, "GL_EXT_multi_draw_arrays");
-            check_gl_extension(gl_info, "GL_ARB_point_parameters");
-            check_gl_extension(gl_info, "GL_EXT_secondary_color");
-            check_gl_extension(gl_info, "GL_EXT_blend_func_separate");
-            check_gl_extension(gl_info, "GL_EXT_stencil_wrap");
-            check_gl_extension(gl_info, "GL_ARB_texture_env_crossbar");
-            check_gl_extension(gl_info, "GL_EXT_texture_lod_bias");
-            check_gl_extension(gl_info, "GL_ARB_texture_mirrored_repeat");
-            check_gl_extension(gl_info, "GL_ARB_window_pos");
-        }
-        if (fGLVersion >= 1.6)
-        {
-            check_gl_extension(gl_info, "GL_ARB_vertex_buffer_object");
-            check_gl_extension(gl_info, "GL_ARB_occlusion_query");
-            check_gl_extension(gl_info, "GL_EXT_shadow_funcs");
-        }
-        if (fGLVersion >= 2.0)
-        {
-            check_gl_extension(gl_info, "GL_ARB_shader_objects"); /*??*/
-            check_gl_extension(gl_info, "GL_ARB_vertex_shader"); /*??*/
-            check_gl_extension(gl_info, "GL_ARB_fragment_shader"); /*??*/
-            check_gl_extension(gl_info, "GL_ARB_shading_language_100"); /*??*/
-            check_gl_extension(gl_info, "GL_ARB_draw_buffers");
-            check_gl_extension(gl_info, "GL_ARB_texture_non_power_of_two");
-            check_gl_extension(gl_info, "GL_ARB_point_sprite");
-            check_gl_extension(gl_info, "GL_ATI_separate_stencil");
-            check_gl_extension(gl_info, "GL_EXT_stencil_two_side");
-        }
-        if (fGLVersion >= 2.1)
-        {
-            check_gl_extension(gl_info, "GL_ARB_pixel_buffer_object");
-            check_gl_extension(gl_info, "GL_EXT_texture_sRGB");
-        }
-        if (fGLVersion >= 3.0)
-        {
-            check_gl_extension(gl_info, "GL_ARB_framebuffer_object");
-            check_gl_extension(gl_info, "GL_ARB_map_buffer_range");
-            check_gl_extension(gl_info, "GL_ARB_vertex_array_object");
-        }
-        if (fGLVersion >= 3.0)
-        {
-            check_gl_extension(gl_info, "GL_ARB_framebuffer_object");
-            check_gl_extension(gl_info, "GL_ARB_map_buffer_range");
-            check_gl_extension(gl_info, "GL_ARB_vertex_array_object");
-        }
-        if (fGLVersion >= 3.1)
-        {
-            check_gl_extension(gl_info, "GL_ARB_copy_buffer");
-            check_gl_extension(gl_info, "GL_ARB_uniform_buffer_object");
-        }
-        if (fGLVersion >= 3.2)
-        {
-            check_gl_extension(gl_info, "GL_ARB_draw_elements_base_vertex");
-            check_gl_extension(gl_info, "GL_ARB_provoking_vertex");
-            check_gl_extension(gl_info, "GL_ARB_sync");
-            check_gl_extension(gl_info, "GL_ARB_texture_multisample");
-        }
-        if (fGLVersion >= 3.3)
-        {
-            check_gl_extension(gl_info, "GL_ARB_blend_func_extended");
-            check_gl_extension(gl_info, "GL_ARB_sampler_objects");
-            check_gl_extension(gl_info, "GL_ARB_explicit_attrib_location");
-            check_gl_extension(gl_info, "GL_ARB_occlusion_query2");
-            check_gl_extension(gl_info, "GL_ARB_shader_bit_encoding");
-            check_gl_extension(gl_info, "GL_ARB_texture_rgb10_a2ui");
-            check_gl_extension(gl_info, "GL_ARB_texture_swizzle");
-            check_gl_extension(gl_info, "GL_ARB_timer_query");
-            check_gl_extension(gl_info, "GL_ARB_vertex_type_2_10_10_10_rev");
-        }
-        if (fGLVersion >=4.0)
-        {
-            check_gl_extension(gl_info, "GL_ARB_texture_query_lod");
-            check_gl_extension(gl_info, "GL_ARB_draw_indirect");
-            check_gl_extension(gl_info, "GL_ARB_gpu_shader5");
-            check_gl_extension(gl_info, "GL_ARB_gpu_shader_fp64");
-            check_gl_extension(gl_info, "GL_ARB_shader_subroutine");
-            check_gl_extension(gl_info, "GL_ARB_tessellation_shader");
-            check_gl_extension(gl_info, "GL_ARB_texture_buffer_object_rgb32");
-            check_gl_extension(gl_info, "GL_ARB_texture_cube_map_array");
-            check_gl_extension(gl_info, "GL_ARB_texture_gather");
-            check_gl_extension(gl_info, "GL_ARB_transform_feedback2");
-            check_gl_extension(gl_info, "GL_ARB_transform_feedback3");
-        }
-        if (fGLVersion >=4.1)
-        {
-            check_gl_extension(gl_info, "GL_ARB_ES2_compatibility");
-            check_gl_extension(gl_info, "GL_ARB_get_program_binary");
-            check_gl_extension(gl_info, "GL_ARB_separate_shader_objects");
-            check_gl_extension(gl_info, "GL_ARB_shader_precision");
-            check_gl_extension(gl_info, "GL_ARB_vertex_attrib_64bit");
-            check_gl_extension(gl_info, "GL_ARB_viewport_array");
-        }
-    }
-
-    LEAVE_GL();
-
-#else
+#ifdef VBOX_WITH_VMSVGA
+    {
+        void *pvEnumCtx = NULL;
+        char  szCurExt[256];
+        while (pVBoxShaderIf->pfnGetNextExtension(pVBoxShaderIf, &pvEnumCtx, szCurExt, sizeof(szCurExt), false /*fOtherProfile*/))
+            check_gl_extension(gl_info, szCurExt);
+
+        /* The cheap way out. */
+        pvEnumCtx = NULL;
+        while (pVBoxShaderIf->pfnGetNextExtension(pVBoxShaderIf, &pvEnumCtx, szCurExt, sizeof(szCurExt), true /*fOtherProfile*/))
+            check_gl_extension(gl_info, szCurExt);
+    }
+#else /* VBOX_WITH_VMSVGA */
     while (*GL_Extensions)
     {
@@ -2361,5 +2222,5 @@
     if (gl_info->supported[ARB_MULTITEXTURE])
     {
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
         glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
         if (glGetError() != GL_NO_ERROR)
@@ -2426,5 +2287,15 @@
     if (gl_info->supported[ARB_VERTEX_BLEND])
     {
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+        glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
+        if (glGetError() != GL_NO_ERROR)
+        {
+            pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, true /*fOtherProfile*/);
+            VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max));
+            pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, false /*fOtherProfile*/);
+        }
+#else
         VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max));
+#endif
         gl_info->limits.blends = gl_max;
         TRACE_(d3d_caps)("Max blends: %u.\n", gl_info->limits.blends);
@@ -2444,4 +2315,9 @@
     if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
     {
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+        GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
+        if (glGetError() != GL_NO_ERROR)
+            pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, true /*fOtherProfile*/);
+#endif
         VBOX_CHECK_GL_CALL(GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max)));
         gl_info->limits.arb_ps_float_constants = gl_max;
@@ -2460,7 +2336,15 @@
         gl_info->limits.arb_ps_local_constants = gl_max;
         TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM local parameters: %d.\n", gl_info->limits.arb_ps_instructions);
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+        pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, false /*fOtherProfile*/);
+#endif
     }
     if (gl_info->supported[ARB_VERTEX_PROGRAM])
     {
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+        GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
+        if (glGetError() != GL_NO_ERROR)
+            pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, true /*fOtherProfile*/);
+#endif
         VBOX_CHECK_GL_CALL(GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max)));
         gl_info->limits.arb_vs_float_constants = gl_max;
@@ -2476,4 +2360,7 @@
         gl_info->limits.arb_vs_instructions = gl_max;
         TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native instructions: %d.\n", gl_info->limits.arb_vs_instructions);
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+        pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, false /*fOtherProfile*/);
+#endif
 #ifndef VBOX_WITH_VMSVGA
         if (test_arb_vs_offset_limit(gl_info)) gl_info->quirks |= WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT;
@@ -2533,8 +2420,12 @@
 #endif
         TRACE_(d3d_caps)("Max ARB_FRAGMENT_SHADER float constants: %u.\n", gl_info->limits.glsl_ps_float_constants);
-#ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
         glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max);
         if (glGetError() != GL_NO_ERROR)
-            gl_max = 60;
+        {
+            pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, true /*fOtherProfile*/);
+            VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max));
+            pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, false /*fOtherProfile*/);
+        }
 #else
         VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max));
@@ -2556,5 +2447,15 @@
     if (gl_info->supported[NV_LIGHT_MAX_EXPONENT])
     {
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+        glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess);
+        if (glGetError() != GL_NO_ERROR)
+        {
+            pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, true /*fOtherProfile*/);
+            VBOX_CHECK_GL_CALL(glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess));
+            pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, false /*fOtherProfile*/);
+        }
+#else
         VBOX_CHECK_GL_CALL(glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess));
+#endif
     }
     else
Index: /trunk/src/VBox/Devices/Graphics/shaderlib/shaderapi.c
===================================================================
--- /trunk/src/VBox/Devices/Graphics/shaderlib/shaderapi.c	(revision 53754)
+++ /trunk/src/VBox/Devices/Graphics/shaderlib/shaderapi.c	(revision 53755)
@@ -132,25 +132,25 @@
             glGetAttribLocationARB,                     ARB_SHADER_OBJECTS,             NULL) \
 
-static struct wined3d_context *pCurrentContext = NULL;
-static struct wined3d_adapter adapter = {0};
-static bool fInitializedLibrary = false;
+static struct wined3d_context *g_pCurrentContext = NULL;
+static struct wined3d_adapter g_adapter = {0};
+static bool g_fInitializedLibrary = false;
 
 #define SHADER_SET_CURRENT_CONTEXT(ctx) \
-    pCurrentContext = (struct wined3d_context *)ctx;
-
-SHADERDECL(int) ShaderInitLib(void)
-{
-    struct wined3d_gl_info *gl_info = &adapter.gl_info;
-
+    g_pCurrentContext = (struct wined3d_context *)ctx;
+
+SHADERDECL(int) ShaderInitLib(PVBOXVMSVGASHADERIF pVBoxShaderIf)
+{
+    struct wined3d_gl_info *gl_info = &g_adapter.gl_info;
+
+    /* Dynamically load all GL core functions. */
 #ifdef RT_OS_WINDOWS
-#define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(GetModuleHandle("opengl32.dll"), #pfn);
+# define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(GetModuleHandle("opengl32.dll"), #pfn);
 #else
-#define USE_GL_FUNC(pfn) pfn = (void*)OGLGETPROCADDRESS(#pfn);
+# define USE_GL_FUNC(pfn) pfn = (void*)OGLGETPROCADDRESS(#pfn);
 #endif
-
-    /* Dynamically load all GL core functions */
     GL_FUNCS_GEN;
 #undef USE_GL_FUNC
 
+    /* Dynamically load all GL extension functions. */
 #define USE_GL_FUNC(type, pfn, ext, replace) \
 { \
@@ -159,6 +159,30 @@
     GL_EXT_FUNCS_GEN;
 
-    IWineD3DImpl_FillGLCaps(&adapter);
-    fInitializedLibrary = true;
+    /* Fill in GL capabilities. */
+    IWineD3DImpl_FillGLCaps(&g_adapter, pVBoxShaderIf);
+
+    LogRel(("shaderlib: GL Limits:\n"));
+    LogRel(("shaderlib:   buffers=%-2u                lights=%-2u                    textures=%-2u            texture_stages=%u\n",
+            gl_info->limits.buffers, gl_info->limits.lights, gl_info->limits.textures, gl_info->limits.texture_stages));
+    LogRel(("shaderlib:   fragment_samplers=%-2u      vertex_samplers=%-2u           combined_samplers=%-3u  general_combiners=%u\n",
+            gl_info->limits.fragment_samplers, gl_info->limits.vertex_samplers, gl_info->limits.combined_samplers, gl_info->limits.general_combiners));
+    LogRel(("shaderlib:   sampler_stages=%-2u         clipplanes=%-2u                texture_size=%-5u     texture3d_size=%u\n",
+            gl_info->limits.sampler_stages, gl_info->limits.clipplanes, gl_info->limits.texture_size, gl_info->limits.texture3d_size));
+    LogRel(("shaderlib:   pointsize_max=%d.%d      pointsize_min=%d.%d            point_sprite_units=%-2u  blends=%u\n",
+            (int)gl_info->limits.pointsize_max, (int)(gl_info->limits.pointsize_max * 10) % 10,
+            (int)gl_info->limits.pointsize_min, (int)(gl_info->limits.pointsize_min * 10) % 10,
+            gl_info->limits.point_sprite_units, gl_info->limits.blends));
+    LogRel(("shaderlib:   anisotropy=%-2u             shininess=%d.%02d\n",
+            gl_info->limits.anisotropy, (int)gl_info->limits.shininess, (int)(gl_info->limits.shininess * 100) % 100));
+    LogRel(("shaderlib:   glsl_varyings=%-3u         glsl_vs_float_constants=%-4u glsl_ps_float_constants=%u\n",
+            gl_info->limits.glsl_varyings, gl_info->limits.glsl_vs_float_constants, gl_info->limits.glsl_ps_float_constants));
+    LogRel(("shaderlib:   arb_vs_instructions=%-4u  arb_vs_native_constants=%-4u qarb_vs_float_constants=%u\n",
+            gl_info->limits.arb_vs_instructions, gl_info->limits.arb_vs_native_constants, gl_info->limits.arb_vs_float_constants));
+    LogRel(("shaderlib:   arb_vs_temps=%-2u           arb_ps_float_constants=%-4u  arb_ps_local_constants=%u\n",
+            gl_info->limits.arb_vs_temps, gl_info->limits.arb_ps_float_constants, gl_info->limits.arb_ps_local_constants));
+    LogRel(("shaderlib:   arb_ps_instructions=%-4u  arb_ps_temps=%-2u              arb_ps_native_constants=%u\n",
+            gl_info->limits.arb_ps_instructions, gl_info->limits.arb_ps_temps, gl_info->limits.arb_ps_native_constants));
+
+    g_fInitializedLibrary = true;
     return VINF_SUCCESS;
 }
@@ -176,10 +200,10 @@
 struct wined3d_context *context_get_current(void)
 {
-    return pCurrentContext;
+    return g_pCurrentContext;
 }
 
 struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, IWineD3DSurface *target, enum ContextUsage usage)
 {
-    return pCurrentContext;
+    return g_pCurrentContext;
 }
 
@@ -194,7 +218,7 @@
     AssertReturn(pContext->pDeviceContext, VERR_NO_MEMORY);
 
-    pContext->gl_info = &adapter.gl_info;
-
-    pContext->pDeviceContext->adapter = &adapter;
+    pContext->gl_info = &g_adapter.gl_info;
+
+    pContext->pDeviceContext->adapter = &g_adapter;
     pContext->pDeviceContext->shader_backend = &glsl_shader_backend;
     pContext->pDeviceContext->ps_selected_mode = SHADER_GLSL;
@@ -204,5 +228,5 @@
     list_init(&pContext->pDeviceContext->shaders);
 
-    if (fInitializedLibrary)
+    if (g_fInitializedLibrary)
     {
         struct shader_caps shader_caps;
@@ -214,5 +238,5 @@
 
         memset(&shader_caps, 0, sizeof(shader_caps));
-        pContext->pDeviceContext->shader_backend->shader_get_caps(&adapter.gl_info, &shader_caps);
+        pContext->pDeviceContext->shader_backend->shader_get_caps(&g_adapter.gl_info, &shader_caps);
         pContext->pDeviceContext->d3d_vshader_constantF = shader_caps.MaxVertexShaderConst;
         pContext->pDeviceContext->d3d_pshader_constantF = shader_caps.MaxPixelShaderConst;
@@ -290,5 +314,5 @@
 
     SHADER_SET_CURRENT_CONTEXT(pShaderContext);
-    This = pCurrentContext->pDeviceContext;
+    This = g_pCurrentContext->pDeviceContext;
 
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
@@ -324,5 +348,5 @@
 
     SHADER_SET_CURRENT_CONTEXT(pShaderContext);
-    This = pCurrentContext->pDeviceContext;
+    This = g_pCurrentContext->pDeviceContext;
 
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
@@ -379,5 +403,5 @@
 
     SHADER_SET_CURRENT_CONTEXT(pShaderContext);
-    This = pCurrentContext->pDeviceContext;
+    This = g_pCurrentContext->pDeviceContext;
     pShader   = (IWineD3DVertexShader* )pShaderObj;
     oldShader = This->updateStateBlock->vertexShader;
@@ -396,6 +420,6 @@
     if(oldShader) IWineD3DVertexShader_Release(oldShader);
 
-    pCurrentContext->fChangedVertexShader = true;
-    pCurrentContext->fChangedVertexShaderConstant = true;    /* force constant reload. */
+    g_pCurrentContext->fChangedVertexShader = true;
+    g_pCurrentContext->fChangedVertexShaderConstant = true;    /* force constant reload. */
 
     return VINF_SUCCESS;
@@ -409,5 +433,5 @@
 
     SHADER_SET_CURRENT_CONTEXT(pShaderContext);
-    This = pCurrentContext->pDeviceContext;
+    This = g_pCurrentContext->pDeviceContext;
     pShader   = (IWineD3DPixelShader* )pShaderObj;
     oldShader = This->updateStateBlock->pixelShader;
@@ -426,6 +450,6 @@
     if(oldShader) IWineD3DPixelShader_Release(oldShader);
 
-    pCurrentContext->fChangedPixelShader = true;
-    pCurrentContext->fChangedPixelShaderConstant = true;    /* force constant reload. */
+    g_pCurrentContext->fChangedPixelShader = true;
+    g_pCurrentContext->fChangedPixelShaderConstant = true;    /* force constant reload. */
     return VINF_SUCCESS;
 }
@@ -437,5 +461,5 @@
 
     SHADER_SET_CURRENT_CONTEXT(pShaderContext);
-    This = pCurrentContext->pDeviceContext;
+    This = g_pCurrentContext->pDeviceContext;
 
     Log(("(ShaderSetVertexShaderConstantB %p, srcData %p, start %d, count %d)\n",
@@ -456,5 +480,5 @@
     }
 
-    pCurrentContext->fChangedVertexShaderConstant = true;
+    g_pCurrentContext->fChangedVertexShaderConstant = true;
 
     return VINF_SUCCESS;
@@ -467,5 +491,5 @@
 
     SHADER_SET_CURRENT_CONTEXT(pShaderContext);
-    This = pCurrentContext->pDeviceContext;
+    This = g_pCurrentContext->pDeviceContext;
 
     Log(("(ShaderSetVertexShaderConstantI %p, srcData %p, start %d, count %d)\n",
@@ -484,5 +508,5 @@
     }
 
-    pCurrentContext->fChangedVertexShaderConstant = true;
+    g_pCurrentContext->fChangedVertexShaderConstant = true;
 
     return VINF_SUCCESS;
@@ -494,5 +518,5 @@
 
     SHADER_SET_CURRENT_CONTEXT(pShaderContext);
-    This = pCurrentContext->pDeviceContext;
+    This = g_pCurrentContext->pDeviceContext;
 
     Log(("(ShaderSetVertexShaderConstantF %p, srcData %p, start %d, count %d)\n",
@@ -511,5 +535,5 @@
            sizeof(*This->updateStateBlock->changed.vertexShaderConstantsF) * count);
 
-    pCurrentContext->fChangedVertexShaderConstant = true;
+    g_pCurrentContext->fChangedVertexShaderConstant = true;
 
     return VINF_SUCCESS;
@@ -522,5 +546,5 @@
 
     SHADER_SET_CURRENT_CONTEXT(pShaderContext);
-    This = pCurrentContext->pDeviceContext;
+    This = g_pCurrentContext->pDeviceContext;
 
     Log(("(ShaderSetPixelShaderConstantB %p, srcData %p, start %d, count %d)\n",
@@ -541,5 +565,5 @@
     }
 
-    pCurrentContext->fChangedPixelShaderConstant = true;
+    g_pCurrentContext->fChangedPixelShaderConstant = true;
 
     return VINF_SUCCESS;
@@ -552,5 +576,5 @@
 
     SHADER_SET_CURRENT_CONTEXT(pShaderContext);
-    This = pCurrentContext->pDeviceContext;
+    This = g_pCurrentContext->pDeviceContext;
 
     Log(("(ShaderSetPixelShaderConstantI %p, srcData %p, start %d, count %d)\n",
@@ -569,5 +593,5 @@
     }
 
-    pCurrentContext->fChangedPixelShaderConstant = true;
+    g_pCurrentContext->fChangedPixelShaderConstant = true;
 
     return VINF_SUCCESS;
@@ -579,5 +603,5 @@
 
     SHADER_SET_CURRENT_CONTEXT(pShaderContext);
-    This = pCurrentContext->pDeviceContext;
+    This = g_pCurrentContext->pDeviceContext;
 
     Log(("(ShaderSetPixelShaderConstantF %p, srcData %p, start %d, count %d)\n",
@@ -597,5 +621,5 @@
             sizeof(*This->updateStateBlock->changed.pixelShaderConstantsF) * count);
 
-    pCurrentContext->fChangedPixelShaderConstant = true;
+    g_pCurrentContext->fChangedPixelShaderConstant = true;
 
     return VINF_SUCCESS;
@@ -609,5 +633,5 @@
 
     SHADER_SET_CURRENT_CONTEXT(pShaderContext);
-    pThis = pCurrentContext->pDeviceContext;
+    pThis = g_pCurrentContext->pDeviceContext;
 
     glGetIntegerv(GL_VIEWPORT, viewport);
@@ -630,14 +654,14 @@
      */
 
-    if (    pCurrentContext->fChangedPixelShader 
-        ||  pCurrentContext->fChangedVertexShader)
-        pThis->shader_backend->shader_select(pCurrentContext, !!pThis->updateStateBlock->pixelShader, !!pThis->updateStateBlock->vertexShader);
-    pCurrentContext->fChangedPixelShader = pCurrentContext->fChangedVertexShader = false;
-
-    if (    pCurrentContext->fChangedPixelShaderConstant 
-        ||  pCurrentContext->fChangedVertexShaderConstant)
-        pThis->shader_backend->shader_load_constants(pCurrentContext, !!pThis->updateStateBlock->pixelShader, !!pThis->updateStateBlock->vertexShader);
-    pCurrentContext->fChangedPixelShaderConstant  = false;
-    pCurrentContext->fChangedVertexShaderConstant = false;
+    if (    g_pCurrentContext->fChangedPixelShader
+        ||  g_pCurrentContext->fChangedVertexShader)
+        pThis->shader_backend->shader_select(g_pCurrentContext, !!pThis->updateStateBlock->pixelShader, !!pThis->updateStateBlock->vertexShader);
+    g_pCurrentContext->fChangedPixelShader = g_pCurrentContext->fChangedVertexShader = false;
+
+    if (    g_pCurrentContext->fChangedPixelShaderConstant
+        ||  g_pCurrentContext->fChangedVertexShaderConstant)
+        pThis->shader_backend->shader_load_constants(g_pCurrentContext, !!pThis->updateStateBlock->pixelShader, !!pThis->updateStateBlock->vertexShader);
+    g_pCurrentContext->fChangedPixelShaderConstant  = false;
+    g_pCurrentContext->fChangedVertexShaderConstant = false;
 
     return VINF_SUCCESS;
Index: /trunk/src/VBox/Devices/Graphics/shaderlib/shaderlib.h
===================================================================
--- /trunk/src/VBox/Devices/Graphics/shaderlib/shaderlib.h	(revision 53754)
+++ /trunk/src/VBox/Devices/Graphics/shaderlib/shaderlib.h	(revision 53755)
@@ -30,6 +30,39 @@
 #endif
 
+/** Pointer to shaderlib callback interface. */
+typedef struct VBOXVMSVGASHADERIF *PVBOXVMSVGASHADERIF;
+/**
+ * Interface the shader lib can use to talk back to the VBox VMSVGA OGL 3D code.
+ */
+typedef struct VBOXVMSVGASHADERIF
+{
+    /**
+     * Switches the initialization profile in builds where we have to juggle two
+     * OpenGL profiles to gather all the data (i.e. mac os x).
+     *
+     * @param   pThis           Pointer to this structure.
+     * @param   fOtherProfile   If set, switch to the non-default profile.  If
+     *                          clear, switch back to the default profile.
+     */
+    DECLCALLBACKMEMBER(void, pfnSwitchInitProfile)(PVBOXVMSVGASHADERIF pThis, bool fOtherProfile);
 
-SHADERDECL(int) ShaderInitLib(void);
+    /**
+     * Extension enumeration function.
+     *
+     * @param   pThis           Pointer to this structure.
+     * @param   ppvEnumCtx      Pointer to a void point that's initialized to NULL
+     *                          before the first call.
+     * @param   pszBuf          Where to store the extension name. Garbled on
+     *                          overflow (we assume no overflow).
+     * @param   cbBuf           The size of the buffer @a pszBuf points to.
+     * @param   fOtherProfile   Indicates which profile to get extensions from,
+     *                          we'll use the default profile if CLEAR and the
+     *                          non-default if SET.
+     */
+    DECLCALLBACKMEMBER(bool, pfnGetNextExtension)(PVBOXVMSVGASHADERIF pThis, void **ppvEnumCtx, char *pszBuf, size_t cbBuf,
+                                                  bool fOtherProfile);
+} VBOXVMSVGASHADERIF;
+
+SHADERDECL(int) ShaderInitLib(PVBOXVMSVGASHADERIF pVBoxShaderIf);
 SHADERDECL(int) ShaderDestroyLib(void);
 
Index: /trunk/src/VBox/Devices/Graphics/shaderlib/wine/include/d3d9caps.h
===================================================================
--- /trunk/src/VBox/Devices/Graphics/shaderlib/wine/include/d3d9caps.h	(revision 53754)
+++ /trunk/src/VBox/Devices/Graphics/shaderlib/wine/include/d3d9caps.h	(revision 53755)
@@ -292,5 +292,4 @@
 #define D3DMAX30SHADERINSTRUCTIONS          32768
 
-#ifndef VBOX_D3D9CAPS_ONLY_DEFINES
 
 typedef struct _D3DVSHADERCAPS2_0 {
@@ -403,5 +402,3 @@
 } D3DCAPS9;
 
-#endif /* !VBOX_D3D9CAPS_ONLY_DEFINES */
-
 #endif
Index: /trunk/src/VBox/Devices/Graphics/shaderlib/wined3d_private.h
===================================================================
--- /trunk/src/VBox/Devices/Graphics/shaderlib/wined3d_private.h	(revision 53754)
+++ /trunk/src/VBox/Devices/Graphics/shaderlib/wined3d_private.h	(revision 53755)
@@ -69,4 +69,5 @@
 # include <VBox/log.h>
 # include "winoverride.h"
+# include "shaderlib.h"
 #endif
 
@@ -1596,5 +1597,6 @@
 extern void add_gl_compat_wrappers(struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
 
-extern BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter);
+struct VBOXVMSVGASHADERIF;
+extern BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter, struct VBOXVMSVGASHADERIF *pVBoxShaderIf);
 
 
Index: /trunk/src/VBox/Devices/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Devices/Makefile.kmk	(revision 53754)
+++ /trunk/src/VBox/Devices/Makefile.kmk	(revision 53755)
@@ -274,5 +274,10 @@
    VBoxDD_LIBS.win      += $(PATH_SDK_$(VBOX_WINPSDK)_LIB)/Opengl32.lib
    VBoxDD_LDFLAGS.darwin += -framework OpenGL
-   VBoxDD_DEFS.darwin   += VBOX_VMSVGA3D_USE_OPENGL_CORE  # Use the OpenGL 3.2 Core profile (see also VBoxSVGA3D_DEFS.darwin and VBoxSVGA3DObjC_DEFS.darwin).
+   VBoxDD_DEFS.darwin    += VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+   if 0 # Use the OpenGL 3.2 Core profile (see also VBoxSVGA3D_DEFS.darwin and VBoxSVGA3DObjC_DEFS.darwin).
+    VBoxDD_DEFS.darwin   += VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE=3.2 VBOX_VMSVGA3D_OTHER_OGL_PROFILE=2.1
+   else
+    VBoxDD_DEFS.darwin   += VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE=2.1 VBOX_VMSVGA3D_OTHER_OGL_PROFILE=3.2
+   endif
   endif
   Graphics/DevVGA-SVGA3d-ogl.cpp_CXXFLAGS.darwin = -F$(VBOX_PATH_MACOSX_SDK_10_7)/System/Library/Frameworks/
@@ -1429,5 +1434,10 @@
  	USE_WIN32_OPENGL \
  	VBOX_WINE_WITHOUT_LIBWINE
- VBoxSVGA3D_DEFS.darwin += VBOX_VMSVGA3D_USE_OPENGL_CORE  # Use the OpenGL 3.2 Core profile (VBoxSVGA3D_DEFS.darwin).
+ VBoxSVGA3D_DEFS.darwin  += VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+ if 0 # Use the OpenGL 3.2 Core profile (VBoxSVGA3D_DEFS.darwin).
+  VBoxSVGA3D_DEFS.darwin += VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE=3.2 VBOX_VMSVGA3D_OTHER_OGL_PROFILE=2.1
+ else
+  VBoxSVGA3D_DEFS.darwin += VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE=2.1 VBOX_VMSVGA3D_OTHER_OGL_PROFILE=3.2
+ endif
 
  # WINE relies on a gcc 4.4 feature but we have 4.2 on Darwin
Index: /trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m	(revision 53754)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m	(revision 53755)
@@ -238,5 +238,5 @@
 # define CR_OVERLAY_BIT         RT_BIT_32(8)
 # define CR_PBUFFER_BIT         RT_BIT_32(9)
-# define VMSVGA3D_LEGACY_PROFILE_BIT RT_BIT_32(31)
+# define VMSVGA3D_NON_DEFAULT_PROFILE_BIT RT_BIT_32(31)
 # define CR_ALL_BITS            UINT32_C(0x800003ff)
 
@@ -311,5 +311,5 @@
 
 
-#endif
+#endif /* IN_VMSVGA3D */
 
 
@@ -318,4 +318,5 @@
 {
 #ifdef IN_VMSVGA3D
+    return [NSOpenGLContext currentContext];
 #else
     GET_CONTEXT(pCtxInfo);
@@ -325,14 +326,14 @@
         return pCtxInfo->context;
     }
-#endif
-
     return nil;
+#endif
 }
 
 static bool vboxCtxSyncCurrentInfo(void)
 {
+#ifdef IN_VMSVGA3D
+    return false;
+#else
     bool fAdjusted = false;
-#ifdef IN_VMSVGA3D
-#else
     GET_CONTEXT(pCtxInfo);
     NSOpenGLContext *pCtx = [NSOpenGLContext currentContext];
@@ -354,7 +355,7 @@
         fAdjusted = true;
     }
-#endif
     
     return fAdjusted;
+#endif
 }
 
@@ -2026,4 +2027,18 @@
         return;
     }
+
+#ifdef IN_VMSVGA3D
+    if (!m_pSharedGLCtx)
+    {
+        Assert(!m_fDataVisible);
+        Assert(!m_fCleanupNeeded);
+        if (![self vboxSharedCtxCreate])
+        {
+            COCOA_LOG_FLOW(("%s: returns - vboxSharedCtxCreate failed\n", __PRETTY_FUNCTION__));
+            return;
+        }
+        Assert(m_pSharedGLCtx);
+    }
+#endif
     
     const VBOXVR_SCR_COMPOSITOR *pCompositor;
@@ -2074,5 +2089,7 @@
     {
         DEBUG_MSG(("%s: NeedCleanup\n", __PRETTY_FUNCTION__));
+#ifndef IN_VMSVGA3D /** @todo VMSVGA3 */
         Assert(m_fCleanupNeeded);
+#endif
         CrVrScrCompositorInit(&TmpCompositor, NULL);
         pCompositor = &TmpCompositor;
@@ -2565,9 +2582,5 @@
     {
 #ifdef IN_VMSVGA3D
-# ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
-        NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
-# else
-        NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy,
-# endif
+        NSOpenGLPFAOpenGLProfile, (NSOpenGLPixelFormatAttribute)0,
 #endif
         NSOpenGLPFAAccelerated,
@@ -2578,12 +2591,8 @@
 
 #ifdef IN_VMSVGA3D
-    if (fVisParams & VMSVGA3D_LEGACY_PROFILE_BIT)
-    {
-# ifdef VBOX_VMSVGA3D_USE_OPENGL_CORE
-        attribs[1] = NSOpenGLProfileVersionLegacy;
-# else
-        AssertFailed();
-# endif
-    }
+    if (fVisParams & VMSVGA3D_NON_DEFAULT_PROFILE_BIT)
+        attribs[1] = VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE >= 3.2 ? NSOpenGLProfileVersionLegacy :  NSOpenGLProfileVersion3_2Core;
+    else
+        attribs[1] = VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE >= 3.2 ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy;
 #endif
 
@@ -2984,7 +2993,8 @@
  */
 
-VMSVGA3D_DECL(void) vmsvga3dCocoaCreateContext(NativeNSOpenGLContextRef *ppCtx, NativeNSOpenGLContextRef pSharedCtx, bool fLegacy)
-{
-    cocoaGLCtxCreate(ppCtx, CR_ALPHA_BIT | CR_DEPTH_BIT | CR_DOUBLE_BIT | (fLegacy ? VMSVGA3D_LEGACY_PROFILE_BIT : 0), 
+VMSVGA3D_DECL(void) vmsvga3dCocoaCreateContext(NativeNSOpenGLContextRef *ppCtx, NativeNSOpenGLContextRef pSharedCtx, 
+                                               bool fOtherProfile)
+{
+    cocoaGLCtxCreate(ppCtx, CR_ALPHA_BIT | CR_DEPTH_BIT | CR_DOUBLE_BIT | (fOtherProfile ? VMSVGA3D_NON_DEFAULT_PROFILE_BIT : 0), 
                      pSharedCtx);
 }
