/*------------------------------------------------------------------------- * 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 #include #include #include #include // 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); 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; 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 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"); 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::istream_iterator(extStream), std::istream_iterator()); } 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 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 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* dst) { std::vector 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 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 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"); } } 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 pixelFormats = wgl.getPixelFormats(deviceCtx); for (std::vector::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