Path: blob/21.2-virgl/src/gallium/frontends/wgl/stw_ext_context.c
4561 views
/*1* Mesa 3-D graphics library2*3* Copyright (C) 2011 Morgan Armand <[email protected]>4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the "Software"),7* to deal in the Software without restriction, including without limitation8* the rights to use, copy, modify, merge, publish, distribute, sublicense,9* and/or sell copies of the Software, and to permit persons to whom the10* Software is furnished to do so, subject to the following conditions:11*12* The above copyright notice and this permission notice shall be included13* in all copies or substantial portions of the Software.14*15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS16* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL18* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR19* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,20* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR21* OTHER DEALINGS IN THE SOFTWARE.22*/2324#include <stdio.h>25#include <windows.h>2627#define WGL_WGLEXT_PROTOTYPES2829#include <GL/gl.h>30#include <GL/wglext.h>3132#include "gldrv.h"33#include "stw_context.h"34#include "stw_device.h"35#include "stw_ext_context.h"3637#include "util/u_debug.h"383940wglCreateContext_t wglCreateContext_func = 0;41wglDeleteContext_t wglDeleteContext_func = 0;424344/**45* The implementation of this function is tricky. The OPENGL32.DLL library46* remaps the context IDs returned by our stw_create_context_attribs()47* function to different values returned to the caller of wglCreateContext().48* That is, DHGLRC (driver) handles are not equivalent to HGLRC (public)49* handles.50*51* So we need to generate a new HGLRC ID here. We do that by calling52* the regular wglCreateContext() function. Then, we replace the newly-53* created stw_context with a new stw_context that reflects the arguments54* to this function.55*/56HGLRC WINAPI57wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int *attribList)58{59HGLRC context;6061int majorVersion = 1, minorVersion = 0, layerPlane = 0;62int contextFlags = 0x0;63int profileMask = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;64int i;65BOOL done = FALSE;66const int contextFlagsAll = (WGL_CONTEXT_DEBUG_BIT_ARB |67WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB);6869/* parse attrib_list */70if (attribList) {71for (i = 0; !done && attribList[i]; i++) {72switch (attribList[i]) {73case WGL_CONTEXT_MAJOR_VERSION_ARB:74majorVersion = attribList[++i];75break;76case WGL_CONTEXT_MINOR_VERSION_ARB:77minorVersion = attribList[++i];78break;79case WGL_CONTEXT_LAYER_PLANE_ARB:80layerPlane = attribList[++i];81break;82case WGL_CONTEXT_FLAGS_ARB:83contextFlags = attribList[++i];84break;85case WGL_CONTEXT_PROFILE_MASK_ARB:86profileMask = attribList[++i];87break;88case 0:89/* end of list */90done = TRUE;91break;92default:93/* bad attribute */94SetLastError(ERROR_INVALID_PARAMETER);95return 0;96}97}98}99100/* check contextFlags */101if (contextFlags & ~contextFlagsAll) {102SetLastError(ERROR_INVALID_PARAMETER);103return NULL;104}105106/* check profileMask */107if (profileMask != WGL_CONTEXT_CORE_PROFILE_BIT_ARB &&108profileMask != WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB &&109profileMask != WGL_CONTEXT_ES_PROFILE_BIT_EXT) {110SetLastError(ERROR_INVALID_PROFILE_ARB);111return NULL;112}113114/* check version (generate ERROR_INVALID_VERSION_ARB if bad) */115if (majorVersion <= 0 ||116minorVersion < 0 ||117(profileMask != WGL_CONTEXT_ES_PROFILE_BIT_EXT &&118((majorVersion == 1 && minorVersion > 5) ||119(majorVersion == 2 && minorVersion > 1) ||120(majorVersion == 3 && minorVersion > 3) ||121(majorVersion == 4 && minorVersion > 5) ||122majorVersion > 4)) ||123(profileMask == WGL_CONTEXT_ES_PROFILE_BIT_EXT &&124((majorVersion == 1 && minorVersion > 1) ||125(majorVersion == 2 && minorVersion > 0) ||126(majorVersion == 3 && minorVersion > 1) ||127majorVersion > 3))) {128SetLastError(ERROR_INVALID_VERSION_ARB);129return NULL;130}131132if ((contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) &&133majorVersion < 3) {134SetLastError(ERROR_INVALID_VERSION_ARB);135return 0;136}137138/* Get pointer to OPENGL32.DLL's wglCreate/DeleteContext() functions */139if (!wglCreateContext_func || !wglDeleteContext_func) {140/* Get the OPENGL32.DLL library */141HMODULE opengl_lib = GetModuleHandleA("opengl32.dll");142if (!opengl_lib) {143_debug_printf("wgl: GetModuleHandleA(\"opengl32.dll\") failed\n");144return 0;145}146147/* Get pointer to wglCreateContext() function */148wglCreateContext_func = (wglCreateContext_t)149GetProcAddress(opengl_lib, "wglCreateContext");150if (!wglCreateContext_func) {151_debug_printf("wgl: failed to get wglCreateContext()\n");152return 0;153}154155/* Get pointer to wglDeleteContext() function */156wglDeleteContext_func = (wglDeleteContext_t)157GetProcAddress(opengl_lib, "wglDeleteContext");158if (!wglDeleteContext_func) {159_debug_printf("wgl: failed to get wglDeleteContext()\n");160return 0;161}162}163164/* Call wglCreateContext to get a valid context ID */165context = wglCreateContext_func(hDC);166167if (context) {168/* Now replace the context we just created with a new one that reflects169* the attributes passed to this function.170*/171DHGLRC dhglrc, c, share_dhglrc = 0;172173/* Convert public HGLRC to driver DHGLRC */174if (stw_dev && stw_dev->callbacks.pfnGetDhglrc) {175dhglrc = stw_dev->callbacks.pfnGetDhglrc(context);176if (hShareContext)177share_dhglrc = stw_dev->callbacks.pfnGetDhglrc(hShareContext);178}179else {180/* not using ICD */181dhglrc = (DHGLRC)(INT_PTR)context;182share_dhglrc = (DHGLRC)(INT_PTR)hShareContext;183}184185c = stw_create_context_attribs(hDC, layerPlane, share_dhglrc,186majorVersion, minorVersion,187contextFlags, profileMask,188dhglrc);189if (!c) {190wglDeleteContext_func(context);191context = 0;192}193}194195return context;196}197198199/** Defined by WGL_ARB_make_current_read */200BOOL APIENTRY201wglMakeContextCurrentARB(HDC hDrawDC, HDC hReadDC, HGLRC hglrc)202{203DHGLRC dhglrc = 0;204205if (stw_dev && stw_dev->callbacks.pfnGetDhglrc) {206/* Convert HGLRC to DHGLRC */207dhglrc = stw_dev->callbacks.pfnGetDhglrc(hglrc);208}209210return stw_make_current(hDrawDC, hReadDC, dhglrc);211}212213214