radeonsi: fix shader disk cache key
[mesa.git] / src / gallium / state_trackers / wgl / stw_ext_context.c
index a3470ac35a5a94955f967f5958ffe977032e40f6..6326d20ba82e024c9fbd8177592914b889e39f51 100644 (file)
@@ -1,6 +1,5 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.11
  *
  * Copyright (C) 2011 Morgan Armand <morgan.devel@gmail.com>
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
  */
 
+#include <stdio.h>
 #include <windows.h>
 
 #define WGL_WGLEXT_PROTOTYPES
 
 #include "stw_icd.h"
 #include "stw_context.h"
+#include "stw_device.h"
+#include "stw_ext_context.h"
 
+#include "util/u_debug.h"
+
+
+wglCreateContext_t wglCreateContext_func = 0;
+wglDeleteContext_t wglDeleteContext_func = 0;
+
+
+/**
+ * The implementation of this function is tricky.  The OPENGL32.DLL library
+ * remaps the context IDs returned by our stw_create_context_attribs()
+ * function to different values returned to the caller of wglCreateContext().
+ * That is, DHGLRC (driver) handles are not equivalent to HGLRC (public)
+ * handles.
+ *
+ * So we need to generate a new HGLRC ID here.  We do that by calling
+ * the regular wglCreateContext() function.  Then, we replace the newly-
+ * created stw_context with a new stw_context that reflects the arguments
+ * to this function.
+ */
 HGLRC WINAPI
 wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int *attribList)
 {
+   HGLRC context;
+
    int majorVersion = 1, minorVersion = 0, layerPlane = 0;
    int contextFlags = 0x0;
    int profileMask = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
    int i;
    BOOL done = FALSE;
+   const int contextFlagsAll = (WGL_CONTEXT_DEBUG_BIT_ARB |
+                                WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB);
 
    /* parse attrib_list */
    if (attribList) {
@@ -67,53 +93,120 @@ wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int *attribList)
          default:
             /* bad attribute */
             SetLastError(ERROR_INVALID_PARAMETER);
-            return NULL;
+            return 0;
          }
       }
    }
 
+   /* check contextFlags */
+   if (contextFlags & ~contextFlagsAll) {
+      SetLastError(ERROR_INVALID_PARAMETER);
+      return NULL;
+   }
+
+   /* check profileMask */
+   if (profileMask != WGL_CONTEXT_CORE_PROFILE_BIT_ARB &&
+       profileMask != WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB &&
+       profileMask != WGL_CONTEXT_ES_PROFILE_BIT_EXT) {
+      SetLastError(ERROR_INVALID_PROFILE_ARB);
+      return NULL;
+   }
+
    /* check version (generate ERROR_INVALID_VERSION_ARB if bad) */
-   switch (majorVersion) {
-   case 1:
-      if (minorVersion < 0 || minorVersion > 5) {
-         SetLastError(ERROR_INVALID_VERSION_ARB);
-         return NULL;
-      }
-      break;
-   case 2:
-      if (minorVersion < 0 || minorVersion > 1) {
-         SetLastError(ERROR_INVALID_VERSION_ARB);
-         return NULL;
+   if (majorVersion <= 0 ||
+       minorVersion < 0 ||
+       (profileMask != WGL_CONTEXT_ES_PROFILE_BIT_EXT &&
+        ((majorVersion == 1 && minorVersion > 5) ||
+         (majorVersion == 2 && minorVersion > 1) ||
+         (majorVersion == 3 && minorVersion > 3) ||
+         (majorVersion == 4 && minorVersion > 5) ||
+         majorVersion > 4)) ||
+       (profileMask == WGL_CONTEXT_ES_PROFILE_BIT_EXT &&
+        ((majorVersion == 1 && minorVersion > 1) ||
+         (majorVersion == 2 && minorVersion > 0) ||
+         (majorVersion == 3 && minorVersion > 1) ||
+         majorVersion > 3))) {
+      SetLastError(ERROR_INVALID_VERSION_ARB);
+      return NULL;
+   }
+
+   if ((contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) &&
+       majorVersion < 3) {
+      SetLastError(ERROR_INVALID_VERSION_ARB);
+      return 0;
+   }
+
+   /* Get pointer to OPENGL32.DLL's wglCreate/DeleteContext() functions */
+   if (!wglCreateContext_func || !wglDeleteContext_func) {
+      /* Get the OPENGL32.DLL library */
+      HMODULE opengl_lib = GetModuleHandleA("opengl32.dll");
+      if (!opengl_lib) {
+         _debug_printf("wgl: GetModuleHandleA(\"opengl32.dll\") failed\n");
+         return 0;
       }
-      break;
-   case 3:
-      if (minorVersion < 0 || minorVersion > 3) {
-         SetLastError(ERROR_INVALID_VERSION_ARB);
-         return NULL;
+
+      /* Get pointer to wglCreateContext() function */
+      wglCreateContext_func = (wglCreateContext_t)
+         GetProcAddress(opengl_lib, "wglCreateContext");
+      if (!wglCreateContext_func) {
+         _debug_printf("wgl: failed to get wglCreateContext()\n");
+         return 0;
       }
-      break;
-   case 4:
-      if (minorVersion < 0 || minorVersion > 2) {
-         SetLastError(ERROR_INVALID_VERSION_ARB);
-         return NULL;
+
+      /* Get pointer to wglDeleteContext() function */
+      wglDeleteContext_func = (wglDeleteContext_t)
+         GetProcAddress(opengl_lib, "wglDeleteContext");
+      if (!wglDeleteContext_func) {
+         _debug_printf("wgl: failed to get wglDeleteContext()\n");
+         return 0;
       }
-      break;
-   default:
-      return NULL;
    }
 
-   if ((contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) && majorVersion < 3) {
-      SetLastError(ERROR_INVALID_VERSION_ARB);
-      return NULL;
+   /* Call wglCreateContext to get a valid context ID */
+   context = wglCreateContext_func(hDC);
+
+   if (context) {
+      /* Now replace the context we just created with a new one that reflects
+       * the attributes passed to this function.
+       */
+      DHGLRC dhglrc, c, share_dhglrc = 0;
+
+      /* Convert public HGLRC to driver DHGLRC */
+      if (stw_dev && stw_dev->callbacks.wglCbGetDhglrc) {
+         dhglrc = stw_dev->callbacks.wglCbGetDhglrc(context);
+         if (hShareContext)
+            share_dhglrc = stw_dev->callbacks.wglCbGetDhglrc(hShareContext);
+      }
+      else {
+         /* not using ICD */
+         dhglrc = (DHGLRC) context;
+         share_dhglrc = (DHGLRC) hShareContext;
+      }
+
+      c = stw_create_context_attribs(hDC, layerPlane, share_dhglrc,
+                                     majorVersion, minorVersion,
+                                     contextFlags, profileMask,
+                                     dhglrc);
+      if (!c) {
+         wglDeleteContext_func(context);
+         context = 0;
+      }
    }
 
-   /* check profileMask */
-   if (profileMask != WGL_CONTEXT_CORE_PROFILE_BIT_ARB &&
-       profileMask != WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) {
-      SetLastError(ERROR_INVALID_PROFILE_ARB);
-      return NULL;
+   return context;
+}
+
+
+/** Defined by WGL_ARB_make_current_read */
+BOOL APIENTRY
+wglMakeContextCurrentARB(HDC hDrawDC, HDC hReadDC, HGLRC hglrc)
+{
+   DHGLRC dhglrc = 0;
+
+   if (stw_dev && stw_dev->callbacks.wglCbGetDhglrc) {
+      /* Convert HGLRC to DHGLRC */
+      dhglrc = stw_dev->callbacks.wglCbGetDhglrc(hglrc);
    }
 
-   return (HGLRC) stw_create_context_attribs( hDC, layerPlane, (DHGLRC)(UINT_PTR)hShareContext,
-                                              majorVersion, minorVersion, contextFlags, profileMask );
+   return stw_make_current(hDrawDC, hReadDC, dhglrc);
 }