You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
663 lines
21 KiB
663 lines
21 KiB
/*-------------------------------------------------------------------------
|
|
* 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_EXT_colorspace
|
|
#define WGL_COLORSPACE_EXT 0x309D
|
|
#define WGL_COLORSPACE_SRGB_EXT 0x3089
|
|
#define WGL_COLORSPACE_LINEAR_EXT 0x308A
|
|
|
|
// 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
|
|
{
|
|
std::vector<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,
|
|
};
|
|
if (getLibrary()->isWglExtensionSupported("WGL_EXT_colorspace"))
|
|
s_attribsToQuery.push_back(WGL_COLORSPACE_EXT);
|
|
|
|
const Functions& wgl = m_library->getFunctions();
|
|
std::map<int, int> values;
|
|
|
|
getPixelFormatAttribs(wgl, deviceCtx, pixelFormat, static_cast<int>(s_attribsToQuery.size()), s_attribsToQuery.data(), &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];
|
|
info.sRGB = (getLibrary()->isWglExtensionSupported("WGL_EXT_colorspace")) ? (values[WGL_COLORSPACE_EXT] == WGL_COLORSPACE_SRGB_EXT) : false;
|
|
|
|
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
|