mirror of
https://github.com/glfw/glfw.git
synced 2025-06-16 20:47:43 +00:00
Added support for choosing the rendering gpu using wgl_nv_affinity
extension. Added Native API call to get the device context.
This commit is contained in:
parent
a18b187494
commit
2e99b10800
@ -188,6 +188,11 @@ used by the context. This can be one of `GLFW_NO_RESET_NOTIFICATION` or
|
|||||||
`GLFW_LOSE_CONTEXT_ON_RESET`, or `GLFW_NO_ROBUSTNESS` to not request
|
`GLFW_LOSE_CONTEXT_ON_RESET`, or `GLFW_NO_ROBUSTNESS` to not request
|
||||||
a robustness strategy.
|
a robustness strategy.
|
||||||
|
|
||||||
|
The `GLFW_AFFINITY_GPU` hint specifies which GPU should render OpenGL commands
|
||||||
|
for the associated context. This uses the WGL_NV_gpu_affinity extension, and is
|
||||||
|
only available on windows systems. The value corresponds with an index position
|
||||||
|
returned from a call to wglEnumGpusNV(...). Note that if sharing context resources
|
||||||
|
with another window, both windows must have the same affinity gpu mask.
|
||||||
|
|
||||||
@subsection window_hints_values Supported and default values
|
@subsection window_hints_values Supported and default values
|
||||||
|
|
||||||
@ -218,6 +223,7 @@ a robustness strategy.
|
|||||||
| `GLFW_OPENGL_FORWARD_COMPAT` | `GL_FALSE` | `GL_TRUE` or `GL_FALSE` |
|
| `GLFW_OPENGL_FORWARD_COMPAT` | `GL_FALSE` | `GL_TRUE` or `GL_FALSE` |
|
||||||
| `GLFW_OPENGL_DEBUG_CONTEXT` | `GL_FALSE` | `GL_TRUE` or `GL_FALSE` |
|
| `GLFW_OPENGL_DEBUG_CONTEXT` | `GL_FALSE` | `GL_TRUE` or `GL_FALSE` |
|
||||||
| `GLFW_OPENGL_PROFILE` | `GLFW_OPENGL_ANY_PROFILE` | `GLFW_OPENGL_ANY_PROFILE`, `GLFW_OPENGL_COMPAT_PROFILE` or `GLFW_OPENGL_CORE_PROFILE` |
|
| `GLFW_OPENGL_PROFILE` | `GLFW_OPENGL_ANY_PROFILE` | `GLFW_OPENGL_ANY_PROFILE`, `GLFW_OPENGL_COMPAT_PROFILE` or `GLFW_OPENGL_CORE_PROFILE` |
|
||||||
|
| `GLFW_AFFINITY_GPU` | -1 | 0 to maximum number of GPUs |
|
||||||
|
|
||||||
|
|
||||||
@section window_close Window close flag
|
@section window_close Window close flag
|
||||||
|
@ -511,6 +511,7 @@ extern "C" {
|
|||||||
#define GLFW_SAMPLES 0x0002100D
|
#define GLFW_SAMPLES 0x0002100D
|
||||||
#define GLFW_SRGB_CAPABLE 0x0002100E
|
#define GLFW_SRGB_CAPABLE 0x0002100E
|
||||||
#define GLFW_REFRESH_RATE 0x0002100F
|
#define GLFW_REFRESH_RATE 0x0002100F
|
||||||
|
#define GLFW_AFFINITY_GPU 0x00021010
|
||||||
|
|
||||||
#define GLFW_CLIENT_API 0x00022001
|
#define GLFW_CLIENT_API 0x00022001
|
||||||
#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002
|
#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002
|
||||||
|
@ -115,6 +115,11 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
|
|||||||
* @ingroup native
|
* @ingroup native
|
||||||
*/
|
*/
|
||||||
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
|
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
|
||||||
|
/*! @brief Returns the `HDC` of the specified window.
|
||||||
|
* @return The `HDC` of the specified window.
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI HDC glfwGetWGLDC(GLFWwindow* window);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
|
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
|
||||||
|
@ -299,6 +299,7 @@ struct _GLFWlibrary
|
|||||||
GLboolean glDebug;
|
GLboolean glDebug;
|
||||||
int glProfile;
|
int glProfile;
|
||||||
int glRobustness;
|
int glRobustness;
|
||||||
|
int gpu;
|
||||||
} hints;
|
} hints;
|
||||||
|
|
||||||
double cursorPosX, cursorPosY;
|
double cursorPosX, cursorPosY;
|
||||||
|
@ -46,6 +46,9 @@ static void initWGLExtensions(_GLFWwindow* window)
|
|||||||
window->wgl.GetExtensionsStringARB = NULL;
|
window->wgl.GetExtensionsStringARB = NULL;
|
||||||
window->wgl.GetExtensionsStringEXT = NULL;
|
window->wgl.GetExtensionsStringEXT = NULL;
|
||||||
window->wgl.CreateContextAttribsARB = NULL;
|
window->wgl.CreateContextAttribsARB = NULL;
|
||||||
|
window->wgl.CreateAffinityDCNV = NULL;
|
||||||
|
window->wgl.DeleteDCNV = NULL;
|
||||||
|
window->wgl.EnumGpusNV = NULL;
|
||||||
|
|
||||||
// This needs to include every extension used below except for
|
// This needs to include every extension used below except for
|
||||||
// WGL_ARB_extensions_string and WGL_EXT_extensions_string
|
// WGL_ARB_extensions_string and WGL_EXT_extensions_string
|
||||||
@ -57,6 +60,7 @@ static void initWGLExtensions(_GLFWwindow* window)
|
|||||||
window->wgl.ARB_create_context_robustness = GL_FALSE;
|
window->wgl.ARB_create_context_robustness = GL_FALSE;
|
||||||
window->wgl.EXT_swap_control = GL_FALSE;
|
window->wgl.EXT_swap_control = GL_FALSE;
|
||||||
window->wgl.ARB_pixel_format = GL_FALSE;
|
window->wgl.ARB_pixel_format = GL_FALSE;
|
||||||
|
window->wgl.NV_gpu_affinity = GL_FALSE;
|
||||||
|
|
||||||
window->wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
|
window->wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
|
||||||
wglGetProcAddress("wglGetExtensionsStringEXT");
|
wglGetProcAddress("wglGetExtensionsStringEXT");
|
||||||
@ -119,6 +123,21 @@ static void initWGLExtensions(_GLFWwindow* window)
|
|||||||
if (window->wgl.GetPixelFormatAttribivARB)
|
if (window->wgl.GetPixelFormatAttribivARB)
|
||||||
window->wgl.ARB_pixel_format = GL_TRUE;
|
window->wgl.ARB_pixel_format = GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_glfwPlatformExtensionSupported("WGL_NV_gpu_affinity"))
|
||||||
|
{
|
||||||
|
window->wgl.EnumGpusNV = (PFNWGLENUMGPUSNVPROC)
|
||||||
|
wglGetProcAddress("wglEnumGpusNV");
|
||||||
|
|
||||||
|
window->wgl.CreateAffinityDCNV = (PFNWGLCREATEAFFINITYDCNVPROC)
|
||||||
|
wglGetProcAddress("wglCreateAffinityDCNV");
|
||||||
|
|
||||||
|
window->wgl.DeleteDCNV = (PFNWGLDELETEDCNVPROC)
|
||||||
|
wglGetProcAddress("wglDeleteDCNV");
|
||||||
|
|
||||||
|
if (window->wgl.EnumGpusNV && window->wgl.CreateAffinityDCNV)
|
||||||
|
window->wgl.NV_gpu_affinity = GL_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the specified attribute of the specified pixel format
|
// Returns the specified attribute of the specified pixel format
|
||||||
@ -358,7 +377,7 @@ int _glfwCreateContext(_GLFWwindow* window,
|
|||||||
if (wndconfig->share)
|
if (wndconfig->share)
|
||||||
share = wndconfig->share->wgl.context;
|
share = wndconfig->share->wgl.context;
|
||||||
|
|
||||||
window->wgl.dc = GetDC(window->win32.handle);
|
window->wgl.dc = GetDC(window->win32.handle);
|
||||||
if (!window->wgl.dc)
|
if (!window->wgl.dc)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
@ -384,6 +403,30 @@ int _glfwCreateContext(_GLFWwindow* window,
|
|||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the nvidia affinity extension is available and the gpu has been set through a hint, create an affinityDC bound to a specific gpu.
|
||||||
|
// We create the affinityDC and then make an affinity context using the
|
||||||
|
// affinityDC. Because we are doing onscreen rendering and the affinityDC isn't bound to a window (i.e. doesn't contain a framebuffer),
|
||||||
|
// we make the affinitycontext current with the normal dc that is bound to the window.
|
||||||
|
if (window->wgl.NV_gpu_affinity && _glfw.hints.gpu != -1)
|
||||||
|
{
|
||||||
|
HGPUNV gpuMask;
|
||||||
|
window->wgl.EnumGpusNV(_glfw.hints.gpu, &gpuMask);
|
||||||
|
window->wgl.affinityDC = window->wgl.CreateAffinityDCNV(&gpuMask);
|
||||||
|
if (!window->wgl.affinityDC)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to create NV Affinity DC for window");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!SetPixelFormat(window->wgl.affinityDC, pixelFormat, &pfd))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to set selected pixel format for affinity DC");
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (window->wgl.ARB_create_context)
|
if (window->wgl.ARB_create_context)
|
||||||
{
|
{
|
||||||
int index = 0, mask = 0, flags = 0, strategy = 0;
|
int index = 0, mask = 0, flags = 0, strategy = 0;
|
||||||
@ -437,9 +480,19 @@ int _glfwCreateContext(_GLFWwindow* window,
|
|||||||
|
|
||||||
setWGLattrib(0, 0);
|
setWGLattrib(0, 0);
|
||||||
|
|
||||||
window->wgl.context = window->wgl.CreateContextAttribsARB(window->wgl.dc,
|
if (window->wgl.affinityDC)
|
||||||
share,
|
{
|
||||||
attribs);
|
window->wgl.context = window->wgl.CreateContextAttribsARB(window->wgl.affinityDC,
|
||||||
|
share,
|
||||||
|
attribs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window->wgl.context = window->wgl.CreateContextAttribsARB(window->wgl.dc,
|
||||||
|
share,
|
||||||
|
attribs);
|
||||||
|
}
|
||||||
|
|
||||||
if (!window->wgl.context)
|
if (!window->wgl.context)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
@ -449,7 +502,11 @@ int _glfwCreateContext(_GLFWwindow* window,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
window->wgl.context = wglCreateContext(window->wgl.dc);
|
if (window->wgl.affinityDC)
|
||||||
|
window->wgl.context = wglCreateContext(window->wgl.affinityDC);
|
||||||
|
else
|
||||||
|
window->wgl.context = wglCreateContext(window->wgl.dc);
|
||||||
|
|
||||||
if (!window->wgl.context)
|
if (!window->wgl.context)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
@ -490,8 +547,14 @@ void _glfwDestroyContext(_GLFWwindow* window)
|
|||||||
if (window->wgl.dc)
|
if (window->wgl.dc)
|
||||||
{
|
{
|
||||||
ReleaseDC(window->win32.handle, window->wgl.dc);
|
ReleaseDC(window->win32.handle, window->wgl.dc);
|
||||||
window->wgl.dc = NULL;
|
window->wgl.dc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (window->wgl.affinityDC)
|
||||||
|
{
|
||||||
|
window->wgl.DeleteDCNV(window->wgl.affinityDC);
|
||||||
|
window->wgl.affinityDC = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Analyzes the specified context for possible recreation
|
// Analyzes the specified context for possible recreation
|
||||||
@ -570,6 +633,12 @@ int _glfwAnalyzeContext(const _GLFWwindow* window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (window->wgl.NV_gpu_affinity && _glfw.hints.gpu != -1)
|
||||||
|
{
|
||||||
|
// We have requested an nvidia affinity context with a specific gpu
|
||||||
|
required = GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (required)
|
if (required)
|
||||||
return _GLFW_RECREATION_REQUIRED;
|
return _GLFW_RECREATION_REQUIRED;
|
||||||
|
|
||||||
@ -668,3 +737,9 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
|
|||||||
return window->wgl.context;
|
return window->wgl.context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWAPI HDC glfwGetWGLDC(GLFWwindow* handle)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
return window->wgl.dc;
|
||||||
|
}
|
||||||
|
@ -50,6 +50,7 @@ typedef struct _GLFWcontextWGL
|
|||||||
{
|
{
|
||||||
// Platform specific window resources
|
// Platform specific window resources
|
||||||
HDC dc; // Private GDI device context
|
HDC dc; // Private GDI device context
|
||||||
|
HDC affinityDC; // gpu affinity device context
|
||||||
HGLRC context; // Permanent rendering context
|
HGLRC context; // Permanent rendering context
|
||||||
|
|
||||||
// Platform specific extensions (context specific)
|
// Platform specific extensions (context specific)
|
||||||
@ -58,6 +59,9 @@ typedef struct _GLFWcontextWGL
|
|||||||
PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT;
|
PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT;
|
||||||
PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
|
PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
|
||||||
PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
|
PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
|
||||||
|
PFNWGLCREATEAFFINITYDCNVPROC CreateAffinityDCNV;
|
||||||
|
PFNWGLDELETEDCNVPROC DeleteDCNV;
|
||||||
|
PFNWGLENUMGPUSNVPROC EnumGpusNV;
|
||||||
GLboolean EXT_swap_control;
|
GLboolean EXT_swap_control;
|
||||||
GLboolean ARB_multisample;
|
GLboolean ARB_multisample;
|
||||||
GLboolean ARB_framebuffer_sRGB;
|
GLboolean ARB_framebuffer_sRGB;
|
||||||
@ -66,6 +70,7 @@ typedef struct _GLFWcontextWGL
|
|||||||
GLboolean ARB_create_context_profile;
|
GLboolean ARB_create_context_profile;
|
||||||
GLboolean EXT_create_context_es2_profile;
|
GLboolean EXT_create_context_es2_profile;
|
||||||
GLboolean ARB_create_context_robustness;
|
GLboolean ARB_create_context_robustness;
|
||||||
|
GLboolean NV_gpu_affinity;
|
||||||
} _GLFWcontextWGL;
|
} _GLFWcontextWGL;
|
||||||
|
|
||||||
|
|
||||||
|
@ -284,6 +284,9 @@ void glfwDefaultWindowHints(void)
|
|||||||
_glfw.hints.alphaBits = 8;
|
_glfw.hints.alphaBits = 8;
|
||||||
_glfw.hints.depthBits = 24;
|
_glfw.hints.depthBits = 24;
|
||||||
_glfw.hints.stencilBits = 8;
|
_glfw.hints.stencilBits = 8;
|
||||||
|
|
||||||
|
// Set the default gpu to -1.
|
||||||
|
_glfw.hints.gpu = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI void glfwWindowHint(int target, int hint)
|
GLFWAPI void glfwWindowHint(int target, int hint)
|
||||||
@ -366,6 +369,9 @@ GLFWAPI void glfwWindowHint(int target, int hint)
|
|||||||
break;
|
break;
|
||||||
case GLFW_OPENGL_PROFILE:
|
case GLFW_OPENGL_PROFILE:
|
||||||
_glfw.hints.glProfile = hint;
|
_glfw.hints.glProfile = hint;
|
||||||
|
break;
|
||||||
|
case GLFW_AFFINITY_GPU:
|
||||||
|
_glfw.hints.gpu = hint;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, NULL);
|
_glfwInputError(GLFW_INVALID_ENUM, NULL);
|
||||||
|
Loading…
Reference in New Issue
Block a user