mirror of
https://github.com/glfw/glfw.git
synced 2024-11-22 04:54:35 +00:00
Add basic Vulkan support
Added GLFW_INCLUDE_VULKAN. Added glfwVulkanSupported, glfwGetRequiredInstanceExtensions, glfwGetInstanceProcAddress, glfwGetPhysicalDevicePresentationSupport and glfwCreateWindowSurface. Added port of LunarG SDK tri example.
This commit is contained in:
parent
c2efe87cff
commit
9b75bffc88
1
.gitignore
vendored
1
.gitignore
vendored
@ -71,5 +71,6 @@ tests/tearing
|
|||||||
tests/threads
|
tests/threads
|
||||||
tests/title
|
tests/title
|
||||||
tests/version
|
tests/version
|
||||||
|
tests/vulkan
|
||||||
tests/windows
|
tests/windows
|
||||||
|
|
||||||
|
23
CMake/modules/FindVulkan.cmake
Normal file
23
CMake/modules/FindVulkan.cmake
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Find Vulkan
|
||||||
|
#
|
||||||
|
# VULKAN_INCLUDE_DIR
|
||||||
|
# VULKAN_LIBRARY
|
||||||
|
# VULKAN_FOUND
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS
|
||||||
|
"$ENV{VK_SDK_PATH}/Include")
|
||||||
|
find_library(VULKAN_LIBRARY NAMES vulkan-1 HINTS
|
||||||
|
"$ENV{VK_SDK_PATH}/Bin")
|
||||||
|
else()
|
||||||
|
find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS
|
||||||
|
"$ENV{VULKAN_SDK}/include")
|
||||||
|
find_library(VULKAN_LIBRARY NAMES vulkan HINTS
|
||||||
|
"$ENV{VULKAN_SDK}/lib")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(Vulkan DEFAULT_MSG VULKAN_LIBRARY VULKAN_INCLUDE_DIR)
|
||||||
|
|
||||||
|
mark_as_advanced(VULKAN_INCLUDE_DIR VULKAN_LIBRARY)
|
||||||
|
|
@ -66,6 +66,7 @@ endif()
|
|||||||
set(CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules")
|
set(CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules")
|
||||||
|
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
|
find_package(Vulkan)
|
||||||
|
|
||||||
if (GLFW_BUILD_DOCS)
|
if (GLFW_BUILD_DOCS)
|
||||||
set(DOXYGEN_SKIP_DOT TRUE)
|
set(DOXYGEN_SKIP_DOT TRUE)
|
||||||
|
16
README.md
16
README.md
@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
GLFW is a free, Open Source, multi-platform library for OpenGL and OpenGL ES
|
GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and
|
||||||
application development. It provides a simple, platform-independent API for
|
Vulkan application development. It provides a simple, platform-independent API
|
||||||
creating windows and contexts, reading input, handling events, etc.
|
for creating windows, contexts and surfaces, reading input, handling events, etc.
|
||||||
|
|
||||||
Version 3.2 is _not yet described_.
|
Version 3.2 is _not yet described_.
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ This will help both us and other people experiencing the same bug.
|
|||||||
|
|
||||||
GLFW itself needs only the headers and libraries for your window system. It
|
GLFW itself needs only the headers and libraries for your window system. It
|
||||||
does not need the headers for any context creation API (WGL, GLX, EGL, NSGL) or
|
does not need the headers for any context creation API (WGL, GLX, EGL, NSGL) or
|
||||||
client API (OpenGL, OpenGL ES) to enable support for them.
|
rendering API (OpenGL, OpenGL ES, Vulkan) to enable support for them.
|
||||||
|
|
||||||
GLFW bundles a number of dependencies in the `deps/` directory. These are only
|
GLFW bundles a number of dependencies in the `deps/` directory. These are only
|
||||||
used by the tests and examples and are not required to build the library.
|
used by the tests and examples and are not required to build the library.
|
||||||
@ -64,15 +64,22 @@ used by the tests and examples and are not required to build the library.
|
|||||||
- [linmath.h](https://github.com/datenwolf/linmath.h) for linear algebra in
|
- [linmath.h](https://github.com/datenwolf/linmath.h) for linear algebra in
|
||||||
examples
|
examples
|
||||||
|
|
||||||
|
The Vulkan example additionally requires the Vulkan SDK to be installed, or it
|
||||||
|
will not be included in the build.
|
||||||
|
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
- Added `glfwVulkanSupported`, `glfwGetRequiredInstanceExtensions`,
|
||||||
|
`glfwGetInstanceProcAddress`, `glfwGetPhysicalDevicePresentationSupport` and
|
||||||
|
`glfwCreateWindowSurface` for platform independent Vulkan support
|
||||||
- Added `glfwSetWindowSizeLimits` and `glfwSetWindowAspectRatio` for setting
|
- Added `glfwSetWindowSizeLimits` and `glfwSetWindowAspectRatio` for setting
|
||||||
absolute and relative window size limits
|
absolute and relative window size limits
|
||||||
- Added `glfwGetKeyName` for querying the layout-specific name of printable
|
- Added `glfwGetKeyName` for querying the layout-specific name of printable
|
||||||
keys
|
keys
|
||||||
- Added `GLFW_NO_API` for creating window without contexts
|
- Added `GLFW_NO_API` for creating window without contexts
|
||||||
- Added `GLFW_CONTEXT_NO_ERROR` context hint for `GL_KHR_no_error` support
|
- Added `GLFW_CONTEXT_NO_ERROR` context hint for `GL_KHR_no_error` support
|
||||||
|
- Added `GLFW_INCLUDE_VULKAN` for including the Vulkan header
|
||||||
- Added `GLFW_TRUE` and `GLFW_FALSE` as client API independent boolean values
|
- Added `GLFW_TRUE` and `GLFW_FALSE` as client API independent boolean values
|
||||||
- Added `glfwGetGLXWindow` to query the `GLXWindow` of a window
|
- Added `glfwGetGLXWindow` to query the `GLXWindow` of a window
|
||||||
- Added icons to examples on Windows and OS X
|
- Added icons to examples on Windows and OS X
|
||||||
@ -168,6 +175,7 @@ skills.
|
|||||||
- Osman Keskin
|
- Osman Keskin
|
||||||
- Cameron King
|
- Cameron King
|
||||||
- Peter Knut
|
- Peter Knut
|
||||||
|
- Christoph Kubisch
|
||||||
- Eric Larson
|
- Eric Larson
|
||||||
- Robin Leffmann
|
- Robin Leffmann
|
||||||
- Glenn Lewis
|
- Glenn Lewis
|
||||||
|
127
deps/vulkan/vk_platform.h
vendored
Normal file
127
deps/vulkan/vk_platform.h
vendored
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
//
|
||||||
|
// File: vk_platform.h
|
||||||
|
//
|
||||||
|
/*
|
||||||
|
** Copyright (c) 2014-2015 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
** copy of this software and/or associated documentation files (the
|
||||||
|
** "Materials"), to deal in the Materials without restriction, including
|
||||||
|
** without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||||
|
** permit persons to whom the Materials are furnished to do so, subject to
|
||||||
|
** the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included
|
||||||
|
** in all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __VK_PLATFORM_H__
|
||||||
|
#define __VK_PLATFORM_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
/*
|
||||||
|
***************************************************************************************************
|
||||||
|
* Platform-specific directives and type declarations
|
||||||
|
***************************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Platform-specific calling convention macros.
|
||||||
|
*
|
||||||
|
* Platforms should define these so that Vulkan clients call Vulkan commands
|
||||||
|
* with the same calling conventions that the Vulkan implementation expects.
|
||||||
|
*
|
||||||
|
* VKAPI_ATTR - Placed before the return type in function declarations.
|
||||||
|
* Useful for C++11 and GCC/Clang-style function attribute syntax.
|
||||||
|
* VKAPI_CALL - Placed after the return type in function declarations.
|
||||||
|
* Useful for MSVC-style calling convention syntax.
|
||||||
|
* VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
|
||||||
|
*
|
||||||
|
* Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
|
||||||
|
* Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
|
||||||
|
*/
|
||||||
|
#if defined(_WIN32)
|
||||||
|
// On Windows, Vulkan commands use the stdcall convention
|
||||||
|
#define VKAPI_ATTR
|
||||||
|
#define VKAPI_CALL __stdcall
|
||||||
|
#define VKAPI_PTR VKAPI_CALL
|
||||||
|
#elif defined(__ANDROID__) && defined(__ARM_EABI__) && !defined(__ARM_ARCH_7A__)
|
||||||
|
// Android does not support Vulkan in native code using the "armeabi" ABI.
|
||||||
|
#error "Vulkan requires the 'armeabi-v7a' or 'armeabi-v7a-hard' ABI on 32-bit ARM CPUs"
|
||||||
|
#elif defined(__ANDROID__) && defined(__ARM_ARCH_7A__)
|
||||||
|
// On Android/ARMv7a, Vulkan functions use the armeabi-v7a-hard calling
|
||||||
|
// convention, even if the application's native code is compiled with the
|
||||||
|
// armeabi-v7a calling convention.
|
||||||
|
#define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
|
||||||
|
#define VKAPI_CALL
|
||||||
|
#define VKAPI_PTR VKAPI_ATTR
|
||||||
|
#else
|
||||||
|
// On other platforms, use the default calling convention
|
||||||
|
#define VKAPI_ATTR
|
||||||
|
#define VKAPI_CALL
|
||||||
|
#define VKAPI_PTR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#if !defined(VK_NO_STDINT_H)
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER < 1600)
|
||||||
|
typedef signed __int8 int8_t;
|
||||||
|
typedef unsigned __int8 uint8_t;
|
||||||
|
typedef signed __int16 int16_t;
|
||||||
|
typedef unsigned __int16 uint16_t;
|
||||||
|
typedef signed __int32 int32_t;
|
||||||
|
typedef unsigned __int32 uint32_t;
|
||||||
|
typedef signed __int64 int64_t;
|
||||||
|
typedef unsigned __int64 uint64_t;
|
||||||
|
#else
|
||||||
|
#include <stdint.h>
|
||||||
|
#endif
|
||||||
|
#endif // !defined(VK_NO_STDINT_H)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
// Platform-specific headers required by platform window system extensions.
|
||||||
|
// These are enabled prior to #including "vulkan.h". The same enable then
|
||||||
|
// controls inclusion of the extension interfaces in vulkan.h.
|
||||||
|
|
||||||
|
#ifdef VK_USE_PLATFORM_ANDROID_KHR
|
||||||
|
#include <android/native_window.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VK_USE_PLATFORM_MIR_KHR
|
||||||
|
#include <mir_toolkit/client_types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||||
|
#include <wayland-client.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __VK_PLATFORM_H__
|
3775
deps/vulkan/vulkan.h
vendored
Normal file
3775
deps/vulkan/vulkan.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -674,6 +674,7 @@ INPUT = @GLFW_INTERNAL_DOCS@ \
|
|||||||
@GLFW_SOURCE_DIR@/docs/monitor.dox \
|
@GLFW_SOURCE_DIR@/docs/monitor.dox \
|
||||||
@GLFW_SOURCE_DIR@/docs/window.dox \
|
@GLFW_SOURCE_DIR@/docs/window.dox \
|
||||||
@GLFW_SOURCE_DIR@/docs/input.dox \
|
@GLFW_SOURCE_DIR@/docs/input.dox \
|
||||||
|
@GLFW_SOURCE_DIR@/docs/vulkan.dox \
|
||||||
@GLFW_SOURCE_DIR@/docs/rift.dox \
|
@GLFW_SOURCE_DIR@/docs/rift.dox \
|
||||||
@GLFW_SOURCE_DIR@/docs/compat.dox
|
@GLFW_SOURCE_DIR@/docs/compat.dox
|
||||||
|
|
||||||
@ -1590,7 +1591,8 @@ PREDEFINED = GLFWAPI= \
|
|||||||
GLFW_EXPOSE_NATIVE_GLX \
|
GLFW_EXPOSE_NATIVE_GLX \
|
||||||
GLFW_EXPOSE_NATIVE_COCOA \
|
GLFW_EXPOSE_NATIVE_COCOA \
|
||||||
GLFW_EXPOSE_NATIVE_NSGL \
|
GLFW_EXPOSE_NATIVE_NSGL \
|
||||||
GLFW_EXPOSE_NATIVE_EGL
|
GLFW_EXPOSE_NATIVE_EGL \
|
||||||
|
VK_VERSION_1_0
|
||||||
|
|
||||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
|
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
|
||||||
# this tag can be used to specify a list of macro names that should be expanded.
|
# this tag can be used to specify a list of macro names that should be expanded.
|
||||||
|
@ -80,6 +80,9 @@ header instead of the regular OpenGL header.
|
|||||||
`GLFW_INCLUDE_ES31` makes the GLFW header include the OpenGL ES 3.1 `GLES3/gl31.h`
|
`GLFW_INCLUDE_ES31` makes the GLFW header include the OpenGL ES 3.1 `GLES3/gl31.h`
|
||||||
header instead of the regular OpenGL header.
|
header instead of the regular OpenGL header.
|
||||||
|
|
||||||
|
`GLFW_INCLUDE_VULKAN` makes the GLFW header include the Vulkan `vulkan/vulkan.h`
|
||||||
|
header instead of the regular OpenGL header.
|
||||||
|
|
||||||
`GLFW_INCLUDE_NONE` makes the GLFW header not include any OpenGL or OpenGL ES API
|
`GLFW_INCLUDE_NONE` makes the GLFW header not include any OpenGL or OpenGL ES API
|
||||||
header. This is useful in combination with an extension loading library.
|
header. This is useful in combination with an extension loading library.
|
||||||
|
|
||||||
|
@ -186,4 +186,43 @@ setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT` hints to
|
|||||||
a non-default value will cause @ref glfwCreateWindow to fail and the
|
a non-default value will cause @ref glfwCreateWindow to fail and the
|
||||||
`GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored.
|
`GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored.
|
||||||
|
|
||||||
|
|
||||||
|
@section compat_vulkan Vulkan loader and API
|
||||||
|
|
||||||
|
GLFW uses the standard system-wside Vulkan loader to access the Vulkan API.
|
||||||
|
This should be installed by graphics drivers and Vulkan SDKs. If this is not
|
||||||
|
available, @ref glfwVulkanSupported will return `GLFW_FALSE` and all other
|
||||||
|
Vulkan-related functions will fail with an @ref GLFW_API_UNAVAILABLE error.
|
||||||
|
|
||||||
|
|
||||||
|
@section compat_wsi Vulkan WSI extensions
|
||||||
|
|
||||||
|
The Vulkan WSI extensions are used to create Vulkan surfaces for GLFW windows on
|
||||||
|
all supported platforms.
|
||||||
|
|
||||||
|
GLFW uses the `VK_KHR_surface` and `VK_KHR_win32_surface` extensions to create
|
||||||
|
surfaces on Microsoft Windows. If any of these extensions are not available,
|
||||||
|
@ref glfwGetRequiredInstanceExtensions will return an empty list and window
|
||||||
|
surface creation will fail.
|
||||||
|
|
||||||
|
GLFW uses the `VK_KHR_surface` and either the `VK_KHR_xlib_surface` or
|
||||||
|
`VK_KHR_xcb_surface` extensions to create surfaces on X11. If `VK_KHR_surface`
|
||||||
|
or both `VK_KHR_xlib_surface` and `VK_KHR_xcb_surface` are not available, @ref
|
||||||
|
glfwGetRequiredInstanceExtensions will return an empty list and window surface
|
||||||
|
creation will fail.
|
||||||
|
|
||||||
|
GLFW uses the `VK_KHR_surface` and `VK_KHR_wayland_surface` extensions to create
|
||||||
|
surfaces on Wayland. If any of these extensions are not available, @ref
|
||||||
|
glfwGetRequiredInstanceExtensions will return an empty list and window surface
|
||||||
|
creation will fail.
|
||||||
|
|
||||||
|
GLFW uses the `VK_KHR_surface` and `VK_KHR_mir_surface` extensions to create
|
||||||
|
surfaces on Mir. If any of these extensions are not available, @ref
|
||||||
|
glfwGetRequiredInstanceExtensions will return an empty list and window surface
|
||||||
|
creation will fail.
|
||||||
|
|
||||||
|
GLFW does not support any extensions for window surface creation on OS X,
|
||||||
|
meaning@ref glfwGetRequiredInstanceExtensions will return an empty list and
|
||||||
|
window surface creation will fail.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -26,6 +26,11 @@ as the context handle.
|
|||||||
To test the creation of various kinds of contexts and see their properties, run
|
To test the creation of various kinds of contexts and see their properties, run
|
||||||
the `glfwinfo` test program.
|
the `glfwinfo` test program.
|
||||||
|
|
||||||
|
@note Vulkan does not have a context and the Vulkan instance is created via the
|
||||||
|
Vulkan API itself. If you will be using Vulkan to render to a window, disable
|
||||||
|
context creation by setting the [GLFW_CLIENT_API](@ref window_hints_ctx) hint to
|
||||||
|
`GLFW_NO_API`. For more information, see the @ref vulkan.
|
||||||
|
|
||||||
|
|
||||||
@subsection context_hints Context creation hints
|
@subsection context_hints Context creation hints
|
||||||
|
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
@section main_intro Introduction
|
@section main_intro Introduction
|
||||||
|
|
||||||
__GLFW__ is a free, Open Source, multi-platform library for creating windows
|
GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and
|
||||||
with OpenGL or OpenGL ES contexts and receiving many kinds of input. It is easy
|
Vulkan application development. It provides a simple, platform-independent API
|
||||||
to integrate into existing applications and does not lay claim to the main loop.
|
for creating windows, contexts and surfaces, reading input, handling events, etc.
|
||||||
|
|
||||||
See @ref news_32 for release highlights or the
|
See @ref news_32 for release highlights or the
|
||||||
[version history](http://www.glfw.org/changelog.html) for details.
|
[version history](http://www.glfw.org/changelog.html) for details.
|
||||||
@ -32,6 +32,8 @@ about specific functions.
|
|||||||
There is a section on @ref guarantees_limitations for pointer lifetimes,
|
There is a section on @ref guarantees_limitations for pointer lifetimes,
|
||||||
reentrancy, thread safety, event order and backward and forward compatibility.
|
reentrancy, thread safety, event order and backward and forward compatibility.
|
||||||
|
|
||||||
|
The @ref vulkan guide fills in the gaps for how to use Vulkan with GLFW.
|
||||||
|
|
||||||
The @ref rift fills in the gaps for how to use LibOVR with GLFW.
|
The @ref rift fills in the gaps for how to use LibOVR with GLFW.
|
||||||
|
|
||||||
The [FAQ](http://www.glfw.org/faq.html) answers many common questions about the
|
The [FAQ](http://www.glfw.org/faq.html) answers many common questions about the
|
||||||
|
@ -17,6 +17,15 @@ GLFW now supports querying the localized name of printable keys with @ref
|
|||||||
glfwGetKeyName, either by key token or by scancode.
|
glfwGetKeyName, either by key token or by scancode.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection news_32_vulkan Support for Vulkan
|
||||||
|
|
||||||
|
GLFW now supports basic integration with Vulkan with @ref glfwVulkanSupported,
|
||||||
|
@ref glfwGetRequiredInstanceExtensions, @ref glfwGetInstanceProcAddress, @ref
|
||||||
|
glfwGetPhysicalDevicePresentationSupport and @ref glfwCreateWindowSurface.
|
||||||
|
Vulkan header inclusion can be selected with
|
||||||
|
[GLFW_INCLUDE_VULKAN](@ref build_macros).
|
||||||
|
|
||||||
|
|
||||||
@section news_31 New features in 3.1
|
@section news_31 New features in 3.1
|
||||||
|
|
||||||
These are the release highlights. For a full list of changes see the
|
These are the release highlights. For a full list of changes see the
|
||||||
|
185
docs/vulkan.dox
Normal file
185
docs/vulkan.dox
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
/*!
|
||||||
|
|
||||||
|
@page vulkan Vulkan guide
|
||||||
|
|
||||||
|
@tableofcontents
|
||||||
|
|
||||||
|
This guide is intended to fill the gaps between the Vulkan documentation and the
|
||||||
|
rest of the GLFW documentation and is not a replacement for either.
|
||||||
|
|
||||||
|
To develop for Vulkan you should install an SDK for your platform, for example
|
||||||
|
the [LunarG Vulkan SDK](http://lunarg.com/vulkan-sdk/). Apart from the headers
|
||||||
|
and libraries, it also provides the validation layers necessary for development.
|
||||||
|
|
||||||
|
GLFW itself does not need a Vulkan SDK to enable support for Vulkan. However,
|
||||||
|
any Vulkan-specific test and example programs are built only if the CMake files
|
||||||
|
find the LunarG SDK.
|
||||||
|
|
||||||
|
|
||||||
|
@section vulkan_include Including the Vulkan and GLFW header files
|
||||||
|
|
||||||
|
To include the Vulkan header, define `GLFW_INCLUDE_VULKAN` before including the
|
||||||
|
GLFW header.
|
||||||
|
|
||||||
|
@code
|
||||||
|
#define GLFW_INCLUDE_VULKAN
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
If you want to include the Vulkan header from a custom location or use your own
|
||||||
|
custom Vulkan header then you need to include them before the GLFW header.
|
||||||
|
|
||||||
|
@code
|
||||||
|
#include <custom/path/vulkan.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Unless a Vulkan header is included, either by the GLFW header or above it, any
|
||||||
|
GLFW functions that use Vulkan types will not be declared.
|
||||||
|
|
||||||
|
The `VK_USE_PLATFORM_*_KHR` macros do not need to be defined for the Vulkan part
|
||||||
|
of GLFW to work.
|
||||||
|
|
||||||
|
|
||||||
|
@section vulkan_support Querying for Vulkan support
|
||||||
|
|
||||||
|
If you are loading the Vulkan loader dynamically instead of linking directly
|
||||||
|
against it, you can check for the availability of a loader with @ref
|
||||||
|
glfwVulkanSupported.
|
||||||
|
|
||||||
|
@code
|
||||||
|
if (glfwVulkanSupported())
|
||||||
|
{
|
||||||
|
// Vulkan is available, at least for compute
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
This function returns `GLFW_TRUE` if the Vulkan loader was found. This check is
|
||||||
|
performed by @ref glfwInit.
|
||||||
|
|
||||||
|
If no loader was found, calling any other Vulkan related GLFW function will
|
||||||
|
generate a @ref GLFW_API_UNAVAILABLE error.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection vulkan_proc Querying Vulkan function pointers
|
||||||
|
|
||||||
|
To load any Vulkan core or extension function from the found loader, call @ref
|
||||||
|
glfwGetInstanceProcAddress.
|
||||||
|
|
||||||
|
@code
|
||||||
|
PFN_vkCreateDevice pfnCreateDevice = (PFN_vkCreateDevice)
|
||||||
|
glfwGetInstanceProcAddress(instance, "vkCreateDevice");
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
This is equivalent to calling `vkGetInstanceProcAddr`. If that fails, the
|
||||||
|
function falls back to a platform-specific query of the Vulkan loader (i.e.
|
||||||
|
`dlsym` or `GetProcAddress`). If that also fails, the function returns `NULL`.
|
||||||
|
For more information about `vkGetInstanceProcAddr`, see the Vulkan
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
Vulkan also provides `vkGetDeviceProcAddr` for loading device-specific versions
|
||||||
|
of Vulkan function. This function can be retrieved from an instance with @ref
|
||||||
|
glfwGetInstanceProcAddress.
|
||||||
|
|
||||||
|
@code
|
||||||
|
PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)
|
||||||
|
glfwGetInstanceProcAddress(instance, "vkGetDeviceProcAddr");
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Device-specific functions may execute a little bit faster, due to not having to
|
||||||
|
dispatch internally based on the device passed to them. For more information
|
||||||
|
about `vkGetDeviceProcAddr`, see the Vulkan documentation.
|
||||||
|
|
||||||
|
|
||||||
|
@section vulkan_ext Querying required Vulkan extensions
|
||||||
|
|
||||||
|
To do anything useful with Vulkan you need to create an instance. If you want
|
||||||
|
to use Vulkan to render to a window, you must enable the instance extensions
|
||||||
|
GLFW requires to create Vulkan surfaces.
|
||||||
|
|
||||||
|
To query the instance extensions required, call @ref
|
||||||
|
glfwGetRequiredInstanceExtensions.
|
||||||
|
|
||||||
|
@code
|
||||||
|
int count;
|
||||||
|
const char** extensions = glfwGetRequiredInstanceExtensions(&count);
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
These extensions must all be enabled when creating instances that are going to
|
||||||
|
be passed to @ref glfwGetPhysicalDevicePresentationSupport and @ref
|
||||||
|
glfwCreateWindowSurface. The set of extensions will vary depending on platform
|
||||||
|
and may also vary depending on graphics drivers and other factors.
|
||||||
|
|
||||||
|
If it fails it will return `NULL` and Vulkan window surface creation will not be
|
||||||
|
possible. You may still use Vulkan for off-screen rendering and compute work.
|
||||||
|
|
||||||
|
The returned array will always contain `VK_KHR_surface`, so if you don't
|
||||||
|
require any additional extensions you can pass this list directly to the
|
||||||
|
`VkInstanceCreateInfo` struct.
|
||||||
|
|
||||||
|
@code
|
||||||
|
VkInstanceCreateInfo ici;
|
||||||
|
|
||||||
|
memset(&ici, 0, sizeof(ici));
|
||||||
|
ici.enabledExtensionCount = count;
|
||||||
|
ici.ppEnabledExtensionNames = extensions;
|
||||||
|
...
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Additional extensions may be required by future versions of GLFW. You should
|
||||||
|
check whether any extensions you wish to enable are already in the returned
|
||||||
|
array, as it is an error to specify an extension more than once in the
|
||||||
|
`VkInstanceCreateInfo` struct.
|
||||||
|
|
||||||
|
|
||||||
|
@section vulkan_present Querying for Vulkan presentation support
|
||||||
|
|
||||||
|
Not every Vulkan queue family of every device can present images to surfaces.
|
||||||
|
To check whether a specific queue family of a physical device supports image
|
||||||
|
presentation without first having to create a window and surface, call @ref
|
||||||
|
glfwGetPhysicalDevicePresentationSupport.
|
||||||
|
|
||||||
|
@code
|
||||||
|
if (glfwGetPhysicalDevicePresentationSupport(instance, physical_device, queue_family_index))
|
||||||
|
{
|
||||||
|
// Queue family supports image presentation
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
The `VK_KHR_surface` extension also provides the
|
||||||
|
`vkGetPhysicalDeviceSurfaceSupportKHR` function, which performs the same test on
|
||||||
|
an existing Vulkan surface.
|
||||||
|
|
||||||
|
|
||||||
|
@section vulkan_window Creating the window
|
||||||
|
|
||||||
|
Unless you will be using OpenGL or OpenGL ES in addition to Vulkan, there is no
|
||||||
|
need to create a context for that window. You can disable context creation by
|
||||||
|
setting the [GLFW_CLIENT_API](@ref window_hints_ctx) hint to `GLFW_NO_API`.
|
||||||
|
|
||||||
|
@code
|
||||||
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||||
|
GLFWwindow* window = glfwCreateWindow(640, 480, "Window Title", NULL, NULL);
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
See @ref context_less for more information.
|
||||||
|
|
||||||
|
|
||||||
|
@section vulkan_surface Creating a Vulkan window surface
|
||||||
|
|
||||||
|
You can create a Vulkan surface (as defined by the `VK_KHR_surface` extension)
|
||||||
|
for a GLFW window with @ref glfwCreateWindowSurface.
|
||||||
|
|
||||||
|
@code
|
||||||
|
VkSurfaceKHR surface;
|
||||||
|
VkResult err = glfwCreateWindowSurface(instance, window, NULL, &surface);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
// Window surface creation failed
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
It is your responsibility to destroy the surface. GLFW does not destroy it for
|
||||||
|
you. Call `vkDestroySurfaceKHR` function from the same extension to destroy it.
|
||||||
|
|
||||||
|
*/
|
@ -1,6 +1,8 @@
|
|||||||
|
|
||||||
link_libraries(glfw)
|
link_libraries(glfw)
|
||||||
|
|
||||||
|
include_directories(${glfw_INCLUDE_DIRS})
|
||||||
|
|
||||||
if (BUILD_SHARED_LIBS)
|
if (BUILD_SHARED_LIBS)
|
||||||
link_libraries("${MATH_LIBRARY}")
|
link_libraries("${MATH_LIBRARY}")
|
||||||
endif()
|
endif()
|
||||||
|
@ -51,6 +51,11 @@ extern "C" {
|
|||||||
* This is the reference documentation for context related functions. For more
|
* This is the reference documentation for context related functions. For more
|
||||||
* information, see the @ref context.
|
* information, see the @ref context.
|
||||||
*/
|
*/
|
||||||
|
/*! @defgroup vulkan Vulkan support
|
||||||
|
*
|
||||||
|
* This is the reference documentation for Vulkan related functions. For more
|
||||||
|
* information, see the @ref vulkan.
|
||||||
|
*/
|
||||||
/*! @defgroup init Initialization, version and errors
|
/*! @defgroup init Initialization, version and errors
|
||||||
*
|
*
|
||||||
* This is the reference documentation for initialization and termination of
|
* This is the reference documentation for initialization and termination of
|
||||||
@ -157,6 +162,8 @@ extern "C" {
|
|||||||
#if defined(GLFW_INCLUDE_GLEXT)
|
#if defined(GLFW_INCLUDE_GLEXT)
|
||||||
#include <GLES2/gl2ext.h>
|
#include <GLES2/gl2ext.h>
|
||||||
#endif
|
#endif
|
||||||
|
#elif defined(GLFW_INCLUDE_VULKAN)
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
#elif !defined(GLFW_INCLUDE_NONE)
|
#elif !defined(GLFW_INCLUDE_NONE)
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#if defined(GLFW_INCLUDE_GLEXT)
|
#if defined(GLFW_INCLUDE_GLEXT)
|
||||||
@ -539,15 +546,12 @@ extern "C" {
|
|||||||
* to our [issue tracker](https://github.com/glfw/glfw/issues).
|
* to our [issue tracker](https://github.com/glfw/glfw/issues).
|
||||||
*/
|
*/
|
||||||
#define GLFW_OUT_OF_MEMORY 0x00010005
|
#define GLFW_OUT_OF_MEMORY 0x00010005
|
||||||
/*! @brief GLFW could not find support for the requested client API on the
|
/*! @brief GLFW could not find support for the requested API on the system.
|
||||||
* system.
|
|
||||||
*
|
*
|
||||||
* GLFW could not find support for the requested client API on the system. If
|
* GLFW could not find support for the requested API on the system.
|
||||||
* emitted by functions other than @ref glfwCreateWindow, no supported client
|
|
||||||
* API was found.
|
|
||||||
*
|
*
|
||||||
* @analysis The installed graphics driver does not support the requested
|
* @analysis The installed graphics driver does not support the requested
|
||||||
* client API, or does not support it via the chosen context creation backend.
|
* API, or does not support it via the chosen context creation backend.
|
||||||
* Below are a few examples.
|
* Below are a few examples.
|
||||||
*
|
*
|
||||||
* @par
|
* @par
|
||||||
@ -555,7 +559,7 @@ extern "C" {
|
|||||||
* supports OpenGL ES via EGL, while Nvidia and Intel only support it via
|
* supports OpenGL ES via EGL, while Nvidia and Intel only support it via
|
||||||
* a WGL or GLX extension. OS X does not provide OpenGL ES at all. The Mesa
|
* a WGL or GLX extension. OS X does not provide OpenGL ES at all. The Mesa
|
||||||
* EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary
|
* EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary
|
||||||
* driver.
|
* driver. Older graphics drivers do not support Vulkan.
|
||||||
*/
|
*/
|
||||||
#define GLFW_API_UNAVAILABLE 0x00010006
|
#define GLFW_API_UNAVAILABLE 0x00010006
|
||||||
/*! @brief The requested OpenGL or OpenGL ES version is not available.
|
/*! @brief The requested OpenGL or OpenGL ES version is not available.
|
||||||
@ -738,6 +742,20 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
typedef void (*GLFWglproc)(void);
|
typedef void (*GLFWglproc)(void);
|
||||||
|
|
||||||
|
/*! @brief Vulkan API function pointer type.
|
||||||
|
*
|
||||||
|
* Generic function pointer used for returning Vulkan API function pointers
|
||||||
|
* without forcing a cast from a regular pointer.
|
||||||
|
*
|
||||||
|
* @sa @ref vulkan_proc
|
||||||
|
* @sa glfwGetInstanceProcAddress
|
||||||
|
*
|
||||||
|
* @since Added in version 3.2.
|
||||||
|
*
|
||||||
|
* @ingroup vulkan
|
||||||
|
*/
|
||||||
|
typedef void (*GLFWvkproc)(void);
|
||||||
|
|
||||||
/*! @brief Opaque monitor object.
|
/*! @brief Opaque monitor object.
|
||||||
*
|
*
|
||||||
* Opaque monitor object.
|
* Opaque monitor object.
|
||||||
@ -3656,6 +3674,204 @@ GLFWAPI int glfwExtensionSupported(const char* extension);
|
|||||||
*/
|
*/
|
||||||
GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);
|
GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);
|
||||||
|
|
||||||
|
/*! @brief Returns whether the Vulkan loader has been found.
|
||||||
|
*
|
||||||
|
* This function returns whether the Vulkan loader has been found. This check
|
||||||
|
* is performed by @ref glfwInit.
|
||||||
|
*
|
||||||
|
* The availability of a Vulkan loader does not by itself guarantee that window
|
||||||
|
* surface creation or even device creation is possible. Call @ref
|
||||||
|
* glfwGetRequiredInstanceExtensions to check whether the extensions necessary
|
||||||
|
* for Vulkan surface creation are available and @ref
|
||||||
|
* glfwGetPhysicalDevicePresentationSupport to check whether a queue family of
|
||||||
|
* a physical device supports image presentation.
|
||||||
|
*
|
||||||
|
* @return `GLFW_TRUE` if Vulkan is available, or `GLFW_FALSE` otherwise.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread.
|
||||||
|
*
|
||||||
|
* @sa @ref vulkan_support
|
||||||
|
*
|
||||||
|
* @since Added in version 3.2.
|
||||||
|
*
|
||||||
|
* @ingroup vulkan
|
||||||
|
*/
|
||||||
|
GLFWAPI int glfwVulkanSupported(void);
|
||||||
|
|
||||||
|
/*! @brief Returns the Vulkan instance extensions required by GLFW.
|
||||||
|
*
|
||||||
|
* This function returns an array of names of Vulkan instance extensions required
|
||||||
|
* by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the
|
||||||
|
* list will always contains `VK_KHR_surface`, so if you don't require any
|
||||||
|
* additional extensions you can pass this list directly to the
|
||||||
|
* `VkInstanceCreateInfo` struct.
|
||||||
|
*
|
||||||
|
* If Vulkan is not available on the machine, this function returns `NULL` and
|
||||||
|
* generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
|
||||||
|
* to check whether Vulkan is available.
|
||||||
|
*
|
||||||
|
* If Vulkan is available but no set of extensions allowing window surface
|
||||||
|
* creation was found, this function returns `NULL`. You may still use Vulkan
|
||||||
|
* for off-screen rendering and compute work.
|
||||||
|
*
|
||||||
|
* @param[out] count Where to store the number of extensions in the returned
|
||||||
|
* array. This is set to zero if an error occurred.
|
||||||
|
* @return An array of ASCII encoded extension names, or `NULL` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||||
|
* GLFW_API_UNAVAILABLE.
|
||||||
|
*
|
||||||
|
* @remarks Additional extensions may be required by future versions of GLFW.
|
||||||
|
* You should check if any extensions you wish to enable are already in the
|
||||||
|
* returned array, as it is an error to specify an extension more than once in
|
||||||
|
* the `VkInstanceCreateInfo` struct.
|
||||||
|
*
|
||||||
|
* @pointer_lifetime The returned array is allocated and freed by GLFW. You
|
||||||
|
* should not free it yourself. It is guaranteed to be valid only until the
|
||||||
|
* library is terminated.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread.
|
||||||
|
*
|
||||||
|
* @sa @ref vulkan_ext
|
||||||
|
* @sa glfwCreateWindowSurface
|
||||||
|
*
|
||||||
|
* @since Added in version 3.2.
|
||||||
|
*
|
||||||
|
* @ingroup vulkan
|
||||||
|
*/
|
||||||
|
GLFWAPI const char** glfwGetRequiredInstanceExtensions(int* count);
|
||||||
|
|
||||||
|
#if defined(VK_VERSION_1_0)
|
||||||
|
|
||||||
|
/*! @brief Returns the address of the specified Vulkan instance function.
|
||||||
|
*
|
||||||
|
* This function returns the address of the specified Vulkan core or extension
|
||||||
|
* function for the specified instance. If instance is set to `NULL` it can
|
||||||
|
* return any function exported from the Vulkan loader, including at least the
|
||||||
|
* following functions:
|
||||||
|
*
|
||||||
|
* - `vkEnumerateInstanceExtensionProperties`
|
||||||
|
* - `vkEnumerateInstanceLayerProperties`
|
||||||
|
* - `vkCreateInstance`
|
||||||
|
* - `vkGetInstanceProcAddr`
|
||||||
|
*
|
||||||
|
* If Vulkan is not available on the machine, this function returns `NULL` and
|
||||||
|
* generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
|
||||||
|
* to check whether Vulkan is available.
|
||||||
|
*
|
||||||
|
* This function is equivalent to calling `vkGetInstanceProcAddr` with
|
||||||
|
* a platform-specific query of the Vulkan loader as a fallback.
|
||||||
|
*
|
||||||
|
* @param[in] instance The Vulkan instance to query, or `NULL` to retrieve
|
||||||
|
* functions related to instance creation.
|
||||||
|
* @param[in] procname The ASCII encoded name of the function.
|
||||||
|
* @return The address of the function, or `NULL` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||||
|
* GLFW_API_UNAVAILABLE.
|
||||||
|
*
|
||||||
|
* @pointer_lifetime The returned function pointer is valid until the library
|
||||||
|
* is terminated.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread.
|
||||||
|
*
|
||||||
|
* @sa @ref vulkan_proc
|
||||||
|
*
|
||||||
|
* @since Added in version 3.2.
|
||||||
|
*
|
||||||
|
* @ingroup vulkan
|
||||||
|
*/
|
||||||
|
GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname);
|
||||||
|
|
||||||
|
/*! @brief Returns whether the specified queue family can present images.
|
||||||
|
*
|
||||||
|
* This function returns whether the specified queue family of the specified
|
||||||
|
* physical device supports presentation to the platform GLFW was built for.
|
||||||
|
*
|
||||||
|
* If Vulkan or the required window surface creation instance extensions are
|
||||||
|
* not available on the machine, or if the specified instance was not created
|
||||||
|
* with the required extensions, this function returns `GLFW_FALSE` and
|
||||||
|
* generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
|
||||||
|
* to check whether Vulkan is available and @ref
|
||||||
|
* glfwGetRequiredInstanceExtensions to check what instance extensions are
|
||||||
|
* required.
|
||||||
|
*
|
||||||
|
* @param[in] instance The instance that the physical device belongs to.
|
||||||
|
* @param[in] device The physical device that the queue family belongs to.
|
||||||
|
* @param[in] queuefamily The index of the queue family to query.
|
||||||
|
* @return `GLFW_TRUE` if the queue family supports presentation, or
|
||||||
|
* `GLFW_FALSE` otherwise.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||||
|
* GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. For
|
||||||
|
* synchronization details of Vulkan objects, see the Vulkan specification.
|
||||||
|
*
|
||||||
|
* @sa @ref vulkan_present
|
||||||
|
*
|
||||||
|
* @since Added in version 3.2.
|
||||||
|
*
|
||||||
|
* @ingroup vulkan
|
||||||
|
*/
|
||||||
|
GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
|
||||||
|
|
||||||
|
/*! @brief Creates a Vulkan surface for the specified window.
|
||||||
|
*
|
||||||
|
* This function creates a Vulkan surface for the specified window.
|
||||||
|
*
|
||||||
|
* If the Vulkan loader was not found at initialization, this function returns
|
||||||
|
* `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref GLFW_API_UNAVAILABLE
|
||||||
|
* error. Call @ref glfwVulkanSupported to check whether the Vulkan loader was
|
||||||
|
* found.
|
||||||
|
*
|
||||||
|
* If the required window surface creation instance extensions are not
|
||||||
|
* available or if the specified instance was not created with these extensions
|
||||||
|
* enabled, this function returns `VK_ERROR_EXTENSION_NOT_PRESENT` and
|
||||||
|
* generates a @ref GLFW_API_UNAVAILABLE error. Call @ref
|
||||||
|
* glfwGetRequiredInstanceExtensions to check what instance extensions are
|
||||||
|
* required.
|
||||||
|
*
|
||||||
|
* The window surface must be destroyed before the specified Vulkan instance.
|
||||||
|
* It is the responsibility of the caller to destroy the window surface. GLFW
|
||||||
|
* does not destroy it for you. Call `vkDestroySurfaceKHR` to destroy the
|
||||||
|
* surface.
|
||||||
|
*
|
||||||
|
* @param[in] instance The Vulkan instance to create the surface in.
|
||||||
|
* @param[in] window The window to create the surface for.
|
||||||
|
* @param[in] allocator The allocator to use, or `NULL` to use the default
|
||||||
|
* allocator.
|
||||||
|
* @param[out] surface Where to store the handle of the surface. This is set
|
||||||
|
* to `VK_NULL_HANDLE` if an error occurred.
|
||||||
|
* @return `VK_SUCCESS` if successful, or a Vulkan error code if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||||
|
* GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
|
||||||
|
*
|
||||||
|
* @remarks If an error occurs before the creation call is made, GLFW returns
|
||||||
|
* the Vulkan error code most appropriate for the error. Appropriate use of
|
||||||
|
* @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should
|
||||||
|
* elminiate almost all occurences of these errors.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. For
|
||||||
|
* synchronization details of Vulkan objects, see the Vulkan specification.
|
||||||
|
*
|
||||||
|
* @sa @ref vulkan_surface
|
||||||
|
* @sa glfwGetRequiredInstanceExtensions
|
||||||
|
*
|
||||||
|
* @since Added in version 3.2.
|
||||||
|
*
|
||||||
|
* @ingroup vulkan
|
||||||
|
*/
|
||||||
|
GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
|
||||||
|
|
||||||
|
#endif /*VK_VERSION_1_0*/
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Global definition cleanup
|
* Global definition cleanup
|
||||||
|
@ -3,7 +3,7 @@ set(common_HEADERS internal.h
|
|||||||
"${GLFW_BINARY_DIR}/src/glfw_config.h"
|
"${GLFW_BINARY_DIR}/src/glfw_config.h"
|
||||||
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
|
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
|
||||||
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h")
|
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h")
|
||||||
set(common_SOURCES context.c init.c input.c monitor.c window.c)
|
set(common_SOURCES context.c init.c input.c monitor.c vulkan.c window.c)
|
||||||
|
|
||||||
if (_GLFW_COCOA)
|
if (_GLFW_COCOA)
|
||||||
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h cocoa_joystick.h
|
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h cocoa_joystick.h
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#define _glfw3_cocoa_platform_h_
|
#define _glfw3_cocoa_platform_h_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#if defined(__OBJC__)
|
#if defined(__OBJC__)
|
||||||
#import <Carbon/Carbon.h>
|
#import <Carbon/Carbon.h>
|
||||||
@ -47,6 +48,10 @@ typedef void* id;
|
|||||||
#error "The Cocoa backend depends on NSGL platform support"
|
#error "The Cocoa backend depends on NSGL platform support"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||||
|
#define _glfw_dlclose(handle) dlclose(handle)
|
||||||
|
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS ns
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS ns
|
||||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns
|
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns
|
||||||
#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeNS ns_time
|
#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeNS ns_time
|
||||||
|
@ -1322,6 +1322,27 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
|||||||
return _glfw.ns.clipboardString;
|
return _glfw.ns.clipboardString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char** _glfwPlatformGetRequiredInstanceExtensions(int* count)
|
||||||
|
{
|
||||||
|
*count = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||||
|
VkPhysicalDevice device,
|
||||||
|
unsigned int queuefamily)
|
||||||
|
{
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
||||||
|
_GLFWwindow* window,
|
||||||
|
const VkAllocationCallbacks* allocator,
|
||||||
|
VkSurfaceKHR* surface)
|
||||||
|
{
|
||||||
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW native API //////
|
////// GLFW native API //////
|
||||||
|
@ -28,17 +28,6 @@
|
|||||||
#ifndef _glfw3_egl_context_h_
|
#ifndef _glfw3_egl_context_h_
|
||||||
#define _glfw3_egl_context_h_
|
#define _glfw3_egl_context_h_
|
||||||
|
|
||||||
#if defined(_GLFW_WIN32)
|
|
||||||
#define _glfw_dlopen(name) LoadLibraryA(name)
|
|
||||||
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
|
|
||||||
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
|
|
||||||
#else
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
|
||||||
#define _glfw_dlclose(handle) dlclose(handle)
|
|
||||||
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_GLFW_USE_EGLPLATFORM_H)
|
#if defined(_GLFW_USE_EGLPLATFORM_H)
|
||||||
#include <EGL/eglplatform.h>
|
#include <EGL/eglplatform.h>
|
||||||
#elif defined(_GLFW_WIN32)
|
#elif defined(_GLFW_WIN32)
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <dlfcn.h>
|
|
||||||
|
|
||||||
#ifndef GLXBadProfileARB
|
#ifndef GLXBadProfileARB
|
||||||
#define GLXBadProfileARB 13
|
#define GLXBadProfileARB 13
|
||||||
|
@ -130,6 +130,8 @@ GLFWAPI int glfwInit(void)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glfwInitVulkan();
|
||||||
|
|
||||||
_glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount);
|
_glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount);
|
||||||
_glfwInitialized = GLFW_TRUE;
|
_glfwInitialized = GLFW_TRUE;
|
||||||
|
|
||||||
@ -161,6 +163,8 @@ GLFWAPI void glfwTerminate(void)
|
|||||||
_glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp);
|
_glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glfwTerminateVulkan();
|
||||||
|
|
||||||
_glfwFreeMonitors(_glfw.monitors, _glfw.monitorCount);
|
_glfwFreeMonitors(_glfw.monitors, _glfw.monitorCount);
|
||||||
_glfw.monitors = NULL;
|
_glfw.monitors = NULL;
|
||||||
_glfw.monitorCount = 0;
|
_glfw.monitorCount = 0;
|
||||||
|
127
src/internal.h
127
src/internal.h
@ -47,6 +47,26 @@
|
|||||||
#define GLFW_INCLUDE_NONE
|
#define GLFW_INCLUDE_NONE
|
||||||
#include "../include/GLFW/glfw3.h"
|
#include "../include/GLFW/glfw3.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER < 1600)
|
||||||
|
typedef unsigned __int64 GLFWuint64;
|
||||||
|
#else
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef uint64_t GLFWuint64;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef int GLFWbool;
|
||||||
|
|
||||||
|
typedef struct _GLFWwndconfig _GLFWwndconfig;
|
||||||
|
typedef struct _GLFWctxconfig _GLFWctxconfig;
|
||||||
|
typedef struct _GLFWfbconfig _GLFWfbconfig;
|
||||||
|
typedef struct _GLFWcontext _GLFWcontext;
|
||||||
|
typedef struct _GLFWwindow _GLFWwindow;
|
||||||
|
typedef struct _GLFWlibrary _GLFWlibrary;
|
||||||
|
typedef struct _GLFWmonitor _GLFWmonitor;
|
||||||
|
typedef struct _GLFWcursor _GLFWcursor;
|
||||||
|
|
||||||
#define GL_VERSION 0x1f02
|
#define GL_VERSION 0x1f02
|
||||||
#define GL_NONE 0
|
#define GL_NONE 0
|
||||||
#define GL_COLOR_BUFFER_BIT 0x00004000
|
#define GL_COLOR_BUFFER_BIT 0x00004000
|
||||||
@ -76,16 +96,66 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGPROC)(GLenum);
|
|||||||
typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*);
|
typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*);
|
||||||
typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
|
typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
|
||||||
|
|
||||||
typedef struct _GLFWwndconfig _GLFWwndconfig;
|
#define VK_NULL_HANDLE 0
|
||||||
typedef struct _GLFWctxconfig _GLFWctxconfig;
|
|
||||||
typedef struct _GLFWfbconfig _GLFWfbconfig;
|
|
||||||
typedef struct _GLFWcontext _GLFWcontext;
|
|
||||||
typedef struct _GLFWwindow _GLFWwindow;
|
|
||||||
typedef struct _GLFWlibrary _GLFWlibrary;
|
|
||||||
typedef struct _GLFWmonitor _GLFWmonitor;
|
|
||||||
typedef struct _GLFWcursor _GLFWcursor;
|
|
||||||
|
|
||||||
typedef int GLFWbool;
|
typedef GLFWuint64 VkInstance;
|
||||||
|
typedef GLFWuint64 VkPhysicalDevice;
|
||||||
|
typedef GLFWuint64 VkSurfaceKHR;
|
||||||
|
typedef unsigned int VkFlags;
|
||||||
|
typedef unsigned int VkBool32;
|
||||||
|
|
||||||
|
typedef enum VkStructureType
|
||||||
|
{
|
||||||
|
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000,
|
||||||
|
VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000,
|
||||||
|
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
|
||||||
|
VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR = 1000007000,
|
||||||
|
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
|
||||||
|
VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
|
||||||
|
} VkStructureType;
|
||||||
|
|
||||||
|
typedef enum VkResult
|
||||||
|
{
|
||||||
|
VK_SUCCESS = 0,
|
||||||
|
VK_NOT_READY = 1,
|
||||||
|
VK_TIMEOUT = 2,
|
||||||
|
VK_EVENT_SET = 3,
|
||||||
|
VK_EVENT_RESET = 4,
|
||||||
|
VK_INCOMPLETE = 5,
|
||||||
|
VK_ERROR_OUT_OF_HOST_MEMORY = -1,
|
||||||
|
VK_ERROR_OUT_OF_DEVICE_MEMORY = -2,
|
||||||
|
VK_ERROR_INITIALIZATION_FAILED = -3,
|
||||||
|
VK_ERROR_DEVICE_LOST = -4,
|
||||||
|
VK_ERROR_MEMORY_MAP_FAILED = -5,
|
||||||
|
VK_ERROR_LAYER_NOT_PRESENT = -6,
|
||||||
|
VK_ERROR_EXTENSION_NOT_PRESENT = -7,
|
||||||
|
VK_ERROR_FEATURE_NOT_PRESENT = -8,
|
||||||
|
VK_ERROR_INCOMPATIBLE_DRIVER = -9,
|
||||||
|
VK_ERROR_TOO_MANY_OBJECTS = -10,
|
||||||
|
VK_ERROR_FORMAT_NOT_SUPPORTED = -11,
|
||||||
|
VK_ERROR_SURFACE_LOST_KHR = -1000000000,
|
||||||
|
VK_SUBOPTIMAL_KHR = 1000001003,
|
||||||
|
VK_ERROR_OUT_OF_DATE_KHR = -1000001004,
|
||||||
|
VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
|
||||||
|
VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,
|
||||||
|
VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
|
||||||
|
VK_RESULT_MAX_ENUM = 0x7FFFFFFF
|
||||||
|
} VkResult;
|
||||||
|
|
||||||
|
typedef struct VkAllocationCallbacks VkAllocationCallbacks;
|
||||||
|
|
||||||
|
typedef struct VkExtensionProperties
|
||||||
|
{
|
||||||
|
char extensionName[256];
|
||||||
|
unsigned int specVersion;
|
||||||
|
} VkExtensionProperties;
|
||||||
|
|
||||||
|
typedef void (APIENTRY * PFN_vkVoidFunction)(void);
|
||||||
|
typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*);
|
||||||
|
typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,unsigned int*,VkExtensionProperties*);
|
||||||
|
|
||||||
|
#define vkEnumerateInstanceExtensionProperties _glfw.vk.EnumerateInstanceExtensionProperties
|
||||||
|
#define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr
|
||||||
|
|
||||||
#if defined(_GLFW_COCOA)
|
#if defined(_GLFW_COCOA)
|
||||||
#include "cocoa_platform.h"
|
#include "cocoa_platform.h"
|
||||||
@ -363,6 +433,21 @@ struct _GLFWlibrary
|
|||||||
_GLFWmonitor** monitors;
|
_GLFWmonitor** monitors;
|
||||||
int monitorCount;
|
int monitorCount;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
GLFWbool available;
|
||||||
|
void* handle;
|
||||||
|
char** extensions;
|
||||||
|
int extensionCount;
|
||||||
|
PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
|
||||||
|
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
|
||||||
|
GLFWbool KHR_surface;
|
||||||
|
GLFWbool KHR_win32_surface;
|
||||||
|
GLFWbool KHR_xlib_surface;
|
||||||
|
GLFWbool KHR_xcb_surface;
|
||||||
|
GLFWbool KHR_wayland_surface;
|
||||||
|
GLFWbool KHR_mir_surface;
|
||||||
|
} vk;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
GLFWmonitorfun monitor;
|
GLFWmonitorfun monitor;
|
||||||
} callbacks;
|
} callbacks;
|
||||||
@ -686,6 +771,18 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor);
|
|||||||
*/
|
*/
|
||||||
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor);
|
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor);
|
||||||
|
|
||||||
|
/*! @ingroup platform
|
||||||
|
*/
|
||||||
|
char** _glfwPlatformGetRequiredInstanceExtensions(int* count);
|
||||||
|
|
||||||
|
/*! @ingroup platform
|
||||||
|
*/
|
||||||
|
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, unsigned int queuefamily);
|
||||||
|
|
||||||
|
/*! @ingroup platform
|
||||||
|
*/
|
||||||
|
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
// Event API functions
|
// Event API functions
|
||||||
@ -920,4 +1017,16 @@ void _glfwFreeMonitors(_GLFWmonitor** monitors, int count);
|
|||||||
*/
|
*/
|
||||||
GLFWbool _glfwIsPrintable(int key);
|
GLFWbool _glfwIsPrintable(int key);
|
||||||
|
|
||||||
|
/*! @ingroup utility
|
||||||
|
*/
|
||||||
|
void _glfwInitVulkan(void);
|
||||||
|
|
||||||
|
/*! @ingroup utility
|
||||||
|
*/
|
||||||
|
void _glfwTerminateVulkan(void);
|
||||||
|
|
||||||
|
/*! @ingroup utility
|
||||||
|
*/
|
||||||
|
const char* _glfwGetVulkanResultString(VkResult result);
|
||||||
|
|
||||||
#endif // _glfw3_internal_h_
|
#endif // _glfw3_internal_h_
|
||||||
|
@ -29,9 +29,24 @@
|
|||||||
|
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#include <mir_toolkit/mir_client_library.h>
|
#include <mir_toolkit/mir_client_library.h>
|
||||||
|
|
||||||
|
typedef VkFlags VkMirSurfaceCreateFlagsKHR;
|
||||||
|
|
||||||
|
typedef struct VkMirSurfaceCreateInfoKHR
|
||||||
|
{
|
||||||
|
VkStructureType sType;
|
||||||
|
const void* pNext;
|
||||||
|
VkMirSurfaceCreateFlagsKHR flags;
|
||||||
|
MirConnection* connection;
|
||||||
|
MirSurface* mirSurface;
|
||||||
|
} VkMirSurfaceCreateInfoKHR;
|
||||||
|
|
||||||
|
typedef VkResult (APIENTRY *PFN_vkCreateMirSurfaceKHR)(VkInstance,const VkMirSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
|
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice,uint32_t,MirConnection*);
|
||||||
|
|
||||||
#include "posix_tls.h"
|
#include "posix_tls.h"
|
||||||
#include "posix_time.h"
|
#include "posix_time.h"
|
||||||
#include "linux_joystick.h"
|
#include "linux_joystick.h"
|
||||||
@ -43,6 +58,10 @@
|
|||||||
#error "The Mir backend depends on EGL platform support"
|
#error "The Mir backend depends on EGL platform support"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||||
|
#define _glfw_dlclose(handle) dlclose(handle)
|
||||||
|
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
||||||
|
|
||||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->mir.window)
|
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->mir.window)
|
||||||
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.mir.display)
|
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.mir.display)
|
||||||
|
|
||||||
|
@ -706,6 +706,76 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char** _glfwPlatformGetRequiredInstanceExtensions(int* count)
|
||||||
|
{
|
||||||
|
char** extensions;
|
||||||
|
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
|
if (!_glfw.vk.KHR_mir_surface)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
extensions = calloc(2, sizeof(char*));
|
||||||
|
extensions[0] = strdup("VK_KHR_surface");
|
||||||
|
extensions[1] = strdup("VK_KHR_mir_surface");
|
||||||
|
|
||||||
|
*count = 2;
|
||||||
|
return extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||||
|
VkPhysicalDevice device,
|
||||||
|
unsigned int queuefamily)
|
||||||
|
{
|
||||||
|
PFN_vkGetPhysicalDeviceMirPresentationSupportKHR vkGetPhysicalDeviceMirPresentationSupportKHR =
|
||||||
|
(PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)
|
||||||
|
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
|
||||||
|
if (!vkGetPhysicalDeviceMirPresentationSupportKHR)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Mir: Vulkan instance missing VK_KHR_mir_surface extension");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vkGetPhysicalDeviceMirPresentationSupportKHR(device,
|
||||||
|
queuefamily,
|
||||||
|
_glfw.mir.connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
||||||
|
_GLFWwindow* window,
|
||||||
|
const VkAllocationCallbacks* allocator,
|
||||||
|
VkSurfaceKHR* surface)
|
||||||
|
{
|
||||||
|
VkResult err;
|
||||||
|
VkMirSurfaceCreateInfoKHR sci;
|
||||||
|
PFN_vkCreateMirSurfaceKHR vkCreateMirSurfaceKHR;
|
||||||
|
|
||||||
|
vkCreateMirSurfaceKHR = (PFN_vkCreateMirSurfaceKHR)
|
||||||
|
vkGetInstanceProcAddr(instance, "vkCreateMirSurfaceKHR");
|
||||||
|
if (!vkCreateMirSurfaceKHR)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Mir: Vulkan instance missing VK_KHR_mir_surface extension");
|
||||||
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&sci, 0, sizeof(sci));
|
||||||
|
sci.sType = VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR;
|
||||||
|
sci.display = _glfw.mir.connection;
|
||||||
|
sci.surface = window->mir.surface;
|
||||||
|
|
||||||
|
err = vkCreateMirSurfaceKHR(instance, &sci, allocator, surface);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Mir: Failed to create Vulkan surface: %s",
|
||||||
|
_glfwGetVulkanResultString(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW native API //////
|
////// GLFW native API //////
|
||||||
|
287
src/vulkan.c
Normal file
287
src/vulkan.c
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.2 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void _glfwInitVulkan(void)
|
||||||
|
{
|
||||||
|
VkResult err;
|
||||||
|
VkExtensionProperties* ep;
|
||||||
|
unsigned int i, count;
|
||||||
|
#if defined(_GLFW_WIN32)
|
||||||
|
const char* name = "vulkan-1.dll";
|
||||||
|
#else
|
||||||
|
const char* name = "libvulkan.so.1";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_glfw.vk.handle = _glfw_dlopen(name);
|
||||||
|
if (!_glfw.vk.handle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
|
||||||
|
_glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr");
|
||||||
|
if (!_glfw.vk.GetInstanceProcAddr)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Vulkan: Loader does not export vkGetInstanceProcAddr");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
|
||||||
|
vkGetInstanceProcAddr(0, "vkEnumerateInstanceExtensionProperties");
|
||||||
|
if (!_glfw.vk.EnumerateInstanceExtensionProperties)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Vulkan: Failed to query instance extension count: %s",
|
||||||
|
_glfwGetVulkanResultString(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ep = calloc(count, sizeof(VkExtensionProperties));
|
||||||
|
|
||||||
|
err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Vulkan: Failed to query instance extensions: %s",
|
||||||
|
_glfwGetVulkanResultString(err));
|
||||||
|
|
||||||
|
free(ep);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0)
|
||||||
|
_glfw.vk.KHR_surface = GLFW_TRUE;
|
||||||
|
if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)
|
||||||
|
_glfw.vk.KHR_win32_surface = GLFW_TRUE;
|
||||||
|
if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
|
||||||
|
_glfw.vk.KHR_xlib_surface = GLFW_TRUE;
|
||||||
|
if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0)
|
||||||
|
_glfw.vk.KHR_xcb_surface = GLFW_TRUE;
|
||||||
|
if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
|
||||||
|
_glfw.vk.KHR_wayland_surface = GLFW_TRUE;
|
||||||
|
if (strcmp(ep[i].extensionName, "VK_KHR_mir_surface") == 0)
|
||||||
|
_glfw.vk.KHR_mir_surface = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(ep);
|
||||||
|
|
||||||
|
_glfw.vk.available = GLFW_TRUE;
|
||||||
|
|
||||||
|
if (!_glfw.vk.KHR_surface)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_glfw.vk.extensions =
|
||||||
|
_glfwPlatformGetRequiredInstanceExtensions(&_glfw.vk.extensionCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwTerminateVulkan(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < _glfw.vk.extensionCount; i++)
|
||||||
|
free(_glfw.vk.extensions[i]);
|
||||||
|
free(_glfw.vk.extensions);
|
||||||
|
|
||||||
|
if (_glfw.vk.handle)
|
||||||
|
_glfw_dlclose(_glfw.vk.handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* _glfwGetVulkanResultString(VkResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case VK_SUCCESS:
|
||||||
|
return "Success";
|
||||||
|
case VK_NOT_READY:
|
||||||
|
return "A fence or query has not yet completed";
|
||||||
|
case VK_TIMEOUT:
|
||||||
|
return "A wait operation has not completed in the specified time";
|
||||||
|
case VK_EVENT_SET:
|
||||||
|
return "An event is signaled";
|
||||||
|
case VK_EVENT_RESET:
|
||||||
|
return "An event is unsignaled";
|
||||||
|
case VK_INCOMPLETE:
|
||||||
|
return "A return array was too small for the result";
|
||||||
|
case VK_ERROR_OUT_OF_HOST_MEMORY:
|
||||||
|
return "A host memory allocation has failed";
|
||||||
|
case VK_ERROR_OUT_OF_DEVICE_MEMORY:
|
||||||
|
return "A device memory allocation has failed";
|
||||||
|
case VK_ERROR_INITIALIZATION_FAILED:
|
||||||
|
return "Initialization of an object could not be completed for implementation-specific reasons";
|
||||||
|
case VK_ERROR_DEVICE_LOST:
|
||||||
|
return "The logical or physical device has been lost";
|
||||||
|
case VK_ERROR_MEMORY_MAP_FAILED:
|
||||||
|
return "Mapping of a memory object has failed";
|
||||||
|
case VK_ERROR_LAYER_NOT_PRESENT:
|
||||||
|
return "A requested layer is not present or could not be loaded";
|
||||||
|
case VK_ERROR_EXTENSION_NOT_PRESENT:
|
||||||
|
return "A requested extension is not supported";
|
||||||
|
case VK_ERROR_FEATURE_NOT_PRESENT:
|
||||||
|
return "A requested feature is not supported";
|
||||||
|
case VK_ERROR_INCOMPATIBLE_DRIVER:
|
||||||
|
return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible";
|
||||||
|
case VK_ERROR_TOO_MANY_OBJECTS:
|
||||||
|
return "Too many objects of the type have already been created";
|
||||||
|
case VK_ERROR_FORMAT_NOT_SUPPORTED:
|
||||||
|
return "A requested format is not supported on this device";
|
||||||
|
case VK_ERROR_SURFACE_LOST_KHR:
|
||||||
|
return "A surface is no longer available";
|
||||||
|
case VK_SUBOPTIMAL_KHR:
|
||||||
|
return "A swapchain no longer matches the surface properties exactly, but can still be used";
|
||||||
|
case VK_ERROR_OUT_OF_DATE_KHR:
|
||||||
|
return "A surface has changed in such a way that it is no longer compatible with the swapchain";
|
||||||
|
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
|
||||||
|
return "The display used by a swapchain does not use the same presentable image layout";
|
||||||
|
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
|
||||||
|
return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API";
|
||||||
|
case VK_ERROR_VALIDATION_FAILED_EXT:
|
||||||
|
return "A validation layer found an error";
|
||||||
|
default:
|
||||||
|
return "ERROR: UNKNOWN VULKAN ERROR TOKEN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW public API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWAPI int glfwVulkanSupported(void)
|
||||||
|
{
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||||
|
return _glfw.vk.available;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI const char** glfwGetRequiredInstanceExtensions(int* count)
|
||||||
|
{
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
|
if (!_glfw.vk.available)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*count = _glfw.vk.extensionCount;
|
||||||
|
return (const char**) _glfw.vk.extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
|
||||||
|
const char* procname)
|
||||||
|
{
|
||||||
|
GLFWvkproc proc;
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
|
if (!_glfw.vk.available)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname);
|
||||||
|
if (!proc)
|
||||||
|
proc = (GLFWvkproc) _glfw_dlsym(_glfw.vk.handle, procname);
|
||||||
|
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||||
|
VkPhysicalDevice device,
|
||||||
|
uint32_t queuefamily)
|
||||||
|
{
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||||
|
|
||||||
|
if (!_glfw.vk.available)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_glfw.vk.extensions)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Vulkan: Window surface creation extensions not found");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _glfwPlatformGetPhysicalDevicePresentationSupport(instance,
|
||||||
|
device,
|
||||||
|
queuefamily);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
|
||||||
|
GLFWwindow* handle,
|
||||||
|
const VkAllocationCallbacks* allocator,
|
||||||
|
VkSurfaceKHR* surface)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
assert(window);
|
||||||
|
|
||||||
|
assert(surface);
|
||||||
|
*surface = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED);
|
||||||
|
|
||||||
|
if (!_glfw.vk.available)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
|
||||||
|
return VK_ERROR_INITIALIZATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_glfw.vk.extensions)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Vulkan: Window surface creation extensions not found");
|
||||||
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _glfwPlatformCreateWindowSurface(instance, window, allocator, surface);
|
||||||
|
}
|
||||||
|
|
@ -140,6 +140,20 @@ typedef HRESULT (WINAPI * DWMFLUSH_T)(VOID);
|
|||||||
typedef HRESULT (WINAPI * SETPROCESSDPIAWARENESS_T)(PROCESS_DPI_AWARENESS);
|
typedef HRESULT (WINAPI * SETPROCESSDPIAWARENESS_T)(PROCESS_DPI_AWARENESS);
|
||||||
#define _glfw_SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness
|
#define _glfw_SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness
|
||||||
|
|
||||||
|
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
|
||||||
|
|
||||||
|
typedef struct VkWin32SurfaceCreateInfoKHR
|
||||||
|
{
|
||||||
|
VkStructureType sType;
|
||||||
|
const void* pNext;
|
||||||
|
VkWin32SurfaceCreateFlagsKHR flags;
|
||||||
|
HINSTANCE hinstance;
|
||||||
|
HWND hwnd;
|
||||||
|
} VkWin32SurfaceCreateInfoKHR;
|
||||||
|
|
||||||
|
typedef VkResult (APIENTRY *PFN_vkCreateWin32SurfaceKHR)(VkInstance,const VkWin32SurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
|
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice,uint32_t);
|
||||||
|
|
||||||
#include "win32_joystick.h"
|
#include "win32_joystick.h"
|
||||||
|
|
||||||
#if defined(_GLFW_WGL)
|
#if defined(_GLFW_WGL)
|
||||||
@ -154,6 +168,10 @@ typedef HRESULT (WINAPI * SETPROCESSDPIAWARENESS_T)(PROCESS_DPI_AWARENESS);
|
|||||||
|
|
||||||
#define _GLFW_WNDCLASSNAME L"GLFW30"
|
#define _GLFW_WNDCLASSNAME L"GLFW30"
|
||||||
|
|
||||||
|
#define _glfw_dlopen(name) LoadLibraryA(name)
|
||||||
|
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
|
||||||
|
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32
|
||||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32
|
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32
|
||||||
#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeWin32 win32_time
|
#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeWin32 win32_time
|
||||||
|
@ -1403,6 +1403,74 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
|||||||
return _glfw.win32.clipboardString;
|
return _glfw.win32.clipboardString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char** _glfwPlatformGetRequiredInstanceExtensions(int* count)
|
||||||
|
{
|
||||||
|
char** extensions;
|
||||||
|
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
|
if (!_glfw.vk.KHR_win32_surface)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
extensions = calloc(2, sizeof(char*));
|
||||||
|
extensions[0] = strdup("VK_KHR_surface");
|
||||||
|
extensions[1] = strdup("VK_KHR_win32_surface");
|
||||||
|
|
||||||
|
*count = 2;
|
||||||
|
return extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||||
|
VkPhysicalDevice device,
|
||||||
|
unsigned int queuefamily)
|
||||||
|
{
|
||||||
|
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR =
|
||||||
|
(PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)
|
||||||
|
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
|
||||||
|
if (!vkGetPhysicalDeviceWin32PresentationSupportKHR)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Win32: Vulkan instance missing VK_KHR_win32_surface extension");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vkGetPhysicalDeviceWin32PresentationSupportKHR(device, queuefamily);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
||||||
|
_GLFWwindow* window,
|
||||||
|
const VkAllocationCallbacks* allocator,
|
||||||
|
VkSurfaceKHR* surface)
|
||||||
|
{
|
||||||
|
VkResult err;
|
||||||
|
VkWin32SurfaceCreateInfoKHR sci;
|
||||||
|
PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
|
||||||
|
|
||||||
|
vkCreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)
|
||||||
|
vkGetInstanceProcAddr(instance, "vkCreateWin32SurfaceKHR");
|
||||||
|
if (!vkCreateWin32SurfaceKHR)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Win32: Vulkan instance missing VK_KHR_win32_surface extension");
|
||||||
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&sci, 0, sizeof(sci));
|
||||||
|
sci.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
|
||||||
|
sci.hinstance = GetModuleHandle(NULL);
|
||||||
|
sci.hwnd = window->win32.handle;
|
||||||
|
|
||||||
|
err = vkCreateWin32SurfaceKHR(instance, &sci, allocator, surface);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to create Vulkan surface: %s",
|
||||||
|
_glfwGetVulkanResultString(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW native API //////
|
////// GLFW native API //////
|
||||||
|
@ -29,6 +29,21 @@
|
|||||||
|
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
|
||||||
|
|
||||||
|
typedef struct VkWaylandSurfaceCreateInfoKHR
|
||||||
|
{
|
||||||
|
VkStructureType sType;
|
||||||
|
const void* pNext;
|
||||||
|
VkWaylandSurfaceCreateFlagsKHR flags;
|
||||||
|
struct wl_display* display;
|
||||||
|
struct wl_surface* surface;
|
||||||
|
} VkWaylandSurfaceCreateInfoKHR;
|
||||||
|
|
||||||
|
typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
|
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*);
|
||||||
|
|
||||||
#include "posix_tls.h"
|
#include "posix_tls.h"
|
||||||
#include "posix_time.h"
|
#include "posix_time.h"
|
||||||
@ -41,6 +56,10 @@
|
|||||||
#error "The Wayland backend depends on EGL platform support"
|
#error "The Wayland backend depends on EGL platform support"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||||
|
#define _glfw_dlclose(handle) dlclose(handle)
|
||||||
|
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
||||||
|
|
||||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->wl.native)
|
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->wl.native)
|
||||||
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.wl.display)
|
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.wl.display)
|
||||||
|
|
||||||
@ -75,6 +94,7 @@ typedef struct _GLFWwindowWayland
|
|||||||
_GLFWmonitor** monitors;
|
_GLFWmonitor** monitors;
|
||||||
int monitorsCount;
|
int monitorsCount;
|
||||||
int monitorsSize;
|
int monitorsSize;
|
||||||
|
|
||||||
} _GLFWwindowWayland;
|
} _GLFWwindowWayland;
|
||||||
|
|
||||||
|
|
||||||
|
@ -699,6 +699,76 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char** _glfwPlatformGetRequiredInstanceExtensions(int* count)
|
||||||
|
{
|
||||||
|
char** extensions;
|
||||||
|
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
|
if (!_glfw.vk.KHR_wayland_surface)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
extensions = calloc(2, sizeof(char*));
|
||||||
|
extensions[0] = strdup("VK_KHR_surface");
|
||||||
|
extensions[1] = strdup("VK_KHR_wayland_surface");
|
||||||
|
|
||||||
|
*count = 2;
|
||||||
|
return extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||||
|
VkPhysicalDevice device,
|
||||||
|
unsigned int queuefamily)
|
||||||
|
{
|
||||||
|
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR =
|
||||||
|
(PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)
|
||||||
|
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
|
||||||
|
if (!vkGetPhysicalDeviceWaylandPresentationSupportKHR)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Wayland: Vulkan instance missing VK_KHR_wayland_surface extension");
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vkGetPhysicalDeviceWaylandPresentationSupportKHR(device,
|
||||||
|
queuefamily,
|
||||||
|
_glfw.wl.display);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
||||||
|
_GLFWwindow* window,
|
||||||
|
const VkAllocationCallbacks* allocator,
|
||||||
|
VkSurfaceKHR* surface)
|
||||||
|
{
|
||||||
|
VkResult err;
|
||||||
|
VkWaylandSurfaceCreateInfoKHR sci;
|
||||||
|
PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;
|
||||||
|
|
||||||
|
vkCreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR)
|
||||||
|
vkGetInstanceProcAddr(instance, "vkCreateWaylandSurfaceKHR");
|
||||||
|
if (!vkCreateWaylandSurfaceKHR)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Wayland: Vulkan instance missing VK_KHR_wayland_surface extension");
|
||||||
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&sci, 0, sizeof(sci));
|
||||||
|
sci.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
|
||||||
|
sci.display = _glfw.wl.display;
|
||||||
|
sci.surface = window->wl.surface;
|
||||||
|
|
||||||
|
err = vkCreateWaylandSurfaceKHR(instance, &sci, allocator, surface);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to create Vulkan surface: %s",
|
||||||
|
_glfwGetVulkanResultString(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW native API //////
|
////// GLFW native API //////
|
||||||
|
@ -581,6 +581,13 @@ static GLFWbool initExtensions(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glfw.x11.x11xcb.handle = dlopen("libX11-xcb.so", RTLD_LAZY | RTLD_GLOBAL);
|
||||||
|
if (_glfw.x11.x11xcb.handle)
|
||||||
|
{
|
||||||
|
_glfw.x11.x11xcb.XGetXCBConnection = (XGETXCBCONNECTION_T)
|
||||||
|
dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection");
|
||||||
|
}
|
||||||
|
|
||||||
// Update the key code LUT
|
// Update the key code LUT
|
||||||
// FIXME: We should listen to XkbMapNotify events to track changes to
|
// FIXME: We should listen to XkbMapNotify events to track changes to
|
||||||
// the keyboard mapping.
|
// the keyboard mapping.
|
||||||
@ -789,6 +796,12 @@ int _glfwPlatformInit(void)
|
|||||||
|
|
||||||
void _glfwPlatformTerminate(void)
|
void _glfwPlatformTerminate(void)
|
||||||
{
|
{
|
||||||
|
if (_glfw.x11.x11xcb.handle)
|
||||||
|
{
|
||||||
|
dlclose(_glfw.x11.x11xcb.handle);
|
||||||
|
_glfw.x11.x11xcb.handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (_glfw.x11.cursor)
|
if (_glfw.x11.cursor)
|
||||||
{
|
{
|
||||||
XFreeCursor(_glfw.x11.display, _glfw.x11.cursor);
|
XFreeCursor(_glfw.x11.display, _glfw.x11.cursor);
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
@ -56,6 +57,37 @@
|
|||||||
#include <X11/extensions/xf86vmode.h>
|
#include <X11/extensions/xf86vmode.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef XID xcb_window_t;
|
||||||
|
typedef XID xcb_visualid_t;
|
||||||
|
typedef struct xcb_connection_t xcb_connection_t;
|
||||||
|
typedef xcb_connection_t* (* XGETXCBCONNECTION_T)(Display*);
|
||||||
|
|
||||||
|
typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
|
||||||
|
typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
|
||||||
|
|
||||||
|
typedef struct VkXlibSurfaceCreateInfoKHR
|
||||||
|
{
|
||||||
|
VkStructureType sType;
|
||||||
|
const void* pNext;
|
||||||
|
VkXlibSurfaceCreateFlagsKHR flags;
|
||||||
|
Display* dpy;
|
||||||
|
Window window;
|
||||||
|
} VkXlibSurfaceCreateInfoKHR;
|
||||||
|
|
||||||
|
typedef struct VkXcbSurfaceCreateInfoKHR
|
||||||
|
{
|
||||||
|
VkStructureType sType;
|
||||||
|
const void* pNext;
|
||||||
|
VkXcbSurfaceCreateFlagsKHR flags;
|
||||||
|
xcb_connection_t* connection;
|
||||||
|
xcb_window_t window;
|
||||||
|
} VkXcbSurfaceCreateInfoKHR;
|
||||||
|
|
||||||
|
typedef VkResult (APIENTRY *PFN_vkCreateXlibSurfaceKHR)(VkInstance,const VkXlibSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
|
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice,uint32_t,Display*,VisualID);
|
||||||
|
typedef VkResult (APIENTRY *PFN_vkCreateXcbSurfaceKHR)(VkInstance,const VkXcbSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
|
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice,uint32_t,xcb_connection_t*,xcb_visualid_t);
|
||||||
|
|
||||||
#include "posix_tls.h"
|
#include "posix_tls.h"
|
||||||
#include "posix_time.h"
|
#include "posix_time.h"
|
||||||
#include "linux_joystick.h"
|
#include "linux_joystick.h"
|
||||||
@ -71,6 +103,10 @@
|
|||||||
#error "No supported context creation API selected"
|
#error "No supported context creation API selected"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||||
|
#define _glfw_dlclose(handle) dlclose(handle)
|
||||||
|
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11
|
||||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11
|
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11
|
||||||
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11
|
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11
|
||||||
@ -207,6 +243,11 @@ typedef struct _GLFWlibraryX11
|
|||||||
int minor;
|
int minor;
|
||||||
} xinerama;
|
} xinerama;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
void* handle;
|
||||||
|
XGETXCBCONNECTION_T XGetXCBConnection;
|
||||||
|
} x11xcb;
|
||||||
|
|
||||||
#if defined(_GLFW_HAS_XINPUT)
|
#if defined(_GLFW_HAS_XINPUT)
|
||||||
struct {
|
struct {
|
||||||
GLFWbool available;
|
GLFWbool available;
|
||||||
|
168
src/x11_window.c
168
src/x11_window.c
@ -1470,13 +1470,21 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
Visual* visual;
|
Visual* visual;
|
||||||
int depth;
|
int depth;
|
||||||
|
|
||||||
|
if (ctxconfig->api == GLFW_NO_API)
|
||||||
|
{
|
||||||
|
visual = DefaultVisual(_glfw.x11.display, _glfw.x11.screen);
|
||||||
|
depth = DefaultDepth(_glfw.x11.display, _glfw.x11.screen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
#if defined(_GLFW_GLX)
|
#if defined(_GLFW_GLX)
|
||||||
if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth))
|
if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
#elif defined(_GLFW_EGL)
|
#elif defined(_GLFW_EGL)
|
||||||
if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth))
|
if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (!createWindow(window, wndconfig, visual, depth))
|
if (!createWindow(window, wndconfig, visual, depth))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
@ -2109,6 +2117,158 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
|||||||
return _glfw.x11.clipboardString;
|
return _glfw.x11.clipboardString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char** _glfwPlatformGetRequiredInstanceExtensions(int* count)
|
||||||
|
{
|
||||||
|
char** extensions;
|
||||||
|
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
|
if (!_glfw.vk.KHR_xlib_surface)
|
||||||
|
{
|
||||||
|
if (!_glfw.vk.KHR_xcb_surface || !_glfw.x11.x11xcb.handle)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
extensions = calloc(2, sizeof(char*));
|
||||||
|
extensions[0] = strdup("VK_KHR_surface");
|
||||||
|
|
||||||
|
if (_glfw.vk.KHR_xlib_surface)
|
||||||
|
extensions[1] = strdup("VK_KHR_xlib_surface");
|
||||||
|
else
|
||||||
|
extensions[1] = strdup("VK_KHR_xcb_surface");
|
||||||
|
|
||||||
|
*count = 2;
|
||||||
|
return extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||||
|
VkPhysicalDevice device,
|
||||||
|
unsigned int queuefamily)
|
||||||
|
{
|
||||||
|
VisualID visualID = XVisualIDFromVisual(DefaultVisual(_glfw.x11.display,
|
||||||
|
_glfw.x11.screen));
|
||||||
|
|
||||||
|
if (_glfw.vk.KHR_xlib_surface)
|
||||||
|
{
|
||||||
|
PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR =
|
||||||
|
(PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)
|
||||||
|
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
|
||||||
|
if (!vkGetPhysicalDeviceXlibPresentationSupportKHR)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"X11: Vulkan instance missing VK_KHR_xlib_surface extension");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vkGetPhysicalDeviceXlibPresentationSupportKHR(device,
|
||||||
|
queuefamily,
|
||||||
|
_glfw.x11.display,
|
||||||
|
visualID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR =
|
||||||
|
(PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)
|
||||||
|
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
|
||||||
|
if (!vkGetPhysicalDeviceXcbPresentationSupportKHR)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"X11: Vulkan instance missing VK_KHR_xcb_surface extension");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_connection_t* connection =
|
||||||
|
_glfw.x11.x11xcb.XGetXCBConnection(_glfw.x11.display);
|
||||||
|
if (!connection)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"X11: Failed to retrieve XCB connection");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vkGetPhysicalDeviceXcbPresentationSupportKHR(device,
|
||||||
|
queuefamily,
|
||||||
|
connection,
|
||||||
|
visualID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
||||||
|
_GLFWwindow* window,
|
||||||
|
const VkAllocationCallbacks* allocator,
|
||||||
|
VkSurfaceKHR* surface)
|
||||||
|
{
|
||||||
|
if (_glfw.vk.KHR_xlib_surface)
|
||||||
|
{
|
||||||
|
VkResult err;
|
||||||
|
VkXlibSurfaceCreateInfoKHR sci;
|
||||||
|
PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;
|
||||||
|
|
||||||
|
vkCreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR)
|
||||||
|
vkGetInstanceProcAddr(instance, "vkCreateXlibSurfaceKHR");
|
||||||
|
if (!vkCreateXlibSurfaceKHR)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"X11: Vulkan instance missing VK_KHR_xlib_surface extension");
|
||||||
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&sci, 0, sizeof(sci));
|
||||||
|
sci.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
|
||||||
|
sci.dpy = _glfw.x11.display;
|
||||||
|
sci.window = window->x11.handle;
|
||||||
|
|
||||||
|
err = vkCreateXlibSurfaceKHR(instance, &sci, allocator, surface);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"X11: Failed to create Vulkan X11 surface: %s",
|
||||||
|
_glfwGetVulkanResultString(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VkResult err;
|
||||||
|
VkXcbSurfaceCreateInfoKHR sci;
|
||||||
|
PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR;
|
||||||
|
|
||||||
|
xcb_connection_t* connection =
|
||||||
|
_glfw.x11.x11xcb.XGetXCBConnection(_glfw.x11.display);
|
||||||
|
if (!connection)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"X11: Failed to retrieve XCB connection");
|
||||||
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
vkCreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR)
|
||||||
|
vkGetInstanceProcAddr(instance, "vkCreateXcbSurfaceKHR");
|
||||||
|
if (!vkCreateXcbSurfaceKHR)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"X11: Vulkan instance missing VK_KHR_xcb_surface extension");
|
||||||
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&sci, 0, sizeof(sci));
|
||||||
|
sci.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
|
||||||
|
sci.connection = connection;
|
||||||
|
sci.window = window->x11.handle;
|
||||||
|
|
||||||
|
err = vkCreateXcbSurfaceKHR(instance, &sci, allocator, surface);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"X11: Failed to create Vulkan XCB surface: %s",
|
||||||
|
_glfwGetVulkanResultString(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW native API //////
|
////// GLFW native API //////
|
||||||
|
@ -43,6 +43,13 @@ set(WINDOWS_BINARIES empty sharing tearing threads title windows)
|
|||||||
set(CONSOLE_BINARIES clipboard events msaa gamma glfwinfo
|
set(CONSOLE_BINARIES clipboard events msaa gamma glfwinfo
|
||||||
iconify joysticks monitors reopen cursor)
|
iconify joysticks monitors reopen cursor)
|
||||||
|
|
||||||
|
if (VULKAN_FOUND)
|
||||||
|
add_executable(vulkan WIN32 vulkan.c ${ICON})
|
||||||
|
target_include_directories(vulkan PRIVATE "${VULKAN_INCLUDE_DIR}")
|
||||||
|
target_link_libraries(vulkan "${VULKAN_LIBRARY}")
|
||||||
|
list(APPEND WINDOWS_BINARIES vulkan)
|
||||||
|
endif()
|
||||||
|
|
||||||
set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
|
set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
|
||||||
FOLDER "GLFW3/Tests")
|
FOLDER "GLFW3/Tests")
|
||||||
|
|
||||||
|
254
tests/glfwinfo.c
254
tests/glfwinfo.c
@ -24,6 +24,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -61,7 +62,8 @@ static void usage(void)
|
|||||||
printf(" -d, --debug request a debug context\n");
|
printf(" -d, --debug request a debug context\n");
|
||||||
printf(" -f, --forward require a forward-compatible context\n");
|
printf(" -f, --forward require a forward-compatible context\n");
|
||||||
printf(" -h, --help show this help\n");
|
printf(" -h, --help show this help\n");
|
||||||
printf(" -l, --list-extensions list all client API extensions\n");
|
printf(" -l, --list-extensions list all Vulkan and client API extensions\n");
|
||||||
|
printf(" --list-layers list all Vulkan layers\n");
|
||||||
printf(" -m, --major=MAJOR the major number of the required "
|
printf(" -m, --major=MAJOR the major number of the required "
|
||||||
"client API version\n");
|
"client API version\n");
|
||||||
printf(" -n, --minor=MINOR the minor number of the required "
|
printf(" -n, --minor=MINOR the minor number of the required "
|
||||||
@ -96,6 +98,22 @@ static void error_callback(int error, const char* description)
|
|||||||
fprintf(stderr, "Error: %s\n", description);
|
fprintf(stderr, "Error: %s\n", description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* get_device_type_name(VkPhysicalDeviceType type)
|
||||||
|
{
|
||||||
|
if (type == VK_PHYSICAL_DEVICE_TYPE_OTHER)
|
||||||
|
return "other";
|
||||||
|
else if (type == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)
|
||||||
|
return "integrated GPU";
|
||||||
|
else if (type == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
||||||
|
return "discrete GPU";
|
||||||
|
else if (type == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU)
|
||||||
|
return "virtual GPU";
|
||||||
|
else if (type == VK_PHYSICAL_DEVICE_TYPE_CPU)
|
||||||
|
return "CPU";
|
||||||
|
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
static const char* get_api_name(int api)
|
static const char* get_api_name(int api)
|
||||||
{
|
{
|
||||||
if (api == GLFW_OPENGL_API)
|
if (api == GLFW_OPENGL_API)
|
||||||
@ -146,13 +164,13 @@ static const char* get_strategy_name_glfw(int strategy)
|
|||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void list_extensions(int api, int major, int minor)
|
static void list_context_extensions(int api, int major, int minor)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
GLint count;
|
GLint count;
|
||||||
const GLubyte* extensions;
|
const GLubyte* extensions;
|
||||||
|
|
||||||
printf("%s context supported extensions:\n", get_api_name(api));
|
printf("%s context extensions:\n", get_api_name(api));
|
||||||
|
|
||||||
if (api == GLFW_OPENGL_API && major > 2)
|
if (api == GLFW_OPENGL_API && major > 2)
|
||||||
{
|
{
|
||||||
@ -182,6 +200,124 @@ static void list_extensions(int api, int major, int minor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void list_vulkan_instance_extensions(void)
|
||||||
|
{
|
||||||
|
uint32_t i, ep_count = 0;
|
||||||
|
VkExtensionProperties* ep;
|
||||||
|
PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties =
|
||||||
|
(PFN_vkEnumerateInstanceExtensionProperties)
|
||||||
|
glfwGetInstanceProcAddress(NULL, "vkEnumerateInstanceExtensionProperties");
|
||||||
|
|
||||||
|
printf("Vulkan instance extensions:\n");
|
||||||
|
|
||||||
|
if (vkEnumerateInstanceExtensionProperties(NULL, &ep_count, NULL) != VK_SUCCESS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ep = calloc(ep_count, sizeof(VkExtensionProperties));
|
||||||
|
|
||||||
|
if (vkEnumerateInstanceExtensionProperties(NULL, &ep_count, ep) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
free(ep);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ep_count; i++)
|
||||||
|
printf(" %s (v%u)\n", ep[i].extensionName, ep[i].specVersion);
|
||||||
|
|
||||||
|
free(ep);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void list_vulkan_instance_layers(void)
|
||||||
|
{
|
||||||
|
uint32_t i, lp_count = 0;
|
||||||
|
VkLayerProperties* lp;
|
||||||
|
PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties =
|
||||||
|
(PFN_vkEnumerateInstanceLayerProperties)
|
||||||
|
glfwGetInstanceProcAddress(NULL, "vkEnumerateInstanceLayerProperties");
|
||||||
|
|
||||||
|
printf("Vulkan instance layers:\n");
|
||||||
|
|
||||||
|
if (vkEnumerateInstanceLayerProperties(&lp_count, NULL) != VK_SUCCESS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lp = calloc(lp_count, sizeof(VkLayerProperties));
|
||||||
|
|
||||||
|
if (vkEnumerateInstanceLayerProperties(&lp_count, lp) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
free(lp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < lp_count; i++)
|
||||||
|
{
|
||||||
|
printf(" %s (v%u) \"%s\"\n",
|
||||||
|
lp[i].layerName,
|
||||||
|
lp[i].specVersion >> 22,
|
||||||
|
lp[i].description);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(lp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void list_vulkan_device_extensions(VkInstance instance, VkPhysicalDevice device)
|
||||||
|
{
|
||||||
|
uint32_t i, ep_count;
|
||||||
|
VkExtensionProperties* ep;
|
||||||
|
PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties =
|
||||||
|
(PFN_vkEnumerateDeviceExtensionProperties)
|
||||||
|
glfwGetInstanceProcAddress(instance, "vkEnumerateDeviceExtensionProperties");
|
||||||
|
|
||||||
|
printf("Vulkan device extensions:\n");
|
||||||
|
|
||||||
|
if (vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, NULL) != VK_SUCCESS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ep = calloc(ep_count, sizeof(VkExtensionProperties));
|
||||||
|
|
||||||
|
if (vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, ep) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
free(ep);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ep_count; i++)
|
||||||
|
printf(" %s (v%u)\n", ep[i].extensionName, ep[i].specVersion);
|
||||||
|
|
||||||
|
free(ep);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void list_vulkan_device_layers(VkInstance instance, VkPhysicalDevice device)
|
||||||
|
{
|
||||||
|
uint32_t i, lp_count;
|
||||||
|
VkLayerProperties* lp;
|
||||||
|
PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties =
|
||||||
|
(PFN_vkEnumerateDeviceLayerProperties)
|
||||||
|
glfwGetInstanceProcAddress(instance, "vkEnumerateDeviceLayerProperties");
|
||||||
|
|
||||||
|
printf("Vulkan device layers:\n");
|
||||||
|
|
||||||
|
if (vkEnumerateDeviceLayerProperties(device, &lp_count, NULL) != VK_SUCCESS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lp = calloc(lp_count, sizeof(VkLayerProperties));
|
||||||
|
|
||||||
|
if (vkEnumerateDeviceLayerProperties(device, &lp_count, lp) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
free(lp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < lp_count; i++)
|
||||||
|
{
|
||||||
|
printf(" %s (v%u) \"%s\"\n",
|
||||||
|
lp[i].layerName,
|
||||||
|
lp[i].specVersion >> 22,
|
||||||
|
lp[i].description);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(lp);
|
||||||
|
}
|
||||||
|
|
||||||
static int valid_version(void)
|
static int valid_version(void)
|
||||||
{
|
{
|
||||||
int major, minor, revision;
|
int major, minor, revision;
|
||||||
@ -216,10 +352,10 @@ int main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
int ch, api, major, minor, revision, profile;
|
int ch, api, major, minor, revision, profile;
|
||||||
GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits;
|
GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits;
|
||||||
int list = GLFW_FALSE;
|
int list_extensions = GLFW_FALSE, list_layers = GLFW_FALSE;
|
||||||
GLFWwindow* window;
|
GLFWwindow* window;
|
||||||
|
|
||||||
enum { API, BEHAVIOR, DEBUG, FORWARD, HELP, EXTENSIONS,
|
enum { API, BEHAVIOR, DEBUG, FORWARD, HELP, EXTENSIONS, LAYERS,
|
||||||
MAJOR, MINOR, PROFILE, ROBUSTNESS, VERSION,
|
MAJOR, MINOR, PROFILE, ROBUSTNESS, VERSION,
|
||||||
REDBITS, GREENBITS, BLUEBITS, ALPHABITS, DEPTHBITS, STENCILBITS,
|
REDBITS, GREENBITS, BLUEBITS, ALPHABITS, DEPTHBITS, STENCILBITS,
|
||||||
ACCUMREDBITS, ACCUMGREENBITS, ACCUMBLUEBITS, ACCUMALPHABITS,
|
ACCUMREDBITS, ACCUMGREENBITS, ACCUMBLUEBITS, ACCUMALPHABITS,
|
||||||
@ -232,6 +368,7 @@ int main(int argc, char** argv)
|
|||||||
{ "forward", 0, NULL, FORWARD },
|
{ "forward", 0, NULL, FORWARD },
|
||||||
{ "help", 0, NULL, HELP },
|
{ "help", 0, NULL, HELP },
|
||||||
{ "list-extensions", 0, NULL, EXTENSIONS },
|
{ "list-extensions", 0, NULL, EXTENSIONS },
|
||||||
|
{ "list-layers", 0, NULL, LAYERS },
|
||||||
{ "major", 1, NULL, MAJOR },
|
{ "major", 1, NULL, MAJOR },
|
||||||
{ "minor", 1, NULL, MINOR },
|
{ "minor", 1, NULL, MINOR },
|
||||||
{ "profile", 1, NULL, PROFILE },
|
{ "profile", 1, NULL, PROFILE },
|
||||||
@ -314,7 +451,10 @@ int main(int argc, char** argv)
|
|||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
case 'l':
|
case 'l':
|
||||||
case EXTENSIONS:
|
case EXTENSIONS:
|
||||||
list = GLFW_TRUE;
|
list_extensions = GLFW_TRUE;
|
||||||
|
break;
|
||||||
|
case LAYERS:
|
||||||
|
list_layers = GLFW_TRUE;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
case MAJOR:
|
case MAJOR:
|
||||||
@ -564,7 +704,7 @@ int main(int argc, char** argv)
|
|||||||
glGetString(GL_SHADING_LANGUAGE_VERSION));
|
glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Framebuffer:\n");
|
printf("%s framebuffer:\n", get_api_name(api));
|
||||||
|
|
||||||
if (api == GLFW_OPENGL_API && profile == GLFW_OPENGL_CORE_PROFILE)
|
if (api == GLFW_OPENGL_API && profile == GLFW_OPENGL_CORE_PROFILE)
|
||||||
{
|
{
|
||||||
@ -632,9 +772,103 @@ int main(int argc, char** argv)
|
|||||||
accumredbits, accumgreenbits, accumbluebits, accumalphabits, auxbuffers);
|
accumredbits, accumgreenbits, accumbluebits, accumalphabits, auxbuffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report client API extensions
|
if (list_extensions)
|
||||||
if (list)
|
list_context_extensions(api, major, minor);
|
||||||
list_extensions(api, major, minor);
|
|
||||||
|
printf("Vulkan loader: %s\n",
|
||||||
|
glfwVulkanSupported() ? "available" : "missing");
|
||||||
|
|
||||||
|
if (glfwVulkanSupported())
|
||||||
|
{
|
||||||
|
uint32_t i, re_count, pd_count;
|
||||||
|
const char** re;
|
||||||
|
VkApplicationInfo ai = {0};
|
||||||
|
VkInstanceCreateInfo ici = {0};
|
||||||
|
VkInstance instance;
|
||||||
|
VkPhysicalDevice* pd;
|
||||||
|
PFN_vkCreateInstance vkCreateInstance = (PFN_vkCreateInstance)
|
||||||
|
glfwGetInstanceProcAddress(NULL, "vkCreateInstance");
|
||||||
|
PFN_vkDestroyInstance vkDestroyInstance;
|
||||||
|
PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
|
||||||
|
PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
|
||||||
|
|
||||||
|
re = glfwGetRequiredInstanceExtensions((int*) &re_count);
|
||||||
|
|
||||||
|
printf("Vulkan required instance extensions:");
|
||||||
|
for (i = 0; i < re_count; i++)
|
||||||
|
printf(" %s", re[i]);
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
|
if (list_extensions)
|
||||||
|
{
|
||||||
|
list_vulkan_instance_extensions();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list_layers)
|
||||||
|
list_vulkan_instance_layers();
|
||||||
|
|
||||||
|
ai.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||||
|
ai.pApplicationName = "glfwinfo";
|
||||||
|
ai.applicationVersion = GLFW_VERSION_MAJOR;
|
||||||
|
ai.pEngineName = "GLFW";
|
||||||
|
ai.engineVersion = GLFW_VERSION_MAJOR;
|
||||||
|
ai.apiVersion = VK_API_VERSION;
|
||||||
|
|
||||||
|
ici.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
|
ici.pApplicationInfo = &ai;
|
||||||
|
ici.enabledExtensionCount = re_count;
|
||||||
|
ici.ppEnabledExtensionNames = re;
|
||||||
|
|
||||||
|
if (vkCreateInstance(&ici, NULL, &instance) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
glfwTerminate();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
vkDestroyInstance = (PFN_vkDestroyInstance)
|
||||||
|
glfwGetInstanceProcAddress(instance, "vkDestroyInstance");
|
||||||
|
vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices)
|
||||||
|
glfwGetInstanceProcAddress(instance, "vkEnumeratePhysicalDevices");
|
||||||
|
vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties)
|
||||||
|
glfwGetInstanceProcAddress(instance, "vkGetPhysicalDeviceProperties");
|
||||||
|
|
||||||
|
if (vkEnumeratePhysicalDevices(instance, &pd_count, NULL) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
vkDestroyInstance(instance, NULL);
|
||||||
|
glfwTerminate();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
pd = calloc(pd_count, sizeof(VkPhysicalDevice));
|
||||||
|
|
||||||
|
if (vkEnumeratePhysicalDevices(instance, &pd_count, pd) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
free(pd);
|
||||||
|
vkDestroyInstance(instance, NULL);
|
||||||
|
glfwTerminate();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < pd_count; i++)
|
||||||
|
{
|
||||||
|
VkPhysicalDeviceProperties pdp;
|
||||||
|
|
||||||
|
vkGetPhysicalDeviceProperties(pd[i], &pdp);
|
||||||
|
|
||||||
|
printf("Vulkan %s device: \"%s\"\n",
|
||||||
|
get_device_type_name(pdp.deviceType),
|
||||||
|
pdp.deviceName);
|
||||||
|
|
||||||
|
if (list_extensions)
|
||||||
|
list_vulkan_device_extensions(instance, pd[i]);
|
||||||
|
|
||||||
|
if (list_layers)
|
||||||
|
list_vulkan_device_layers(instance, pd[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pd);
|
||||||
|
vkDestroyInstance(instance, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
|
2240
tests/vulkan.c
Normal file
2240
tests/vulkan.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user