From b9619f07a8fe6b95ac74ff8e3f17b12a182f453b Mon Sep 17 00:00:00 2001 From: combolek <4743344+combolek@users.noreply.github.com> Date: Tue, 15 Aug 2023 09:19:56 -0700 Subject: [PATCH] Added support for D3D11on12 on Windows 10+ via ANGLE. ANGLE's EGL supports D3D11on12 via the ANGLE_platform_angle_d3d11on12 extension. Enabling it requires passing the EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE attribute to eglGetPlatformDisplayEXT. Specifying custom EGL attributes is not currently exposed in GLFW and based on https://github.com/glfw/glfw/issues/1718#issuecomment-653236025 this may not even be desirable. Instead, this change adds a new value GLFW_ANGLE_PLATFORM_TYPE_D3D11ON12 for the ANGLE platform type glfwInitHint. When specified it implicitly sets the required EGL attribute. Note that D3D11on12 is supported only on executables specifically targetted for Windows 10, which requires a manifest. --- README.md | 1 + docs/intro.dox | 6 +++--- docs/news.dox | 1 + include/GLFW/glfw3.h | 1 + src/internal.h | 2 ++ src/win32_window.c | 26 ++++++++++++++++++++++---- tests/CMakeLists.txt | 2 +- tests/glfwinfo.c | 4 ++++ tests/glfwinfo.manifest | 40 ++++++++++++++++++++++++++++++++++++++++ 9 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 tests/glfwinfo.manifest diff --git a/README.md b/README.md index e3d18ec8..d3abf927 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,7 @@ information on what to include when reporting a bug. ## Changelog + - Added `GLFW_ANGLE_PLATFORM_TYPE_D3D11ON12` init hint for D3D11on12 support - Added `GLFW_PLATFORM` init hint for runtime platform selection (#1958) - Added `GLFW_ANY_PLATFORM`, `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`, `GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` and `GLFW_PLATFORM_NULL` symbols to diff --git a/docs/intro.dox b/docs/intro.dox index 36ec0ef5..9c0876fc 100644 --- a/docs/intro.dox +++ b/docs/intro.dox @@ -112,8 +112,8 @@ request when using OpenGL ES and EGL via platform type is unavailable, ANGLE will use its default. Possible values are one of `GLFW_ANGLE_PLATFORM_TYPE_NONE`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGL`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGLES`, `GLFW_ANGLE_PLATFORM_TYPE_D3D9`, -`GLFW_ANGLE_PLATFORM_TYPE_D3D11`, `GLFW_ANGLE_PLATFORM_TYPE_VULKAN` and -`GLFW_ANGLE_PLATFORM_TYPE_METAL`. +`GLFW_ANGLE_PLATFORM_TYPE_D3D11`, `GLFW_ANGLE_PLATFORM_TYPE_D3D11ON12`, +`GLFW_ANGLE_PLATFORM_TYPE_VULKAN` and `GLFW_ANGLE_PLATFORM_TYPE_METAL`. The ANGLE platform type is specified via the `EGL_ANGLE_platform_angle` extension. This extension is not used if this hint is @@ -159,7 +159,7 @@ Initialization hint | Default value | Supported v -------------------------------- | ------------------------------- | ---------------- @ref GLFW_PLATFORM | `GLFW_ANY_PLATFORM` | `GLFW_ANY_PLATFORM`, `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`, `GLFW_PLATFORM_X11`, `GLFW_PLATFORM_WAYLAND` or `GLFW_PLATFORM_NULL` @ref GLFW_JOYSTICK_HAT_BUTTONS | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` -@ref GLFW_ANGLE_PLATFORM_TYPE | `GLFW_ANGLE_PLATFORM_TYPE_NONE` | `GLFW_ANGLE_PLATFORM_TYPE_NONE`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGL`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGLES`, `GLFW_ANGLE_PLATFORM_TYPE_D3D9`, `GLFW_ANGLE_PLATFORM_TYPE_D3D11`, `GLFW_ANGLE_PLATFORM_TYPE_VULKAN` or `GLFW_ANGLE_PLATFORM_TYPE_METAL` +@ref GLFW_ANGLE_PLATFORM_TYPE | `GLFW_ANGLE_PLATFORM_TYPE_NONE` | `GLFW_ANGLE_PLATFORM_TYPE_NONE`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGL`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGLES`, `GLFW_ANGLE_PLATFORM_TYPE_D3D9`, `GLFW_ANGLE_PLATFORM_TYPE_D3D11`, `GLFW_ANGLE_PLATFORM_TYPE_D3D11ON12`, `GLFW_ANGLE_PLATFORM_TYPE_VULKAN` or `GLFW_ANGLE_PLATFORM_TYPE_METAL` @ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` @ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` @ref GLFW_X11_XCB_VULKAN_SURFACE | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` diff --git a/docs/news.dox b/docs/news.dox index e16267b2..c5d9d8e7 100644 --- a/docs/news.dox +++ b/docs/news.dox @@ -270,6 +270,7 @@ then GLFW will fail to initialize. - @ref GLFW_ANGLE_PLATFORM_TYPE_OPENGLES - @ref GLFW_ANGLE_PLATFORM_TYPE_D3D9 - @ref GLFW_ANGLE_PLATFORM_TYPE_D3D11 + - @ref GLFW_ANGLE_PLATFORM_TYPE_D3D11ON12 - @ref GLFW_ANGLE_PLATFORM_TYPE_VULKAN - @ref GLFW_ANGLE_PLATFORM_TYPE_METAL - @ref GLFW_X11_XCB_VULKAN_SURFACE diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 58b395cd..2c1d0dd2 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1161,6 +1161,7 @@ extern "C" { #define GLFW_ANGLE_PLATFORM_TYPE_OPENGLES 0x00037003 #define GLFW_ANGLE_PLATFORM_TYPE_D3D9 0x00037004 #define GLFW_ANGLE_PLATFORM_TYPE_D3D11 0x00037005 +#define GLFW_ANGLE_PLATFORM_TYPE_D3D11ON12 0x00037006 #define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007 #define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008 diff --git a/src/internal.h b/src/internal.h index fe0369aa..3b49c19d 100644 --- a/src/internal.h +++ b/src/internal.h @@ -114,6 +114,7 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint); #define EGLAPIENTRY #endif +#define EGL_TRUE 1 #define EGL_SUCCESS 0x3000 #define EGL_NOT_INITIALIZED 0x3001 #define EGL_BAD_ACCESS 0x3002 @@ -186,6 +187,7 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint); #define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208 #define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450 #define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489 +#define EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE 0x3488 #define EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE 0x348f typedef int EGLint; diff --git a/src/win32_window.c b/src/win32_window.c index 676640bf..cae9f540 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -2373,8 +2374,18 @@ const char* _glfwGetClipboardStringWin32(void) return _glfw.win32.clipboardString; } +#define SET_ATTRIB(a, v) \ +{ \ + assert(((size_t) index + 1) < sizeof(tmp_attribs) / sizeof(tmp_attribs[0])); \ + tmp_attribs[index++] = a; \ + tmp_attribs[index++] = v; \ +} + EGLenum _glfwGetEGLPlatformWin32(EGLint** attribs) { + EGLint tmp_attribs[8]; + int index = 0; + if (_glfw.egl.ANGLE_platform_angle) { int type = 0; @@ -2393,6 +2404,11 @@ EGLenum _glfwGetEGLPlatformWin32(EGLint** attribs) type = EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE; else if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_D3D11) type = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE; + else if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_D3D11ON12) + { + type = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE; + SET_ATTRIB(EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE, EGL_TRUE); + } } if (_glfw.egl.ANGLE_platform_angle_vulkan) @@ -2403,10 +2419,10 @@ EGLenum _glfwGetEGLPlatformWin32(EGLint** attribs) if (type) { - *attribs = _glfw_calloc(3, sizeof(EGLint)); - (*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE; - (*attribs)[1] = type; - (*attribs)[2] = EGL_NONE; + SET_ATTRIB(EGL_PLATFORM_ANGLE_TYPE_ANGLE, type); + SET_ATTRIB(EGL_NONE, EGL_NONE); + *attribs = _glfw_calloc(index, sizeof(EGLint)); + memcpy(*attribs, tmp_attribs, index * sizeof(EGLint)); return EGL_PLATFORM_ANGLE_ANGLE; } } @@ -2414,6 +2430,8 @@ EGLenum _glfwGetEGLPlatformWin32(EGLint** attribs) return 0; } +#undef SET_ATTRIB + EGLNativeDisplayType _glfwGetEGLNativeDisplayWin32(void) { return GetDC(_glfw.win32.helperWindowHandle); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f81cfeb9..099ba8f4 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -23,7 +23,7 @@ add_executable(allocator allocator.c ${GLAD_GL}) add_executable(clipboard clipboard.c ${GETOPT} ${GLAD_GL}) add_executable(events events.c ${GETOPT} ${GLAD_GL}) add_executable(msaa msaa.c ${GETOPT} ${GLAD_GL}) -add_executable(glfwinfo glfwinfo.c ${GETOPT} ${GLAD_GL} ${GLAD_VULKAN}) +add_executable(glfwinfo glfwinfo.c glfwinfo.manifest ${GETOPT} ${GLAD_GL} ${GLAD_VULKAN}) add_executable(iconify iconify.c ${GETOPT} ${GLAD_GL}) add_executable(monitors monitors.c ${GETOPT} ${GLAD_GL}) add_executable(reopen reopen.c ${GLAD_GL}) diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index 12acbccc..253a89bc 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -61,6 +61,7 @@ #define ANGLE_TYPE_OPENGLES "es" #define ANGLE_TYPE_D3D9 "d3d9" #define ANGLE_TYPE_D3D11 "d3d11" +#define ANGLE_TYPE_D3D11ON12 "d3d11on12" #define ANGLE_TYPE_VULKAN "vk" #define ANGLE_TYPE_METAL "mtl" @@ -129,6 +130,7 @@ static void usage(void) ANGLE_TYPE_OPENGLES ", " ANGLE_TYPE_D3D9 ", " ANGLE_TYPE_D3D11 ", " + ANGLE_TYPE_D3D11ON12 ", " ANGLE_TYPE_VULKAN " or " ANGLE_TYPE_METAL ")\n"); printf(" --graphics-switching request macOS graphics switching\n"); @@ -638,6 +640,8 @@ int main(int argc, char** argv) angle_type = GLFW_ANGLE_PLATFORM_TYPE_D3D9; else if (strcmp(optarg, ANGLE_TYPE_D3D11) == 0) angle_type = GLFW_ANGLE_PLATFORM_TYPE_D3D11; + else if (strcmp(optarg, ANGLE_TYPE_D3D11ON12) == 0) + angle_type = GLFW_ANGLE_PLATFORM_TYPE_D3D11ON12; else if (strcmp(optarg, ANGLE_TYPE_VULKAN) == 0) angle_type = GLFW_ANGLE_PLATFORM_TYPE_VULKAN; else if (strcmp(optarg, ANGLE_TYPE_METAL) == 0) diff --git a/tests/glfwinfo.manifest b/tests/glfwinfo.manifest new file mode 100644 index 00000000..8db331d3 --- /dev/null +++ b/tests/glfwinfo.manifest @@ -0,0 +1,40 @@ + + + + GLFW context creation and information tool + + + + + + + + + + + + + + + + + + + + + + +