| /*------------------------------------------------------------------------- |
| * drawElements Quality Program Tester Core |
| * ---------------------------------------- |
| * |
| * Copyright 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief WGL Utilities. |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "tcuWGL.hpp" |
| #include "tcuWin32Window.hpp" |
| #include "deDynamicLibrary.hpp" |
| #include "deMemory.h" |
| #include "deStringUtil.hpp" |
| #include "tcuFormatUtil.hpp" |
| #include "gluRenderConfig.hpp" |
| #include "glwEnums.hpp" |
| |
| #include <map> |
| #include <sstream> |
| #include <iterator> |
| #include <set> |
| |
| #include <WinGDI.h> |
| |
| // WGL_ARB_pixel_format |
| #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 |
| #define WGL_DRAW_TO_WINDOW_ARB 0x2001 |
| #define WGL_DRAW_TO_BITMAP_ARB 0x2002 |
| #define WGL_ACCELERATION_ARB 0x2003 |
| #define WGL_NEED_PALETTE_ARB 0x2004 |
| #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 |
| #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 |
| #define WGL_SWAP_METHOD_ARB 0x2007 |
| #define WGL_NUMBER_OVERLAYS_ARB 0x2008 |
| #define WGL_NUMBER_UNDERLAYS_ARB 0x2009 |
| #define WGL_TRANSPARENT_ARB 0x200A |
| #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 |
| #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 |
| #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 |
| #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A |
| #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B |
| #define WGL_SHARE_DEPTH_ARB 0x200C |
| #define WGL_SHARE_STENCIL_ARB 0x200D |
| #define WGL_SHARE_ACCUM_ARB 0x200E |
| #define WGL_SUPPORT_GDI_ARB 0x200F |
| #define WGL_SUPPORT_OPENGL_ARB 0x2010 |
| #define WGL_DOUBLE_BUFFER_ARB 0x2011 |
| #define WGL_STEREO_ARB 0x2012 |
| #define WGL_PIXEL_TYPE_ARB 0x2013 |
| #define WGL_COLOR_BITS_ARB 0x2014 |
| #define WGL_RED_BITS_ARB 0x2015 |
| #define WGL_RED_SHIFT_ARB 0x2016 |
| #define WGL_GREEN_BITS_ARB 0x2017 |
| #define WGL_GREEN_SHIFT_ARB 0x2018 |
| #define WGL_BLUE_BITS_ARB 0x2019 |
| #define WGL_BLUE_SHIFT_ARB 0x201A |
| #define WGL_ALPHA_BITS_ARB 0x201B |
| #define WGL_ALPHA_SHIFT_ARB 0x201C |
| #define WGL_ACCUM_BITS_ARB 0x201D |
| #define WGL_ACCUM_RED_BITS_ARB 0x201E |
| #define WGL_ACCUM_GREEN_BITS_ARB 0x201F |
| #define WGL_ACCUM_BLUE_BITS_ARB 0x2020 |
| #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 |
| #define WGL_DEPTH_BITS_ARB 0x2022 |
| #define WGL_STENCIL_BITS_ARB 0x2023 |
| #define WGL_AUX_BUFFERS_ARB 0x2024 |
| |
| #define WGL_NO_ACCELERATION_ARB 0x2025 |
| #define WGL_GENERIC_ACCELERATION_ARB 0x2026 |
| #define WGL_FULL_ACCELERATION_ARB 0x2027 |
| |
| #define WGL_TYPE_RGBA_ARB 0x202B |
| #define WGL_TYPE_COLORINDEX_ARB 0x202C |
| |
| // WGL_ARB_color_buffer_float |
| #define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 |
| |
| // WGL_EXT_pixel_type_packed_float |
| #define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 |
| |
| // WGL_ARB_multisample |
| #define WGL_SAMPLE_BUFFERS_ARB 0x2041 |
| #define WGL_SAMPLES_ARB 0x2042 |
| |
| // WGL_ARB_create_context |
| #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 |
| #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 |
| #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 |
| #define WGL_CONTEXT_FLAGS_ARB 0x2094 |
| #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 |
| #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 |
| #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 |
| #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 |
| #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 |
| #define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 |
| |
| // WGL_ARB_create_context_robustness |
| #define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x0004 |
| #define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 |
| #define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 |
| #define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 |
| |
| // WGL ARB_create_context_no_error |
| #define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3 |
| |
| DE_BEGIN_EXTERN_C |
| |
| // WGL core |
| typedef HGLRC (WINAPI* wglCreateContextFunc) (HDC hdc); |
| typedef BOOL (WINAPI* wglDeleteContextFunc) (HGLRC hglrc); |
| typedef BOOL (WINAPI* wglMakeCurrentFunc) (HDC hdc, HGLRC hglrc); |
| typedef PROC (WINAPI* wglGetProcAddressFunc) (LPCSTR lpszProc); |
| typedef BOOL (WINAPI* wglSwapLayerBuffersFunc) (HDC dhc, UINT fuPlanes); |
| |
| // WGL_ARB_pixel_format |
| typedef BOOL (WINAPI* wglGetPixelFormatAttribivARBFunc) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); |
| typedef BOOL (WINAPI* wglGetPixelFormatAttribfvARBFunc) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); |
| typedef BOOL (WINAPI* wglChoosePixelFormatARBFunc) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); |
| |
| // WGL_ARB_create_context |
| typedef HGLRC (WINAPI* wglCreateContextAttribsARBFunc) (HDC hdc, HGLRC hshareContext, const int* attribList); |
| typedef const char* (WINAPI* wglGetExtensionsStringARBFunc) (HDC hdc); |
| |
| // WGL_EXT_swap_control |
| typedef BOOL (WINAPI* wglSwapIntervalEXTFunc) (int interval); |
| |
| DE_END_EXTERN_C |
| |
| namespace tcu |
| { |
| namespace wgl |
| { |
| |
| // Functions |
| |
| struct Functions |
| { |
| // Core |
| wglCreateContextFunc createContext; |
| wglDeleteContextFunc deleteContext; |
| wglMakeCurrentFunc makeCurrent; |
| wglGetProcAddressFunc getProcAddress; |
| wglSwapLayerBuffersFunc swapLayerBuffers; |
| |
| // WGL_ARB_pixel_format |
| wglGetPixelFormatAttribivARBFunc getPixelFormatAttribivARB; |
| wglGetPixelFormatAttribfvARBFunc getPixelFormatAttribfvARB; |
| wglChoosePixelFormatARBFunc choosePixelFormatARB; |
| |
| // WGL_ARB_create_context |
| wglCreateContextAttribsARBFunc createContextAttribsARB; |
| wglGetExtensionsStringARBFunc getExtensionsStringARB; |
| |
| // WGL_EXT_swap_control |
| wglSwapIntervalEXTFunc swapIntervalEXT; |
| |
| |
| Functions (void) |
| : createContext (DE_NULL) |
| , deleteContext (DE_NULL) |
| , makeCurrent (DE_NULL) |
| , getProcAddress (DE_NULL) |
| , swapLayerBuffers (DE_NULL) |
| , getPixelFormatAttribivARB (DE_NULL) |
| , getPixelFormatAttribfvARB (DE_NULL) |
| , choosePixelFormatARB (DE_NULL) |
| , createContextAttribsARB (DE_NULL) |
| , getExtensionsStringARB (DE_NULL) |
| { |
| } |
| }; |
| |
| // Library |
| |
| class Library |
| { |
| public: |
| Library (HINSTANCE instance); |
| ~Library (void); |
| |
| const Functions& getFunctions (void) const { return m_functions; } |
| const de::DynamicLibrary& getGLLibrary (void) const { return m_library; } |
| bool isWglExtensionSupported (const char* extName) const; |
| |
| private: |
| de::DynamicLibrary m_library; |
| Functions m_functions; |
| std::set<std::string> m_extensions; |
| }; |
| |
| Library::Library (HINSTANCE instance) |
| : m_library("opengl32.dll") |
| { |
| // Temporary 1x1 window for creating context |
| win32::Window tmpWindow(instance, 1, 1); |
| |
| // Load WGL core. |
| m_functions.createContext = (wglCreateContextFunc) m_library.getFunction("wglCreateContext"); |
| m_functions.deleteContext = (wglDeleteContextFunc) m_library.getFunction("wglDeleteContext"); |
| m_functions.getProcAddress = (wglGetProcAddressFunc) m_library.getFunction("wglGetProcAddress"); |
| m_functions.makeCurrent = (wglMakeCurrentFunc) m_library.getFunction("wglMakeCurrent"); |
| m_functions.swapLayerBuffers = (wglSwapLayerBuffersFunc) m_library.getFunction("wglSwapLayerBuffers"); |
| |
| if (!m_functions.createContext || |
| !m_functions.deleteContext || |
| !m_functions.getProcAddress || |
| !m_functions.makeCurrent || |
| !m_functions.swapLayerBuffers) |
| throw ResourceError("Failed to load core WGL functions"); |
| |
| { |
| PIXELFORMATDESCRIPTOR pixelFormatDesc; |
| deMemset(&pixelFormatDesc, 0, sizeof(pixelFormatDesc)); |
| |
| pixelFormatDesc.nSize = sizeof(pixelFormatDesc); |
| pixelFormatDesc.nVersion = 1; |
| pixelFormatDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; |
| pixelFormatDesc.iPixelType = PFD_TYPE_RGBA; |
| pixelFormatDesc.iLayerType = PFD_MAIN_PLANE; |
| |
| int pixelFormat = ChoosePixelFormat(tmpWindow.getDeviceContext(), &pixelFormatDesc); |
| if (!SetPixelFormat(tmpWindow.getDeviceContext(), pixelFormat, &pixelFormatDesc)) |
| throw ResourceError("Failed to set pixel format for temporary context creation"); |
| } |
| |
| // Create temporary context for loading extension functions. |
| HGLRC tmpCtx = m_functions.createContext(tmpWindow.getDeviceContext()); |
| if (!tmpCtx || !m_functions.makeCurrent(tmpWindow.getDeviceContext(), tmpCtx)) |
| { |
| if (tmpCtx) |
| m_functions.deleteContext(tmpCtx); |
| throw ResourceError("Failed to create temporary WGL context"); |
| } |
| |
| // WGL_ARB_pixel_format |
| m_functions.getPixelFormatAttribivARB = (wglGetPixelFormatAttribivARBFunc)m_functions.getProcAddress("wglGetPixelFormatAttribivARB"); |
| m_functions.getPixelFormatAttribfvARB = (wglGetPixelFormatAttribfvARBFunc)m_functions.getProcAddress("wglGetPixelFormatAttribfvARB"); |
| m_functions.choosePixelFormatARB = (wglChoosePixelFormatARBFunc)m_functions.getProcAddress("wglChoosePixelFormatARB"); |
| |
| // WGL_ARB_create_context |
| m_functions.createContextAttribsARB = (wglCreateContextAttribsARBFunc)m_functions.getProcAddress("wglCreateContextAttribsARB"); |
| m_functions.getExtensionsStringARB = (wglGetExtensionsStringARBFunc)m_functions.getProcAddress("wglGetExtensionsStringARB"); |
| |
| // WGL_EXT_swap_control |
| m_functions.swapIntervalEXT = (wglSwapIntervalEXTFunc)m_functions.getProcAddress("wglSwapIntervalEXT"); |
| |
| m_functions.makeCurrent(tmpWindow.getDeviceContext(), NULL); |
| m_functions.deleteContext(tmpCtx); |
| |
| if (!m_functions.getPixelFormatAttribivARB || |
| !m_functions.getPixelFormatAttribfvARB || |
| !m_functions.choosePixelFormatARB || |
| !m_functions.createContextAttribsARB || |
| !m_functions.getExtensionsStringARB) |
| throw ResourceError("Failed to load WGL extension functions"); |
| |
| const char* extensions = m_functions.getExtensionsStringARB(tmpWindow.getDeviceContext()); |
| std::istringstream extStream(extensions); |
| m_extensions = std::set<std::string>(std::istream_iterator<std::string>(extStream), |
| std::istream_iterator<std::string>()); |
| } |
| |
| Library::~Library (void) |
| { |
| } |
| |
| bool Library::isWglExtensionSupported (const char* extName) const |
| { |
| return m_extensions.find(extName) != m_extensions.end(); |
| } |
| |
| // Core |
| |
| Core::Core (HINSTANCE instance) |
| : m_library(new Library(instance)) |
| { |
| } |
| |
| Core::~Core (void) |
| { |
| delete m_library; |
| } |
| |
| std::vector<int> Core::getPixelFormats (HDC deviceCtx) const |
| { |
| const Functions& wgl = m_library->getFunctions(); |
| |
| int attribs[] = { WGL_NUMBER_PIXEL_FORMATS_ARB }; |
| int values[DE_LENGTH_OF_ARRAY(attribs)]; |
| |
| if (!wgl.getPixelFormatAttribivARB(deviceCtx, 0, 0, DE_LENGTH_OF_ARRAY(attribs), &attribs[0], &values[0])) |
| TCU_THROW(ResourceError, "Failed to query number of WGL pixel formats"); |
| |
| std::vector<int> pixelFormats(values[0]); |
| for (int i = 0; i < values[0]; i++) |
| pixelFormats[i] = i+1; |
| |
| return pixelFormats; |
| } |
| |
| static PixelFormatInfo::Acceleration translateAcceleration (int accel) |
| { |
| switch (accel) |
| { |
| case WGL_NO_ACCELERATION_ARB: return PixelFormatInfo::ACCELERATION_NONE; |
| case WGL_GENERIC_ACCELERATION_ARB: return PixelFormatInfo::ACCELERATION_GENERIC; |
| case WGL_FULL_ACCELERATION_ARB: return PixelFormatInfo::ACCELERATION_FULL; |
| default: return PixelFormatInfo::ACCELERATION_UNKNOWN; |
| } |
| } |
| |
| static PixelFormatInfo::PixelType translatePixelType (int type) |
| { |
| switch (type) |
| { |
| case WGL_TYPE_RGBA_ARB: return PixelFormatInfo::PIXELTYPE_RGBA; |
| case WGL_TYPE_RGBA_FLOAT_ARB: return PixelFormatInfo::PIXELTYPE_RGBA_FLOAT; |
| case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT: return PixelFormatInfo::PIXELTYPE_RGBA_UNSIGNED_FLOAT; |
| case WGL_TYPE_COLORINDEX_ARB: return PixelFormatInfo::PIXELTYPE_COLOR_INDEX; |
| default: return PixelFormatInfo::PIXELTYPE_UNKNOWN; |
| } |
| } |
| |
| static void getPixelFormatAttribs (const Functions& wgl, HDC deviceCtx, int pixelFormat, int numAttribs, const int* attribs, std::map<int, int>* dst) |
| { |
| std::vector<int> values (numAttribs); |
| |
| if (!wgl.getPixelFormatAttribivARB(deviceCtx, pixelFormat, 0, numAttribs, &attribs[0], &values[0])) |
| TCU_THROW(ResourceError, "Pixel format query failed"); |
| |
| for (int ndx = 0; ndx < numAttribs; ++ndx) |
| (*dst)[attribs[ndx]] = values[ndx]; |
| } |
| |
| PixelFormatInfo Core::getPixelFormatInfo (HDC deviceCtx, int pixelFormat) const |
| { |
| static const int s_attribsToQuery[] = |
| { |
| WGL_DRAW_TO_WINDOW_ARB, |
| WGL_DRAW_TO_BITMAP_ARB, |
| WGL_ACCELERATION_ARB, |
| WGL_NEED_PALETTE_ARB, |
| WGL_NEED_SYSTEM_PALETTE_ARB, |
| WGL_NUMBER_OVERLAYS_ARB, |
| WGL_NUMBER_UNDERLAYS_ARB, |
| WGL_SUPPORT_OPENGL_ARB, |
| WGL_DOUBLE_BUFFER_ARB, |
| WGL_STEREO_ARB, |
| WGL_PIXEL_TYPE_ARB, |
| WGL_RED_BITS_ARB, |
| WGL_GREEN_BITS_ARB, |
| WGL_BLUE_BITS_ARB, |
| WGL_ALPHA_BITS_ARB, |
| WGL_ACCUM_BITS_ARB, |
| WGL_DEPTH_BITS_ARB, |
| WGL_STENCIL_BITS_ARB, |
| WGL_AUX_BUFFERS_ARB, |
| WGL_SAMPLE_BUFFERS_ARB, |
| WGL_SAMPLES_ARB, |
| }; |
| const Functions& wgl = m_library->getFunctions(); |
| std::map<int, int> values; |
| |
| getPixelFormatAttribs(wgl, deviceCtx, pixelFormat, DE_LENGTH_OF_ARRAY(s_attribsToQuery), &s_attribsToQuery[0], &values); |
| |
| // Translate values. |
| PixelFormatInfo info; |
| |
| info.pixelFormat = pixelFormat; |
| info.surfaceTypes |= (values[WGL_DRAW_TO_WINDOW_ARB] ? PixelFormatInfo::SURFACE_WINDOW : 0); |
| info.surfaceTypes |= (values[WGL_DRAW_TO_BITMAP_ARB] ? PixelFormatInfo::SURFACE_PIXMAP : 0); |
| info.acceleration = translateAcceleration(values[WGL_ACCELERATION_ARB]); |
| info.needPalette = values[WGL_NEED_PALETTE_ARB] != 0; |
| info.needSystemPalette = values[WGL_NEED_SYSTEM_PALETTE_ARB] != 0; |
| info.numOverlays = values[WGL_NUMBER_OVERLAYS_ARB] != 0; |
| info.numUnderlays = values[WGL_NUMBER_UNDERLAYS_ARB] != 0; |
| info.supportOpenGL = values[WGL_SUPPORT_OPENGL_ARB] != 0; |
| info.doubleBuffer = values[WGL_DOUBLE_BUFFER_ARB] != 0; |
| info.stereo = values[WGL_STEREO_ARB] != 0; |
| info.pixelType = translatePixelType(values[WGL_PIXEL_TYPE_ARB]); |
| info.redBits = values[WGL_RED_BITS_ARB]; |
| info.greenBits = values[WGL_GREEN_BITS_ARB]; |
| info.blueBits = values[WGL_BLUE_BITS_ARB]; |
| info.alphaBits = values[WGL_ALPHA_BITS_ARB]; |
| info.accumBits = values[WGL_ACCUM_BITS_ARB]; |
| info.depthBits = values[WGL_DEPTH_BITS_ARB]; |
| info.stencilBits = values[WGL_STENCIL_BITS_ARB]; |
| info.numAuxBuffers = values[WGL_AUX_BUFFERS_ARB]; |
| info.sampleBuffers = values[WGL_SAMPLE_BUFFERS_ARB]; |
| info.samples = values[WGL_SAMPLES_ARB]; |
| |
| return info; |
| } |
| |
| // Context |
| |
| Context::Context (const Core* core, |
| HDC deviceCtx, |
| const Context* sharedContext, |
| glu::ContextType ctxType, |
| int pixelFormat, |
| glu::ResetNotificationStrategy resetNotificationStrategy) |
| : m_core (core) |
| , m_deviceCtx (deviceCtx) |
| , m_context (0) |
| { |
| const Functions& wgl = core->getLibrary()->getFunctions(); |
| std::vector<int> attribList; |
| |
| // Context version and profile |
| { |
| int profileBit = 0; |
| HGLRC sharedCtx = DE_NULL; |
| int minor = ctxType.getMinorVersion(); |
| int major = ctxType.getMajorVersion(); |
| |
| switch (ctxType.getProfile()) |
| { |
| case glu::PROFILE_CORE: |
| profileBit = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; |
| if (major == 3 && minor < 3) |
| minor = 3; |
| break; |
| |
| case glu::PROFILE_ES: |
| profileBit = WGL_CONTEXT_ES_PROFILE_BIT_EXT; |
| break; |
| |
| case glu::PROFILE_COMPATIBILITY: |
| profileBit = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; |
| break; |
| |
| default: |
| TCU_THROW(NotSupportedError, "Unsupported context type for WGL"); |
| } |
| |
| attribList.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB); |
| attribList.push_back(major); |
| attribList.push_back(WGL_CONTEXT_MINOR_VERSION_ARB); |
| attribList.push_back(minor); |
| attribList.push_back(WGL_CONTEXT_PROFILE_MASK_ARB); |
| attribList.push_back(profileBit); |
| } |
| |
| // Context flags |
| { |
| int flags = 0; |
| |
| if ((ctxType.getFlags() & glu::CONTEXT_FORWARD_COMPATIBLE) != 0) |
| { |
| if (glu::isContextTypeES(ctxType)) |
| TCU_THROW(InternalError, "Only OpenGL core contexts can be forward-compatible"); |
| |
| flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; |
| } |
| |
| if ((ctxType.getFlags() & glu::CONTEXT_DEBUG) != 0) |
| flags |= WGL_CONTEXT_DEBUG_BIT_ARB; |
| |
| if ((ctxType.getFlags() & glu::CONTEXT_ROBUST) != 0) |
| flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB; |
| |
| if ((ctxType.getFlags() & glu::CONTEXT_NO_ERROR) != 0) |
| { |
| if (core->getLibrary()->isWglExtensionSupported("WGL_ARB_create_context_no_error")) |
| { |
| attribList.push_back(WGL_CONTEXT_OPENGL_NO_ERROR_ARB); |
| attribList.push_back(1); |
| } |
| else |
| TCU_THROW(NotSupportedError, "WGL_ARB_create_context_no_error is required for creating no-error contexts"); |
| } |
| |
| if (flags != 0) |
| { |
| attribList.push_back(WGL_CONTEXT_FLAGS_ARB); |
| attribList.push_back(flags); |
| } |
| } |
| |
| if (resetNotificationStrategy != glu::RESET_NOTIFICATION_STRATEGY_NOT_SPECIFIED) |
| { |
| attribList.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB); |
| |
| if (resetNotificationStrategy == glu::RESET_NOTIFICATION_STRATEGY_NO_RESET_NOTIFICATION) |
| attribList.push_back(WGL_NO_RESET_NOTIFICATION_ARB); |
| else if (resetNotificationStrategy == glu::RESET_NOTIFICATION_STRATEGY_LOSE_CONTEXT_ON_RESET) |
| attribList.push_back(WGL_LOSE_CONTEXT_ON_RESET_ARB); |
| else |
| TCU_THROW(InternalError, "Unknown reset notification strategy"); |
| } |
| |
| // Set pixel format |
| { |
| PIXELFORMATDESCRIPTOR pixelFormatDesc; |
| deMemset(&pixelFormatDesc, 0, sizeof(pixelFormatDesc)); |
| |
| if (!DescribePixelFormat(deviceCtx, pixelFormat, sizeof(pixelFormatDesc), &pixelFormatDesc)) |
| throw ResourceError("DescribePixelFormat() failed"); |
| |
| if (!SetPixelFormat(deviceCtx, pixelFormat, &pixelFormatDesc)) |
| throw ResourceError("Failed to set pixel format"); |
| } |
| |
| HGLRC sharedCtx = DE_NULL; |
| if (DE_NULL != sharedContext) |
| sharedCtx = sharedContext->m_context; |
| |
| // Terminate attribList |
| attribList.push_back(0); |
| |
| // Create context |
| m_context = wgl.createContextAttribsARB(deviceCtx, sharedCtx, &attribList[0]); |
| |
| if (!m_context) |
| TCU_THROW(ResourceError, "Failed to create WGL context"); |
| |
| if (!wgl.makeCurrent(deviceCtx, m_context)) |
| { |
| wgl.deleteContext(m_context); |
| TCU_THROW(ResourceError, "wglMakeCurrent() failed"); |
| } |
| |
| if (core->getLibrary()->isWglExtensionSupported("WGL_EXT_swap_control")) |
| core->getLibrary()->getFunctions().swapIntervalEXT(0); |
| } |
| |
| Context::~Context (void) |
| { |
| const Functions& wgl = m_core->getLibrary()->getFunctions(); |
| |
| wgl.makeCurrent(m_deviceCtx, NULL); |
| wgl.deleteContext(m_context); |
| } |
| |
| FunctionPtr Context::getGLFunction (const char* name) const |
| { |
| FunctionPtr ptr = DE_NULL; |
| |
| // Try first with wglGeProcAddress() |
| ptr = (FunctionPtr)m_core->getLibrary()->getFunctions().getProcAddress(name); |
| |
| // Fall-back to dynlib |
| if (!ptr) |
| ptr = (FunctionPtr)m_core->getLibrary()->getGLLibrary().getFunction(name); |
| |
| return ptr; |
| } |
| |
| void Context::makeCurrent (void) |
| { |
| const Functions& wgl = m_core->getLibrary()->getFunctions(); |
| if (!wgl.makeCurrent(m_deviceCtx, m_context)) |
| TCU_THROW(ResourceError, "wglMakeCurrent() failed"); |
| } |
| |
| void Context::swapBuffers (void) const |
| { |
| const Functions& wgl = m_core->getLibrary()->getFunctions(); |
| if (!wgl.swapLayerBuffers(m_deviceCtx, WGL_SWAP_MAIN_PLANE)) |
| TCU_THROW(ResourceError, "wglSwapBuffers() failed"); |
| } |
| |
| bool isSupportedByTests (const PixelFormatInfo& info) |
| { |
| if (!info.supportOpenGL) |
| return false; |
| |
| if (info.acceleration != wgl::PixelFormatInfo::ACCELERATION_FULL) |
| return false; |
| |
| if (info.pixelType != wgl::PixelFormatInfo::PIXELTYPE_RGBA) |
| return false; |
| |
| if ((info.surfaceTypes & wgl::PixelFormatInfo::SURFACE_WINDOW) == 0) |
| return false; |
| |
| if (info.needPalette || info.needSystemPalette) |
| return false; |
| |
| if (info.numOverlays != 0 || info.numUnderlays != 0) |
| return false; |
| |
| if (info.stereo) |
| return false; |
| |
| return true; |
| } |
| |
| int choosePixelFormat (const Core& wgl, HDC deviceCtx, const glu::RenderConfig& config) |
| { |
| std::vector<int> pixelFormats = wgl.getPixelFormats(deviceCtx); |
| |
| for (std::vector<int>::const_iterator fmtIter = pixelFormats.begin(); fmtIter != pixelFormats.end(); ++fmtIter) |
| { |
| const PixelFormatInfo info = wgl.getPixelFormatInfo(deviceCtx, *fmtIter); |
| |
| // Skip formats that are fundamentally not compatible with current tests |
| if (!isSupportedByTests(info)) |
| continue; |
| |
| if (config.redBits != glu::RenderConfig::DONT_CARE && |
| config.redBits != info.redBits) |
| continue; |
| |
| if (config.greenBits != glu::RenderConfig::DONT_CARE && |
| config.greenBits != info.greenBits) |
| continue; |
| |
| if (config.blueBits != glu::RenderConfig::DONT_CARE && |
| config.blueBits != info.blueBits) |
| continue; |
| |
| if (config.alphaBits != glu::RenderConfig::DONT_CARE && |
| config.alphaBits != info.alphaBits) |
| continue; |
| |
| if (config.depthBits != glu::RenderConfig::DONT_CARE && |
| config.depthBits != info.depthBits) |
| continue; |
| |
| if (config.stencilBits != glu::RenderConfig::DONT_CARE && |
| config.stencilBits != info.stencilBits) |
| continue; |
| |
| if (config.numSamples != glu::RenderConfig::DONT_CARE && |
| config.numSamples != info.samples) |
| continue; |
| |
| // Passed all tests - select this. |
| return info.pixelFormat; |
| } |
| |
| return -1; |
| } |
| |
| } // wgl |
| } // tcu |