mirror of
https://github.com/glfw/glfw.git
synced 2025-10-04 13:46:37 +00:00
Merge branch 'master' into transparent_windows
This commit is contained in:
commit
c76658186b
22
.appveyor.yml
Normal file
22
.appveyor.yml
Normal file
@ -0,0 +1,22 @@
|
||||
branches:
|
||||
only:
|
||||
- ci
|
||||
- master
|
||||
skip_tags: true
|
||||
environment:
|
||||
matrix:
|
||||
- BUILD_SHARED_LIBS: ON
|
||||
- BUILD_SHARED_LIBS: OFF
|
||||
matrix:
|
||||
fast_finish: true
|
||||
build_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% ..
|
||||
- cmake --build .
|
||||
notifications:
|
||||
- provider: Email
|
||||
to:
|
||||
- ci@glfw.org
|
||||
- on_build_failure: true
|
||||
- on_build_success: false
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -71,4 +71,5 @@ tests/tearing
|
||||
tests/threads
|
||||
tests/title
|
||||
tests/version
|
||||
tests/vulkan
|
||||
tests/windows
|
||||
|
30
.travis.yml
Normal file
30
.travis.yml
Normal file
@ -0,0 +1,30 @@
|
||||
language: c
|
||||
compiler: clang
|
||||
branches:
|
||||
only:
|
||||
- ci
|
||||
- master
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
sudo: false
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- kubuntu-backports
|
||||
packages:
|
||||
- cmake
|
||||
env:
|
||||
- BUILD_SHARED_LIBS=ON
|
||||
- BUILD_SHARED_LIBS=OFF
|
||||
script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} ..
|
||||
- cmake --build .
|
||||
notifications:
|
||||
email:
|
||||
recipients:
|
||||
- ci@glfw.org
|
||||
on_success: never
|
||||
on_failure: always
|
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)
|
||||
|
@ -50,6 +50,13 @@ if (BUILD_SHARED_LIBS)
|
||||
set(_GLFW_BUILD_DLL 1)
|
||||
endif()
|
||||
|
||||
if (BUILD_SHARED_LIBS AND UNIX)
|
||||
# On Unix-like systems, shared libraries can use the soname system.
|
||||
set(GLFW_LIB_NAME glfw)
|
||||
else()
|
||||
set(GLFW_LIB_NAME glfw3)
|
||||
endif()
|
||||
|
||||
if (GLFW_USE_WAYLAND)
|
||||
set(GLFW_USE_EGL ON)
|
||||
elseif (GLFW_USE_MIR)
|
||||
@ -59,6 +66,7 @@ endif()
|
||||
set(CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules")
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(Vulkan)
|
||||
|
||||
if (GLFW_BUILD_DOCS)
|
||||
set(DOXYGEN_SKIP_DOT TRUE)
|
||||
@ -347,7 +355,6 @@ endif()
|
||||
#--------------------------------------------------------------------
|
||||
# Export GLFW library dependencies
|
||||
#--------------------------------------------------------------------
|
||||
set(GLFW_LIBRARIES ${glfw_LIBRARIES} CACHE STRING "Dependencies of GLFW")
|
||||
foreach(arg ${glfw_PKG_DEPS})
|
||||
set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} ${arg}")
|
||||
endforeach()
|
||||
@ -360,32 +367,24 @@ endforeach()
|
||||
#--------------------------------------------------------------------
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
if (UNIX)
|
||||
set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/lib/cmake/glfw3/")
|
||||
else()
|
||||
set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/")
|
||||
endif()
|
||||
set(GLFW_CONFIG_PATH "lib${LIB_SUFFIX}/cmake/glfw3")
|
||||
|
||||
configure_package_config_file("${GLFW_SOURCE_DIR}/src/glfw3Config.cmake.in"
|
||||
"${GLFW_BINARY_DIR}/src/glfw3Config.cmake"
|
||||
configure_package_config_file(src/glfw3Config.cmake.in
|
||||
src/glfw3Config.cmake
|
||||
INSTALL_DESTINATION "${GLFW_CONFIG_PATH}"
|
||||
PATH_VARS CMAKE_INSTALL_PREFIX
|
||||
NO_CHECK_REQUIRED_COMPONENTS_MACRO)
|
||||
|
||||
write_basic_package_version_file("${GLFW_BINARY_DIR}/src/glfw3ConfigVersion.cmake"
|
||||
write_basic_package_version_file(src/glfw3ConfigVersion.cmake
|
||||
VERSION ${GLFW_VERSION_FULL}
|
||||
COMPATIBILITY SameMajorVersion)
|
||||
|
||||
if (GLFW_BUILD_DOCS)
|
||||
configure_file("${GLFW_SOURCE_DIR}/docs/Doxyfile.in"
|
||||
"${GLFW_BINARY_DIR}/docs/Doxyfile" @ONLY)
|
||||
configure_file(docs/Doxyfile.in docs/Doxyfile @ONLY)
|
||||
endif()
|
||||
|
||||
configure_file("${GLFW_SOURCE_DIR}/src/glfw_config.h.in"
|
||||
"${GLFW_BINARY_DIR}/src/glfw_config.h" @ONLY)
|
||||
configure_file(src/glfw_config.h.in src/glfw_config.h @ONLY)
|
||||
|
||||
configure_file("${GLFW_SOURCE_DIR}/src/glfw3.pc.in"
|
||||
"${GLFW_BINARY_DIR}/src/glfw3.pc" @ONLY)
|
||||
configure_file(src/glfw3.pc.in src/glfw3.pc @ONLY)
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Add subdirectories
|
||||
@ -414,16 +413,18 @@ if (GLFW_INSTALL)
|
||||
|
||||
install(FILES "${GLFW_BINARY_DIR}/src/glfw3Config.cmake"
|
||||
"${GLFW_BINARY_DIR}/src/glfw3ConfigVersion.cmake"
|
||||
DESTINATION lib${LIB_SUFFIX}/cmake/glfw)
|
||||
DESTINATION "${GLFW_CONFIG_PATH}")
|
||||
|
||||
install(EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX}/cmake/glfw)
|
||||
install(EXPORT glfwTargets FILE glfw3Targets.cmake
|
||||
EXPORT_LINK_INTERFACE_LIBRARIES
|
||||
DESTINATION "${GLFW_CONFIG_PATH}")
|
||||
install(FILES "${GLFW_BINARY_DIR}/src/glfw3.pc"
|
||||
DESTINATION lib${LIB_SUFFIX}/pkgconfig)
|
||||
DESTINATION "lib${LIB_SUFFIX}/pkgconfig")
|
||||
|
||||
# Only generate this target if no higher-level project already has
|
||||
if (NOT TARGET uninstall)
|
||||
configure_file("${GLFW_SOURCE_DIR}/cmake_uninstall.cmake.in"
|
||||
"${GLFW_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
|
||||
configure_file(cmake_uninstall.cmake.in
|
||||
cmake_uninstall.cmake IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(uninstall
|
||||
"${CMAKE_COMMAND}" -P
|
||||
|
106
CONTRIBUTING.md
Normal file
106
CONTRIBUTING.md
Normal file
@ -0,0 +1,106 @@
|
||||
# Contribution Guide
|
||||
|
||||
This file is a work in progress and you can report errors or submit patches for
|
||||
it the same as any other file.
|
||||
|
||||
|
||||
## Reporting a bug
|
||||
|
||||
If GLFW is behaving unexpectedly, make sure you have set an error callback.
|
||||
GLFW will often tell you the cause of an issue via this callback.
|
||||
|
||||
If GLFW is crashing or triggering asserts, make sure that all your object
|
||||
handles and other pointers are valid.
|
||||
|
||||
Always include the __operating system name and version__ (i.e. `Windows
|
||||
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW,
|
||||
include the __GLFW release version__ (i.e. `3.1.2`), otherwise include the
|
||||
__GLFW commit ID__ (i.e. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
|
||||
If possible, please also include the __GLFW version string__ (`3.2.0 X11 EGL
|
||||
clock_gettime /dev/js XI Xf86vm`), as described
|
||||
[here](http://www.glfw.org/docs/latest/intro.html#intro_version_string).
|
||||
|
||||
|
||||
### Reporting a compile or link bug
|
||||
|
||||
__Note:__ GLFW needs many system APIs to do its job. See the [Building
|
||||
applications](http://www.glfw.org/docs/latest/build.html) guide for more
|
||||
information.
|
||||
|
||||
In addition to the information above, always include the complete build log from
|
||||
your compiler and linker. Issue posts are editable so it can always be
|
||||
shortened later.
|
||||
|
||||
|
||||
### Reporting a context creation bug
|
||||
|
||||
__Note:__ Windows ships with graphics drivers that do not support OpenGL. If
|
||||
GLFW says that your machine lacks support for OpenGL, it very likely does.
|
||||
Install drivers from the computer manufacturer or graphics card manufacturer
|
||||
([Nvidia](http://www.geforce.com/drivers),
|
||||
[AMD](http://support.amd.com/en-us/download),
|
||||
[Intel](https://www-ssl.intel.com/content/www/us/en/support/detect.html)) to
|
||||
fix this.
|
||||
|
||||
__Note:__ AMD only supports OpenGL ES on Windows via EGL. EGL support is not
|
||||
enabled in GLFW by default. You need to [enable EGL when
|
||||
compiling](http://www.glfw.org/docs/latest/compile.html) GLFW to use this.
|
||||
|
||||
The `glfwinfo` tool is included in the GLFW source tree as `tests/glfwinfo.c`
|
||||
and is built along with the library. It lets you request any kind of context
|
||||
and framebuffer format supported by the GLFW API without having to recompile.
|
||||
If context creation fails in your application, please verify that it also fails
|
||||
with this tool before reporting it as a bug.
|
||||
|
||||
In addition to the information above (OS and GLFW version), always include the
|
||||
__GPU model and driver version__ (i.e. `GeForce GTX660 with 352.79`) when
|
||||
reporting this kind of bug.
|
||||
|
||||
|
||||
### Reporting a monitor or video mode bug
|
||||
|
||||
__Note:__ On headless systems on some platforms, no monitors are reported. This
|
||||
causes glfwGetPrimaryMonitor to return `NULL`, which not all applications are
|
||||
prepared for.
|
||||
|
||||
__Note:__ Some third-party tools report more video modes than those approved of
|
||||
by the OS. For safety and compatbility, GLFW only reports video modes the OS
|
||||
wants programs to use. This is not a bug.
|
||||
|
||||
The `monitors` tool is included in the GLFW source tree as `tests/monitors.c`
|
||||
and is built along with the library. lists all information about connected
|
||||
monitors made available by GLFW.
|
||||
|
||||
In addition to the information above (OS and GLFW version), please also include
|
||||
the output of the `monitors` tool when reporting this kind of bug. If it
|
||||
doesn't work at all, please mention this.
|
||||
|
||||
|
||||
### Reporting a window event bug
|
||||
|
||||
__Note:__ While GLFW tries to provide the exact same behavior between platforms,
|
||||
the exact ordering of related window events will sometimes differ.
|
||||
|
||||
The `events` tool is included in the GLFW source tree as `tests/events.c` and is
|
||||
built along with the library. It prints all information provided to every
|
||||
callback supported by GLFW as events occur. Each event is listed with the time
|
||||
and a unique number to make discussions about event logs easier. The tool has
|
||||
command-line options for creating multiple windows and full screen windows.
|
||||
|
||||
|
||||
### Reporting a documentation bug
|
||||
|
||||
If you found the error in the generated documentation then it's fine to just
|
||||
link to that webpage. You don't need to figure out which documentation source
|
||||
file the text comes from.
|
||||
|
||||
|
||||
## Contributing a bug fix
|
||||
|
||||
There should be text here, but there isn't.
|
||||
|
||||
|
||||
## Contributing a feature
|
||||
|
||||
This is not (yet) the text you are looking for.
|
||||
|
25
README.md
25
README.md
@ -1,10 +1,13 @@
|
||||
# GLFW
|
||||
|
||||
[](https://travis-ci.org/glfw/glfw)
|
||||
[](https://ci.appveyor.com/project/elmindreda/glfw)
|
||||
|
||||
## Introduction
|
||||
|
||||
GLFW is a free, Open Source, multi-platform library for OpenGL and OpenGL ES
|
||||
application development. It provides a simple, platform-independent API for
|
||||
creating windows and contexts, reading input, handling events, etc.
|
||||
GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and
|
||||
Vulkan application development. It provides a simple, platform-independent API
|
||||
for creating windows, contexts and surfaces, reading input, handling events, etc.
|
||||
|
||||
Version 3.2 is _not yet described_.
|
||||
|
||||
@ -47,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
|
||||
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
|
||||
used by the tests and examples and are not required to build the library.
|
||||
@ -61,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
|
||||
examples
|
||||
|
||||
The Vulkan example additionally requires the Vulkan SDK to be installed, or it
|
||||
will not be included in the build.
|
||||
|
||||
|
||||
## Changelog
|
||||
|
||||
- Added `glfwVulkanSupported`, `glfwGetRequiredInstanceExtensions`,
|
||||
`glfwGetInstanceProcAddress`, `glfwGetPhysicalDevicePresentationSupport` and
|
||||
`glfwCreateWindowSurface` for platform independent Vulkan support
|
||||
- Added `glfwSetWindowSizeLimits` and `glfwSetWindowAspectRatio` for setting
|
||||
absolute and relative window size limits
|
||||
- Added `glfwGetKeyName` for querying the layout-specific name of printable
|
||||
keys
|
||||
- Added `GLFW_NO_API` for creating window without contexts
|
||||
- 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 `glfwGetGLXWindow` to query the `GLXWindow` of a window
|
||||
- Added icons to examples on Windows and OS X
|
||||
@ -85,8 +95,10 @@ used by the tests and examples and are not required to build the library.
|
||||
when no windows existed
|
||||
- [Cocoa] Removed support for OS X 10.6
|
||||
- [Cocoa] Bugfix: Full screen windows on secondary monitors were mispositioned
|
||||
- [Cocoa] Bugfix: Connecting a joystick that reports no name would segfault
|
||||
- [X11] Bugfix: Monitor connection and disconnection events were not reported
|
||||
- [X11] Bugfix: Decoding of UTF-8 text from XIM could continue past the end
|
||||
- [X11] Bugfix: An XKB structure was leaked during `glfwInit`
|
||||
- [POSIX] Bugfix: An unrelated TLS key could be deleted by `glfwTerminate`
|
||||
- [WGL] Changed extension loading to only be performed once
|
||||
- [WGL] Removed dependency on external WGL headers
|
||||
@ -95,6 +107,8 @@ used by the tests and examples and are not required to build the library.
|
||||
- [GLX] Bugfix: NetBSD does not provide `libGL.so.1`
|
||||
- [EGL] Added `_GLFW_USE_EGLPLATFORM_H` configuration macro for controlling
|
||||
whether to use an existing `EGL/eglplatform.h` header
|
||||
- [EGL] Added and documented test for if the context is current on the calling
|
||||
thread during buffer swap
|
||||
- [EGL] Removed dependency on external EGL headers
|
||||
|
||||
|
||||
@ -161,6 +175,7 @@ skills.
|
||||
- Osman Keskin
|
||||
- Cameron King
|
||||
- Peter Knut
|
||||
- Christoph Kubisch
|
||||
- Eric Larson
|
||||
- Robin Leffmann
|
||||
- Glenn Lewis
|
||||
@ -170,6 +185,7 @@ skills.
|
||||
- Martins Mozeiko
|
||||
- Tristam MacDonald
|
||||
- Hans Mackowiak
|
||||
- Zbigniew Mandziejewicz
|
||||
- Kyle McDonald
|
||||
- David Medlock
|
||||
- Bryce Mehring
|
||||
@ -217,6 +233,7 @@ skills.
|
||||
- urraka
|
||||
- Jari Vetoniemi
|
||||
- Ricardo Vieira
|
||||
- Nicholas Vitovitch
|
||||
- Simon Voordouw
|
||||
- Torsten Walluhn
|
||||
- Patrick Walton
|
||||
|
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
@ -195,7 +195,15 @@ TAB_SIZE = 8
|
||||
# will result in a user-defined paragraph with heading "Side Effects:".
|
||||
# You can put \n's in the value part of an alias to insert newlines.
|
||||
|
||||
ALIASES =
|
||||
ALIASES = "thread_safety=@par Thread safety\n" \
|
||||
"pointer_lifetime=@par Pointer lifetime\n" \
|
||||
"analysis=@par Analysis\n" \
|
||||
"reentrancy=@par Reentrancy\n" \
|
||||
"errors=@par Errors\n" \
|
||||
"glfw3=@par\n__GLFW 3:__" \
|
||||
"x11=__X11:__" \
|
||||
"win32=__Windows:__" \
|
||||
"osx=__OS X:__"
|
||||
|
||||
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
||||
# A mapping has the form "name=value". For example adding
|
||||
@ -666,6 +674,7 @@ INPUT = @GLFW_INTERNAL_DOCS@ \
|
||||
@GLFW_SOURCE_DIR@/docs/monitor.dox \
|
||||
@GLFW_SOURCE_DIR@/docs/window.dox \
|
||||
@GLFW_SOURCE_DIR@/docs/input.dox \
|
||||
@GLFW_SOURCE_DIR@/docs/vulkan.dox \
|
||||
@GLFW_SOURCE_DIR@/docs/rift.dox \
|
||||
@GLFW_SOURCE_DIR@/docs/compat.dox
|
||||
|
||||
@ -1582,7 +1591,8 @@ PREDEFINED = GLFWAPI= \
|
||||
GLFW_EXPOSE_NATIVE_GLX \
|
||||
GLFW_EXPOSE_NATIVE_COCOA \
|
||||
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
|
||||
# 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`
|
||||
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
|
||||
header. This is useful in combination with an extension loading library.
|
||||
|
||||
@ -148,6 +151,10 @@ uses OpenGL and `glu32` if it uses GLU.
|
||||
|
||||
@subsection build_link_cmake_source With CMake and GLFW source
|
||||
|
||||
This section is about using CMake to compile and link GLFW along with your
|
||||
application. If you want to use an installed binary instead, see @ref
|
||||
build_link_cmake_module.
|
||||
|
||||
With just a few changes to your `CMakeLists.txt` you can have the GLFW source
|
||||
tree built along with your application.
|
||||
|
||||
@ -158,73 +165,70 @@ will add the `glfw` target and the necessary cache variables to your project.
|
||||
add_subdirectory(path/to/glfw)
|
||||
@endcode
|
||||
|
||||
To be able to include the GLFW header from your code, you need to tell the
|
||||
compiler where to find it.
|
||||
Once GLFW has been added to the project, link against it with the `glfw` target.
|
||||
This adds all link-time dependencies of GLFW as it is currently configured,
|
||||
the include directory for the GLFW header and, when applicable, the
|
||||
[GLFW_DLL](@ref build_macros) macro.
|
||||
|
||||
@code{.cmake}
|
||||
include_directories(path/to/glfw/include)
|
||||
target_link_libraries(myapp glfw)
|
||||
@endcode
|
||||
|
||||
Once GLFW has been added to the project, the `GLFW_LIBRARIES` cache variable
|
||||
contains all link-time dependencies of GLFW as it is currently configured. To
|
||||
link against GLFW, link against them and the `glfw` target.
|
||||
Note that it does not include GLU, as GLFW does not use it. If your application
|
||||
needs GLU, you can find it by requiring the OpenGL package.
|
||||
|
||||
@code{.cmake}
|
||||
target_link_libraries(myapp glfw ${GLFW_LIBRARIES})
|
||||
find_package(OpenGL REQUIRED)
|
||||
@endcode
|
||||
|
||||
Note that `GLFW_LIBRARIES` does not include GLU, as GLFW does not use it. If
|
||||
your application needs GLU, you can add it to the list of dependencies with the
|
||||
`OPENGL_glu_LIBRARY` cache variable, which is implicitly created when the GLFW
|
||||
CMake files look for OpenGL.
|
||||
If GLU is found, the `OPENGL_GLU_FOUND` variable is true and the
|
||||
`OPENGL_INCLUDE_DIR` and `OPENGL_glu_LIBRARY` cache variables can be used.
|
||||
|
||||
@code{.cmake}
|
||||
target_link_libraries(myapp glfw ${OPENGL_glu_LIBRARY} ${GLFW_LIBRARIES})
|
||||
target_include_directories(myapp ${OPENGL_INCLUDE_DIR})
|
||||
target_link_libraries(myapp ${OPENGL_glu_LIBRARY})
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection build_link_cmake_pkgconfig With CMake on Unix and installed GLFW binaries
|
||||
@subsection build_link_cmake_module With CMake and installed GLFW binaries
|
||||
|
||||
CMake can import settings from pkg-config, which GLFW supports. When you
|
||||
installed GLFW, the pkg-config file `glfw3.pc` was installed along with it.
|
||||
This section is about using CMake to link GLFW after it has been built and
|
||||
installed. If you want to build it along with your application instead, see
|
||||
@ref build_link_cmake_source.
|
||||
|
||||
First you need to find the PkgConfig package. If this fails, you may need to
|
||||
install the pkg-config package for your distribution.
|
||||
With just a few changes to your `CMakeLists.txt`, you can locate the module and
|
||||
target files generated when GLFW is installed.
|
||||
|
||||
@code{.cmake}
|
||||
find_package(PkgConfig REQUIRED)
|
||||
find_package(glfw3 3.2 REQUIRED)
|
||||
@endcode
|
||||
|
||||
This creates the CMake commands to find pkg-config packages. Then you need to
|
||||
find the GLFW package.
|
||||
Once GLFW has been located, link against it with the `glfw` target. This adds
|
||||
all link-time dependencies of GLFW as it is currently configured, the include
|
||||
directory for the GLFW header and, when applicable, the
|
||||
[GLFW_DLL](@ref build_macros) macro.
|
||||
|
||||
@code{.cmake}
|
||||
pkg_search_module(GLFW REQUIRED glfw3)
|
||||
target_link_libraries(myapp glfw)
|
||||
@endcode
|
||||
|
||||
This creates the CMake variables you need to use GLFW. To be able to include
|
||||
the GLFW header, you need to tell your compiler where it is.
|
||||
Note that it does not include GLU, as GLFW does not use it. If your application
|
||||
needs GLU, you can find it by requiring the OpenGL package.
|
||||
|
||||
@code{.cmake}
|
||||
include_directories(${GLFW_INCLUDE_DIRS})
|
||||
find_package(OpenGL REQUIRED)
|
||||
@endcode
|
||||
|
||||
You also need to link against the correct libraries. If you are using the
|
||||
shared library version of GLFW, use the `GLFW_LIBRARIES` variable.
|
||||
If GLU is found, the `OPENGL_GLU_FOUND` variable is true and the
|
||||
`OPENGL_INCLUDE_DIR` and `OPENGL_glu_LIBRARY` cache variables can be used.
|
||||
|
||||
@code{.cmake}
|
||||
target_link_libraries(simple ${GLFW_LIBRARIES})
|
||||
@endcode
|
||||
|
||||
If you are using the static library version of GLFW, use the
|
||||
`GLFW_STATIC_LIBRARIES` variable instead.
|
||||
|
||||
@code{.cmake}
|
||||
target_link_libraries(simple ${GLFW_STATIC_LIBRARIES})
|
||||
target_include_directories(myapp ${OPENGL_INCLUDE_DIR})
|
||||
target_link_libraries(myapp ${OPENGL_glu_LIBRARY})
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection build_link_pkgconfig With pkg-config on OS X or other Unix
|
||||
@subsection build_link_pkgconfig With makefiles and pkg-config on Unix
|
||||
|
||||
GLFW supports [pkg-config](http://www.freedesktop.org/wiki/Software/pkg-config/),
|
||||
and the `glfw3.pc` pkf-config file is generated when the GLFW library is built
|
||||
|
@ -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
|
||||
`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
|
||||
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
|
||||
|
||||
|
@ -4,9 +4,9 @@
|
||||
|
||||
@section main_intro Introduction
|
||||
|
||||
__GLFW__ is a free, Open Source, multi-platform library for creating windows
|
||||
with OpenGL or OpenGL ES contexts and receiving many kinds of input. It is easy
|
||||
to integrate into existing applications and does not lay claim to the main loop.
|
||||
GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and
|
||||
Vulkan application development. It provides a simple, platform-independent API
|
||||
for creating windows, contexts and surfaces, reading input, handling events, etc.
|
||||
|
||||
See @ref news_32 for release highlights or the
|
||||
[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,
|
||||
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 [FAQ](http://www.glfw.org/faq.html) answers many common questions about the
|
||||
|
@ -61,6 +61,9 @@ used from any thread and which must only be used from the main thread.
|
||||
`glfwUnlockMutex`, `glfwCreateCond`, `glfwDestroyCond`, `glfwWaitCond`,
|
||||
`glfwSignalCond`, `glfwBroadcastCond` and `glfwGetNumberOfProcessors`.
|
||||
|
||||
@par Removed types
|
||||
`GLFWthreadfun`
|
||||
|
||||
|
||||
@subsection moving_image Removal of image and texture loading
|
||||
|
||||
@ -467,6 +470,15 @@ defining `GLFW_INCLUDE_GLU` before the inclusion of the GLFW header.
|
||||
| `glfwGetDesktopMode` | @ref glfwGetVideoMode | Returns the current mode of a monitor |
|
||||
| `glfwGetJoystickParam` | @ref glfwJoystickPresent | The axis and button counts are provided by @ref glfwGetJoystickAxes and @ref glfwGetJoystickButtons |
|
||||
|
||||
|
||||
@subsection moving_renamed_types Renamed types
|
||||
|
||||
| GLFW 2 | GLFW 3 | Notes |
|
||||
| ------------------- | --------------------- | |
|
||||
| `GLFWmousewheelfun` | @ref GLFWscrollfun | |
|
||||
| `GLFWmouseposfun` | @ref GLFWcursorposfun | |
|
||||
|
||||
|
||||
@subsection moving_renamed_tokens Renamed tokens
|
||||
|
||||
| GLFW 2 | GLFW 3 | Notes |
|
||||
|
@ -17,6 +17,15 @@ GLFW now supports querying the localized name of printable keys with @ref
|
||||
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
|
||||
|
||||
These are the release highlights. For a full list of changes see the
|
||||
|
@ -64,7 +64,9 @@ successful initialization, `GLFW_TRUE` is returned. If an error occurred,
|
||||
|
||||
@code
|
||||
if (!glfwInit())
|
||||
exit(EXIT_FAILURE);
|
||||
{
|
||||
// Initialization failed
|
||||
}
|
||||
@endcode
|
||||
|
||||
Note that `GLFW_TRUE` and `GLFW_FALSE` are and will always be just one and zero.
|
||||
@ -112,22 +114,36 @@ glfwSetErrorCallback(error_callback);
|
||||
|
||||
@subsection quick_create_window Creating a window and context
|
||||
|
||||
The window and its OpenGL context are created with a single call, which returns
|
||||
a handle to the created combined window and context object. For example, this
|
||||
creates a 640 by 480 windowed mode window with an OpenGL context:
|
||||
The window and its OpenGL context are created with a single call to @ref
|
||||
glfwCreateWindow, which returns a handle to the created combined window and
|
||||
context object
|
||||
|
||||
@code
|
||||
GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL);
|
||||
@endcode
|
||||
|
||||
If window or context creation fails, `NULL` will be returned, so it is necessary
|
||||
to check the return value.
|
||||
|
||||
@code
|
||||
if (!window)
|
||||
{
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
// Window or OpenGL context creation failed
|
||||
}
|
||||
@endcode
|
||||
|
||||
This creates a 640 by 480 windowed mode window with an OpenGL context. If
|
||||
window or OpenGL context creation fails, `NULL` will be returned. You should
|
||||
always check the return value. While window creation rarely fails, context
|
||||
creation depends on properly installed drivers and may fail even on machines
|
||||
with the necessary hardware.
|
||||
|
||||
By default, the OpenGL context GLFW creates may have any version. You can
|
||||
require a minimum OpenGL version by setting the `GLFW_CONTEXT_VERSION_MAJOR` and
|
||||
`GLFW_CONTEXT_VERSION_MINOR` hints _before_ creation. If the required minimum
|
||||
version is not supported on the machine, context (and window) creation fails.
|
||||
|
||||
@code
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||
GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL);
|
||||
if (!window)
|
||||
{
|
||||
// Window or context creation failed
|
||||
}
|
||||
@endcode
|
||||
|
||||
@ -135,7 +151,7 @@ The window handle is passed to all window related functions and is provided to
|
||||
along to all window related callbacks, so they can tell which window received
|
||||
the event.
|
||||
|
||||
When a window is no longer needed, destroy it.
|
||||
When a window and context is no longer needed, destroy it.
|
||||
|
||||
@code
|
||||
glfwDestroyWindow(window);
|
||||
|
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,19 +1,17 @@
|
||||
|
||||
link_libraries(glfw)
|
||||
|
||||
include_directories(${glfw_INCLUDE_DIRS})
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
add_definitions(-DGLFW_DLL)
|
||||
link_libraries("${MATH_LIBRARY}")
|
||||
else()
|
||||
link_libraries(${glfw_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
include_directories("${GLFW_SOURCE_DIR}/include"
|
||||
"${GLFW_SOURCE_DIR}/deps")
|
||||
include_directories("${GLFW_SOURCE_DIR}/deps")
|
||||
|
||||
if (WIN32)
|
||||
set(ICON glfw.rc)
|
||||
|
1288
include/GLFW/glfw3.h
1288
include/GLFW/glfw3.h
File diff suppressed because it is too large
Load Diff
@ -127,11 +127,10 @@ extern "C" {
|
||||
* of the specified monitor, or `NULL` if an [error](@ref error_handling)
|
||||
* occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.1.
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -143,11 +142,10 @@ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
|
||||
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.1.
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -158,11 +156,10 @@ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
|
||||
* @return The `HWND` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -175,11 +172,10 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
|
||||
* @return The `HGLRC` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -192,11 +188,10 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
|
||||
* @return The `CGDirectDisplayID` of the specified monitor, or
|
||||
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.1.
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -207,11 +202,10 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
|
||||
* @return The `NSWindow` of the specified window, or `nil` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -224,11 +218,10 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
|
||||
* @return The `NSOpenGLContext` of the specified window, or `nil` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -241,11 +234,10 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
|
||||
* @return The `Display` used by GLFW, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -256,11 +248,10 @@ GLFWAPI Display* glfwGetX11Display(void);
|
||||
* @return The `RRCrtc` of the specified monitor, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.1.
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -271,11 +262,10 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
|
||||
* @return The `RROutput` of the specified monitor, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.1.
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -286,11 +276,10 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
|
||||
* @return The `Window` of the specified window, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -303,11 +292,10 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
|
||||
* @return The `GLXContext` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -318,11 +306,10 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
|
||||
* @return The `GLXWindow` of the specified window, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.2.
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -335,11 +322,10 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
|
||||
* @return The `struct wl_display*` used by GLFW, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.2.
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -350,11 +336,10 @@ GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
|
||||
* @return The `struct wl_output*` of the specified monitor, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.2.
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -365,11 +350,10 @@ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
|
||||
* @return The main `struct wl_surface*` of the specified window, or `NULL` if
|
||||
* an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.2.
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -382,11 +366,10 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
|
||||
* @return The `MirConnection*` used by GLFW, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.2.
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -397,11 +380,10 @@ GLFWAPI MirConnection* glfwGetMirDisplay(void);
|
||||
* @return The Mir output ID of the specified monitor, or zero if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.2.
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -412,11 +394,10 @@ GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor);
|
||||
* @return The `MirSurface*` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.2.
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -429,11 +410,10 @@ GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window);
|
||||
* @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -444,11 +424,10 @@ GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
|
||||
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
@ -459,11 +438,10 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
|
||||
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
|
@ -3,7 +3,7 @@ set(common_HEADERS internal.h
|
||||
"${GLFW_BINARY_DIR}/src/glfw_config.h"
|
||||
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3.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)
|
||||
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h cocoa_joystick.h
|
||||
@ -52,12 +52,16 @@ endif()
|
||||
|
||||
add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
|
||||
set_target_properties(glfw PROPERTIES
|
||||
OUTPUT_NAME ${GLFW_LIB_NAME}
|
||||
VERSION ${GLFW_VERSION}
|
||||
SOVERSION ${GLFW_VERSION_MAJOR}
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
FOLDER "GLFW3")
|
||||
|
||||
target_compile_definitions(glfw PRIVATE -D_GLFW_USE_CONFIG_H)
|
||||
target_include_directories(glfw PUBLIC
|
||||
$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>)
|
||||
target_include_directories(glfw PRIVATE
|
||||
"${GLFW_SOURCE_DIR}/src"
|
||||
"${GLFW_BINARY_DIR}/src"
|
||||
@ -92,26 +96,22 @@ if (BUILD_SHARED_LIBS)
|
||||
target_compile_options(glfw PRIVATE "-fno-common")
|
||||
|
||||
set_target_properties(glfw PROPERTIES
|
||||
INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}")
|
||||
INSTALL_NAME_DIR "lib${LIB_SUFFIX}")
|
||||
elseif (UNIX)
|
||||
# Hide symbols not explicitly tagged for export from the shared library
|
||||
target_compile_options(glfw PRIVATE "-fvisibility=hidden")
|
||||
endif()
|
||||
|
||||
target_link_libraries(glfw ${glfw_LIBRARIES})
|
||||
target_compile_definitions(glfw INTERFACE -DGLFW_DLL)
|
||||
target_link_libraries(glfw PRIVATE ${glfw_LIBRARIES})
|
||||
else()
|
||||
target_link_libraries(glfw INTERFACE ${glfw_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
if (BUILD_SHARED_LIBS AND UNIX)
|
||||
# On Unix-like systems, shared libraries can use the soname system.
|
||||
set_target_properties(glfw PROPERTIES OUTPUT_NAME glfw)
|
||||
else()
|
||||
set_target_properties(glfw PROPERTIES OUTPUT_NAME glfw3)
|
||||
endif()
|
||||
|
||||
if (GLFW_INSTALL)
|
||||
install(TARGETS glfw EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX})
|
||||
endif()
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_error.h>
|
||||
@ -287,10 +288,15 @@ static void matchCallback(void* context,
|
||||
|
||||
CFStringRef name = IOHIDDeviceGetProperty(deviceRef,
|
||||
CFSTR(kIOHIDProductKey));
|
||||
CFStringGetCString(name,
|
||||
joystick->name,
|
||||
sizeof(joystick->name),
|
||||
kCFStringEncodingUTF8);
|
||||
if (name)
|
||||
{
|
||||
CFStringGetCString(name,
|
||||
joystick->name,
|
||||
sizeof(joystick->name),
|
||||
kCFStringEncodingUTF8);
|
||||
}
|
||||
else
|
||||
strncpy(joystick->name, "Unknown", sizeof(joystick->name));
|
||||
|
||||
joystick->axisElements = CFArrayCreateMutable(NULL, 0, NULL);
|
||||
joystick->buttonElements = CFArrayCreateMutable(NULL, 0, NULL);
|
||||
|
@ -28,6 +28,7 @@
|
||||
#define _glfw3_cocoa_platform_h_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#if defined(__OBJC__)
|
||||
#import <Carbon/Carbon.h>
|
||||
@ -47,6 +48,10 @@ typedef void* id;
|
||||
#error "The Cocoa backend depends on NSGL platform support"
|
||||
#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_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns
|
||||
#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeNS ns_time
|
||||
|
@ -1332,6 +1332,27 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
||||
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 //////
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
@ -572,6 +573,7 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
|
||||
GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
@ -601,6 +603,8 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
|
||||
{
|
||||
_GLFWwindow* window;
|
||||
|
||||
assert(extension);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
|
||||
window = _glfwPlatformGetCurrentContext();
|
||||
@ -663,6 +667,8 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
|
||||
|
||||
GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
|
||||
{
|
||||
assert(procname);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (!_glfwPlatformGetCurrentContext())
|
||||
|
@ -584,6 +584,13 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
|
||||
|
||||
void _glfwPlatformSwapBuffers(_GLFWwindow* window)
|
||||
{
|
||||
if (window != _glfwPlatformGetCurrentContext())
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: The context must be current on the calling thread when swapping buffers");
|
||||
return;
|
||||
}
|
||||
|
||||
eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);
|
||||
}
|
||||
|
||||
|
@ -28,17 +28,6 @@
|
||||
#ifndef _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)
|
||||
#include <EGL/eglplatform.h>
|
||||
#elif defined(_GLFW_WIN32)
|
||||
|
@ -1,15 +1 @@
|
||||
# - Config file for the glfw3 package
|
||||
# It defines the following variables
|
||||
# GLFW3_INCLUDE_DIR, the path where GLFW headers are located
|
||||
# GLFW3_LIBRARY_DIR, folder in which the GLFW library is located
|
||||
# GLFW3_LIBRARY, library to link against to use GLFW
|
||||
|
||||
set(GLFW3_VERSION "@GLFW_VERSION_FULL@")
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
set_and_check(GLFW3_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_PREFIX@/include")
|
||||
set_and_check(GLFW3_LIBRARY_DIR "@PACKAGE_CMAKE_INSTALL_PREFIX@/lib@LIB_SUFFIX@")
|
||||
|
||||
find_library(GLFW3_LIBRARY "@GLFW_LIB_NAME@" HINTS ${GLFW3_LIBRARY_DIR})
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/glfw3Targets.cmake")
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#ifndef GLXBadProfileARB
|
||||
#define GLXBadProfileARB 13
|
||||
|
@ -130,6 +130,8 @@ GLFWAPI int glfwInit(void)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfwInitVulkan();
|
||||
|
||||
_glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount);
|
||||
_glfwInitialized = GLFW_TRUE;
|
||||
|
||||
@ -161,6 +163,8 @@ GLFWAPI void glfwTerminate(void)
|
||||
_glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp);
|
||||
}
|
||||
|
||||
_glfwTerminateVulkan();
|
||||
|
||||
_glfwFreeMonitors(_glfw.monitors, _glfw.monitorCount);
|
||||
_glfw.monitors = NULL;
|
||||
_glfw.monitorCount = 0;
|
||||
|
34
src/input.c
34
src/input.c
@ -27,6 +27,7 @@
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Internal key state used for sticky keys
|
||||
@ -239,6 +240,7 @@ GLFWbool _glfwIsPrintable(int key)
|
||||
GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(0);
|
||||
|
||||
@ -259,6 +261,7 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
|
||||
GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
@ -288,6 +291,7 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode)
|
||||
GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
|
||||
|
||||
@ -310,6 +314,7 @@ GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
|
||||
GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
|
||||
|
||||
@ -333,6 +338,7 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button)
|
||||
GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
if (xpos)
|
||||
*xpos = 0;
|
||||
@ -355,6 +361,7 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
|
||||
GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
@ -378,6 +385,8 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
|
||||
{
|
||||
_GLFWcursor* cursor;
|
||||
|
||||
assert(image);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
cursor = calloc(1, sizeof(_GLFWcursor));
|
||||
@ -462,6 +471,7 @@ GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) windowHandle;
|
||||
_GLFWcursor* cursor = (_GLFWcursor*) cursorHandle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
@ -473,6 +483,8 @@ GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
|
||||
GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.key, cbfun);
|
||||
return cbfun;
|
||||
@ -481,6 +493,8 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
|
||||
GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.character, cbfun);
|
||||
return cbfun;
|
||||
@ -489,6 +503,8 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun)
|
||||
GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmodsfun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.charmods, cbfun);
|
||||
return cbfun;
|
||||
@ -498,6 +514,8 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle,
|
||||
GLFWmousebuttonfun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.mouseButton, cbfun);
|
||||
return cbfun;
|
||||
@ -507,6 +525,8 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle,
|
||||
GLFWcursorposfun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.cursorPos, cbfun);
|
||||
return cbfun;
|
||||
@ -516,6 +536,8 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle,
|
||||
GLFWcursorenterfun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.cursorEnter, cbfun);
|
||||
return cbfun;
|
||||
@ -525,6 +547,8 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle,
|
||||
GLFWscrollfun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.scroll, cbfun);
|
||||
return cbfun;
|
||||
@ -533,6 +557,8 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle,
|
||||
GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun);
|
||||
return cbfun;
|
||||
@ -553,6 +579,7 @@ GLFWAPI int glfwJoystickPresent(int joy)
|
||||
|
||||
GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count)
|
||||
{
|
||||
assert(count);
|
||||
*count = 0;
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
@ -568,6 +595,7 @@ GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count)
|
||||
|
||||
GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count)
|
||||
{
|
||||
assert(count);
|
||||
*count = 0;
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
@ -597,6 +625,10 @@ GLFWAPI const char* glfwGetJoystickName(int joy)
|
||||
GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
assert(string);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
_glfwPlatformSetClipboardString(window, string);
|
||||
}
|
||||
@ -604,6 +636,8 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
|
||||
GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
return _glfwPlatformGetClipboardString(window);
|
||||
}
|
||||
|
127
src/internal.h
127
src/internal.h
@ -47,6 +47,26 @@
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#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_NONE 0
|
||||
#define GL_COLOR_BUFFER_BIT 0x00004000
|
||||
@ -76,16 +96,66 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGPROC)(GLenum);
|
||||
typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*);
|
||||
typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
|
||||
|
||||
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 VK_NULL_HANDLE 0
|
||||
|
||||
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)
|
||||
#include "cocoa_platform.h"
|
||||
@ -366,6 +436,21 @@ struct _GLFWlibrary
|
||||
_GLFWmonitor** monitors;
|
||||
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 {
|
||||
GLFWmonitorfun monitor;
|
||||
} callbacks;
|
||||
@ -689,6 +774,18 @@ void _glfwPlatformDestroyCursor(_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
|
||||
@ -923,4 +1020,16 @@ void _glfwFreeMonitors(_GLFWmonitor** monitors, int count);
|
||||
*/
|
||||
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_
|
||||
|
@ -29,9 +29,24 @@
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include <pthread.h>
|
||||
#include <dlfcn.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_time.h"
|
||||
#include "linux_joystick.h"
|
||||
@ -43,6 +58,10 @@
|
||||
#error "The Mir backend depends on EGL platform support"
|
||||
#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_DISPLAY ((EGLNativeDisplayType) _glfw.mir.display)
|
||||
|
||||
|
@ -706,6 +706,76 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
||||
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 //////
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
@ -293,6 +294,7 @@ void _glfwSplitBPP(int bpp, int* red, int* green, int* blue)
|
||||
|
||||
GLFWAPI GLFWmonitor** glfwGetMonitors(int* count)
|
||||
{
|
||||
assert(count);
|
||||
*count = 0;
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
@ -314,6 +316,7 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void)
|
||||
GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos)
|
||||
{
|
||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||
assert(monitor);
|
||||
|
||||
if (xpos)
|
||||
*xpos = 0;
|
||||
@ -328,6 +331,7 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos)
|
||||
GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM)
|
||||
{
|
||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||
assert(monitor);
|
||||
|
||||
if (widthMM)
|
||||
*widthMM = 0;
|
||||
@ -345,6 +349,8 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int*
|
||||
GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle)
|
||||
{
|
||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||
assert(monitor);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
return monitor->name;
|
||||
}
|
||||
@ -359,7 +365,9 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun)
|
||||
GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count)
|
||||
{
|
||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||
assert(monitor);
|
||||
|
||||
assert(count);
|
||||
*count = 0;
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
@ -374,6 +382,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count)
|
||||
GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle)
|
||||
{
|
||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||
assert(monitor);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
@ -422,6 +431,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
|
||||
GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
|
||||
{
|
||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||
assert(monitor);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
@ -434,6 +444,9 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
|
||||
GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
|
||||
{
|
||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||
assert(monitor);
|
||||
|
||||
assert(ramp);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
|
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);
|
||||
}
|
||||
|
@ -102,8 +102,8 @@ static GLFWbool loadLibraries(void)
|
||||
_glfw.win32.shcore.instance = LoadLibraryA("shcore.dll");
|
||||
if (_glfw.win32.shcore.instance)
|
||||
{
|
||||
_glfw.win32.shcore.SetProcessDPIAwareness = (SETPROCESSDPIAWARENESS_T)
|
||||
GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDPIAwareness");
|
||||
_glfw.win32.shcore.SetProcessDpiAwareness = (SETPROCESSDPIAWARENESS_T)
|
||||
GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDpiAwareness");
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
@ -357,8 +357,8 @@ int _glfwPlatformInit(void)
|
||||
|
||||
createKeyTables();
|
||||
|
||||
if (_glfw_SetProcessDPIAwareness)
|
||||
_glfw_SetProcessDPIAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||
if (_glfw_SetProcessDpiAwareness)
|
||||
_glfw_SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||
else if (_glfw_SetProcessDPIAware)
|
||||
_glfw_SetProcessDPIAware();
|
||||
|
||||
@ -387,6 +387,9 @@ int _glfwPlatformInit(void)
|
||||
|
||||
void _glfwPlatformTerminate(void)
|
||||
{
|
||||
if (_glfw.win32.helperWindow)
|
||||
DestroyWindow(_glfw.win32.helperWindow);
|
||||
|
||||
_glfwUnregisterWindowClassWin32();
|
||||
|
||||
// Restore previous foreground lock timeout system setting
|
||||
@ -405,9 +408,6 @@ void _glfwPlatformTerminate(void)
|
||||
_glfwTerminateJoysticksWin32();
|
||||
_glfwTerminateThreadLocalStorageWin32();
|
||||
|
||||
if (_glfw.win32.helperWindow)
|
||||
DestroyWindow(_glfw.win32.helperWindow);
|
||||
|
||||
freeLibraries();
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,21 @@ typedef HRESULT (WINAPI * DWMFLUSH_T)(VOID);
|
||||
|
||||
// shcore.dll function pointer typedefs
|
||||
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"
|
||||
|
||||
@ -154,6 +168,10 @@ typedef HRESULT (WINAPI * SETPROCESSDPIAWARENESS_T)(PROCESS_DPI_AWARENESS);
|
||||
|
||||
#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_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32
|
||||
#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeWin32 win32_time
|
||||
@ -218,7 +236,7 @@ typedef struct _GLFWlibraryWin32
|
||||
// shcore.dll
|
||||
struct {
|
||||
HINSTANCE instance;
|
||||
SETPROCESSDPIAWARENESS_T SetProcessDPIAwareness;
|
||||
SETPROCESSDPIAWARENESS_T SetProcessDpiAwareness;
|
||||
} shcore;
|
||||
|
||||
} _GLFWlibraryWin32;
|
||||
|
@ -1403,6 +1403,74 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
||||
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 //////
|
||||
|
112
src/window.c
112
src/window.c
@ -28,6 +28,7 @@
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -124,6 +125,8 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
||||
_GLFWwindow* window;
|
||||
_GLFWwindow* previous;
|
||||
|
||||
assert(title);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
@ -274,107 +277,107 @@ void glfwDefaultWindowHints(void)
|
||||
_glfw.hints.refreshRate = GLFW_DONT_CARE;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwWindowHint(int target, int hint)
|
||||
GLFWAPI void glfwWindowHint(int hint, int value)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
switch (target)
|
||||
switch (hint)
|
||||
{
|
||||
case GLFW_RED_BITS:
|
||||
_glfw.hints.framebuffer.redBits = hint;
|
||||
_glfw.hints.framebuffer.redBits = value;
|
||||
break;
|
||||
case GLFW_GREEN_BITS:
|
||||
_glfw.hints.framebuffer.greenBits = hint;
|
||||
_glfw.hints.framebuffer.greenBits = value;
|
||||
break;
|
||||
case GLFW_BLUE_BITS:
|
||||
_glfw.hints.framebuffer.blueBits = hint;
|
||||
_glfw.hints.framebuffer.blueBits = value;
|
||||
break;
|
||||
case GLFW_ALPHA_BITS:
|
||||
_glfw.hints.framebuffer.alphaBits = hint;
|
||||
_glfw.hints.framebuffer.alphaBits = value;
|
||||
break;
|
||||
case GLFW_DEPTH_BITS:
|
||||
_glfw.hints.framebuffer.depthBits = hint;
|
||||
_glfw.hints.framebuffer.depthBits = value;
|
||||
break;
|
||||
case GLFW_STENCIL_BITS:
|
||||
_glfw.hints.framebuffer.stencilBits = hint;
|
||||
_glfw.hints.framebuffer.stencilBits = value;
|
||||
break;
|
||||
case GLFW_ACCUM_RED_BITS:
|
||||
_glfw.hints.framebuffer.accumRedBits = hint;
|
||||
_glfw.hints.framebuffer.accumRedBits = value;
|
||||
break;
|
||||
case GLFW_ACCUM_GREEN_BITS:
|
||||
_glfw.hints.framebuffer.accumGreenBits = hint;
|
||||
_glfw.hints.framebuffer.accumGreenBits = value;
|
||||
break;
|
||||
case GLFW_ACCUM_BLUE_BITS:
|
||||
_glfw.hints.framebuffer.accumBlueBits = hint;
|
||||
_glfw.hints.framebuffer.accumBlueBits = value;
|
||||
break;
|
||||
case GLFW_ACCUM_ALPHA_BITS:
|
||||
_glfw.hints.framebuffer.accumAlphaBits = hint;
|
||||
_glfw.hints.framebuffer.accumAlphaBits = value;
|
||||
break;
|
||||
case GLFW_AUX_BUFFERS:
|
||||
_glfw.hints.framebuffer.auxBuffers = hint;
|
||||
_glfw.hints.framebuffer.auxBuffers = value;
|
||||
break;
|
||||
case GLFW_STEREO:
|
||||
_glfw.hints.framebuffer.stereo = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_DOUBLEBUFFER:
|
||||
_glfw.hints.framebuffer.doublebuffer = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_TRANSPARENT:
|
||||
_glfw.hints.framebuffer.transparent = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_SAMPLES:
|
||||
_glfw.hints.framebuffer.samples = hint;
|
||||
_glfw.hints.framebuffer.samples = value;
|
||||
break;
|
||||
case GLFW_SRGB_CAPABLE:
|
||||
_glfw.hints.framebuffer.sRGB = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_RESIZABLE:
|
||||
_glfw.hints.window.resizable = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_DECORATED:
|
||||
_glfw.hints.window.decorated = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_FOCUSED:
|
||||
_glfw.hints.window.focused = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_AUTO_ICONIFY:
|
||||
_glfw.hints.window.autoIconify = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_FLOATING:
|
||||
_glfw.hints.window.floating = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_VISIBLE:
|
||||
_glfw.hints.window.visible = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_CLIENT_API:
|
||||
_glfw.hints.context.api = hint;
|
||||
_glfw.hints.context.api = value;
|
||||
break;
|
||||
case GLFW_CONTEXT_VERSION_MAJOR:
|
||||
_glfw.hints.context.major = hint;
|
||||
_glfw.hints.context.major = value;
|
||||
break;
|
||||
case GLFW_CONTEXT_VERSION_MINOR:
|
||||
_glfw.hints.context.minor = hint;
|
||||
_glfw.hints.context.minor = value;
|
||||
break;
|
||||
case GLFW_CONTEXT_ROBUSTNESS:
|
||||
_glfw.hints.context.robustness = hint;
|
||||
_glfw.hints.context.robustness = value;
|
||||
break;
|
||||
case GLFW_OPENGL_FORWARD_COMPAT:
|
||||
_glfw.hints.context.forward = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_OPENGL_DEBUG_CONTEXT:
|
||||
_glfw.hints.context.debug = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_CONTEXT_NO_ERROR:
|
||||
_glfw.hints.context.noerror = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_OPENGL_PROFILE:
|
||||
_glfw.hints.context.profile = hint;
|
||||
_glfw.hints.context.profile = value;
|
||||
break;
|
||||
case GLFW_CONTEXT_RELEASE_BEHAVIOR:
|
||||
_glfw.hints.context.release = hint;
|
||||
_glfw.hints.context.release = value;
|
||||
break;
|
||||
case GLFW_REFRESH_RATE:
|
||||
_glfw.hints.refreshRate = hint;
|
||||
_glfw.hints.refreshRate = value;
|
||||
break;
|
||||
default:
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint");
|
||||
@ -422,6 +425,8 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
|
||||
GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(0);
|
||||
return window->closed;
|
||||
}
|
||||
@ -429,6 +434,8 @@ GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle)
|
||||
GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
window->closed = value;
|
||||
}
|
||||
@ -436,6 +443,10 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value)
|
||||
GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
assert(title);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
_glfwPlatformSetWindowTitle(window, title);
|
||||
}
|
||||
@ -443,6 +454,7 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title)
|
||||
GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
if (xpos)
|
||||
*xpos = 0;
|
||||
@ -456,6 +468,7 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos)
|
||||
GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
@ -472,6 +485,7 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos)
|
||||
GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
if (width)
|
||||
*width = 0;
|
||||
@ -485,6 +499,7 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height)
|
||||
GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
@ -502,6 +517,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle,
|
||||
int maxwidth, int maxheight)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
@ -516,6 +532,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle,
|
||||
GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
@ -534,6 +551,7 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)
|
||||
GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
if (width)
|
||||
*width = 0;
|
||||
@ -549,6 +567,7 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle,
|
||||
int* right, int* bottom)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
if (left)
|
||||
*left = 0;
|
||||
@ -566,6 +585,8 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle,
|
||||
GLFWAPI void glfwIconifyWindow(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
_glfwPlatformIconifyWindow(window);
|
||||
}
|
||||
@ -573,6 +594,8 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* handle)
|
||||
GLFWAPI void glfwRestoreWindow(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
_glfwPlatformRestoreWindow(window);
|
||||
}
|
||||
@ -580,6 +603,7 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow* handle)
|
||||
GLFWAPI void glfwShowWindow(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
@ -592,6 +616,7 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle)
|
||||
GLFWAPI void glfwHideWindow(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
@ -604,6 +629,7 @@ GLFWAPI void glfwHideWindow(GLFWwindow* handle)
|
||||
GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(0);
|
||||
|
||||
@ -650,6 +676,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
|
||||
GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
return (GLFWmonitor*) window->monitor;
|
||||
}
|
||||
@ -657,6 +685,8 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle)
|
||||
GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
window->userPointer = pointer;
|
||||
}
|
||||
@ -664,6 +694,8 @@ GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer)
|
||||
GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
return window->userPointer;
|
||||
}
|
||||
@ -672,6 +704,8 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle,
|
||||
GLFWwindowposfun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.pos, cbfun);
|
||||
return cbfun;
|
||||
@ -681,6 +715,8 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle,
|
||||
GLFWwindowsizefun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.size, cbfun);
|
||||
return cbfun;
|
||||
@ -690,6 +726,8 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle,
|
||||
GLFWwindowclosefun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.close, cbfun);
|
||||
return cbfun;
|
||||
@ -699,6 +737,8 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle,
|
||||
GLFWwindowrefreshfun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.refresh, cbfun);
|
||||
return cbfun;
|
||||
@ -708,6 +748,8 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle,
|
||||
GLFWwindowfocusfun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.focus, cbfun);
|
||||
return cbfun;
|
||||
@ -717,6 +759,8 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle,
|
||||
GLFWwindowiconifyfun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.iconify, cbfun);
|
||||
return cbfun;
|
||||
@ -726,6 +770,8 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle
|
||||
GLFWframebuffersizefun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.fbsize, cbfun);
|
||||
return cbfun;
|
||||
|
@ -36,6 +36,11 @@
|
||||
#include <wayland-cursor.h>
|
||||
|
||||
|
||||
static inline int min(int n1, int n2)
|
||||
{
|
||||
return n1 < n2 ? n1 : n2;
|
||||
}
|
||||
|
||||
static void pointerHandleEnter(void* data,
|
||||
struct wl_pointer* pointer,
|
||||
uint32_t serial,
|
||||
@ -380,8 +385,10 @@ static void registryHandleGlobal(void* data,
|
||||
{
|
||||
if (strcmp(interface, "wl_compositor") == 0)
|
||||
{
|
||||
_glfw.wl.wl_compositor_version = min(3, version);
|
||||
_glfw.wl.compositor =
|
||||
wl_registry_bind(registry, name, &wl_compositor_interface, 1);
|
||||
wl_registry_bind(registry, name, &wl_compositor_interface,
|
||||
_glfw.wl.wl_compositor_version);
|
||||
}
|
||||
else if (strcmp(interface, "wl_shm") == 0)
|
||||
{
|
||||
|
@ -97,6 +97,9 @@ static void scale(void* data,
|
||||
struct wl_output* output,
|
||||
int32_t factor)
|
||||
{
|
||||
struct _GLFWmonitor *monitor = data;
|
||||
|
||||
monitor->wl.scale = factor;
|
||||
}
|
||||
|
||||
static const struct wl_output_listener output_listener = {
|
||||
@ -142,6 +145,8 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
|
||||
monitor->wl.modes = calloc(4, sizeof(_GLFWvidmodeWayland));
|
||||
monitor->wl.modesSize = 4;
|
||||
|
||||
monitor->wl.scale = 1;
|
||||
|
||||
monitor->wl.output = output;
|
||||
wl_output_add_listener(output, &output_listener, monitor);
|
||||
|
||||
|
@ -29,6 +29,21 @@
|
||||
|
||||
#include <wayland-client.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_time.h"
|
||||
@ -41,6 +56,10 @@
|
||||
#error "The Wayland backend depends on EGL platform support"
|
||||
#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_DISPLAY ((EGLNativeDisplayType) _glfw.wl.display)
|
||||
|
||||
@ -65,8 +84,17 @@ typedef struct _GLFWwindowWayland
|
||||
struct wl_egl_window* native;
|
||||
struct wl_shell_surface* shell_surface;
|
||||
struct wl_callback* callback;
|
||||
|
||||
_GLFWcursor* currentCursor;
|
||||
double cursorPosX, cursorPosY;
|
||||
|
||||
// We need to track the monitors the window spans on to calculate the
|
||||
// optimal scaling factor.
|
||||
int scale;
|
||||
_GLFWmonitor** monitors;
|
||||
int monitorsCount;
|
||||
int monitorsSize;
|
||||
|
||||
} _GLFWwindowWayland;
|
||||
|
||||
|
||||
@ -83,6 +111,8 @@ typedef struct _GLFWlibraryWayland
|
||||
struct wl_pointer* pointer;
|
||||
struct wl_keyboard* keyboard;
|
||||
|
||||
int wl_compositor_version;
|
||||
|
||||
struct wl_cursor_theme* cursorTheme;
|
||||
struct wl_surface* cursorSurface;
|
||||
uint32_t pointerSerial;
|
||||
@ -123,7 +153,7 @@ typedef struct _GLFWmonitorWayland
|
||||
|
||||
int x;
|
||||
int y;
|
||||
|
||||
int scale;
|
||||
} _GLFWmonitorWayland;
|
||||
|
||||
|
||||
|
166
src/wl_window.c
166
src/wl_window.c
@ -72,6 +72,84 @@ static const struct wl_shell_surface_listener shellSurfaceListener = {
|
||||
handlePopupDone
|
||||
};
|
||||
|
||||
static void checkScaleChange(_GLFWwindow* window)
|
||||
{
|
||||
int scaledWidth, scaledHeight;
|
||||
int scale = 1;
|
||||
int i;
|
||||
int monitorScale;
|
||||
|
||||
// Check if we will be able to set the buffer scale or not.
|
||||
if (_glfw.wl.wl_compositor_version <
|
||||
WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
|
||||
return;
|
||||
|
||||
// Get the scale factor from the highest scale monitor.
|
||||
for (i = 0; i < window->wl.monitorsCount; ++i)
|
||||
{
|
||||
monitorScale = window->wl.monitors[i]->wl.scale;
|
||||
if (scale < monitorScale)
|
||||
scale = monitorScale;
|
||||
}
|
||||
|
||||
// Only change the framebuffer size if the scale changed.
|
||||
if (scale != window->wl.scale)
|
||||
{
|
||||
window->wl.scale = scale;
|
||||
scaledWidth = window->wl.width * scale;
|
||||
scaledHeight = window->wl.height * scale;
|
||||
wl_surface_set_buffer_scale(window->wl.surface, scale);
|
||||
wl_egl_window_resize(window->wl.native, scaledWidth, scaledHeight, 0, 0);
|
||||
_glfwInputFramebufferSize(window, scaledWidth, scaledHeight);
|
||||
}
|
||||
}
|
||||
|
||||
static void handleEnter(void *data,
|
||||
struct wl_surface *surface,
|
||||
struct wl_output *output)
|
||||
{
|
||||
_GLFWwindow* window = data;
|
||||
_GLFWmonitor* monitor = wl_output_get_user_data(output);
|
||||
|
||||
if (window->wl.monitorsCount + 1 > window->wl.monitorsSize)
|
||||
{
|
||||
++window->wl.monitorsSize;
|
||||
window->wl.monitors =
|
||||
realloc(window->wl.monitors,
|
||||
window->wl.monitorsSize * sizeof(_GLFWmonitor*));
|
||||
}
|
||||
|
||||
window->wl.monitors[window->wl.monitorsCount++] = monitor;
|
||||
|
||||
checkScaleChange(window);
|
||||
}
|
||||
|
||||
static void handleLeave(void *data,
|
||||
struct wl_surface *surface,
|
||||
struct wl_output *output)
|
||||
{
|
||||
_GLFWwindow* window = data;
|
||||
_GLFWmonitor* monitor = wl_output_get_user_data(output);
|
||||
GLFWbool found;
|
||||
int i;
|
||||
|
||||
for (i = 0, found = GLFW_FALSE; i < window->wl.monitorsCount - 1; ++i)
|
||||
{
|
||||
if (monitor == window->wl.monitors[i])
|
||||
found = GLFW_TRUE;
|
||||
if (found)
|
||||
window->wl.monitors[i] = window->wl.monitors[i + 1];
|
||||
}
|
||||
window->wl.monitors[--window->wl.monitorsCount] = NULL;
|
||||
|
||||
checkScaleChange(window);
|
||||
}
|
||||
|
||||
static const struct wl_surface_listener surfaceListener = {
|
||||
handleEnter,
|
||||
handleLeave
|
||||
};
|
||||
|
||||
static GLFWbool createSurface(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig)
|
||||
{
|
||||
@ -79,6 +157,10 @@ static GLFWbool createSurface(_GLFWwindow* window,
|
||||
if (!window->wl.surface)
|
||||
return GLFW_FALSE;
|
||||
|
||||
wl_surface_add_listener(window->wl.surface,
|
||||
&surfaceListener,
|
||||
window);
|
||||
|
||||
wl_surface_set_user_data(window->wl.surface, window);
|
||||
|
||||
window->wl.native = wl_egl_window_create(window->wl.surface,
|
||||
@ -98,6 +180,7 @@ static GLFWbool createSurface(_GLFWwindow* window,
|
||||
|
||||
window->wl.width = wndconfig->width;
|
||||
window->wl.height = wndconfig->height;
|
||||
window->wl.scale = 1;
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
@ -262,6 +345,10 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
|
||||
window->wl.currentCursor = NULL;
|
||||
|
||||
window->wl.monitors = calloc(1, sizeof(_GLFWmonitor*));
|
||||
window->wl.monitorsCount = 0;
|
||||
window->wl.monitorsSize = 1;
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
@ -288,6 +375,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
|
||||
if (window->wl.surface)
|
||||
wl_surface_destroy(window->wl.surface);
|
||||
|
||||
free(window->wl.monitors);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
||||
@ -322,9 +411,12 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
|
||||
|
||||
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
||||
{
|
||||
wl_egl_window_resize(window->wl.native, width, height, 0, 0);
|
||||
int scaledWidth = width * window->wl.scale;
|
||||
int scaledHeight = height * window->wl.scale;
|
||||
window->wl.width = width;
|
||||
window->wl.height = height;
|
||||
wl_egl_window_resize(window->wl.native, scaledWidth, scaledHeight, 0, 0);
|
||||
_glfwInputFramebufferSize(window, scaledWidth, scaledHeight);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
||||
@ -344,6 +436,8 @@ void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom
|
||||
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
|
||||
{
|
||||
_glfwPlatformGetWindowSize(window, width, height);
|
||||
*width *= window->wl.scale;
|
||||
*height *= window->wl.scale;
|
||||
}
|
||||
|
||||
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
||||
@ -605,6 +699,76 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
||||
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 //////
|
||||
|
@ -310,7 +310,7 @@ static void createKeyTables(void)
|
||||
}
|
||||
|
||||
XkbFreeNames(desc, XkbKeyNamesMask, True);
|
||||
XkbFreeClientMap(desc, 0, True);
|
||||
XkbFreeKeyboard(desc, 0, True);
|
||||
}
|
||||
|
||||
for (scancode = 0; scancode < 256; scancode++)
|
||||
@ -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
|
||||
// FIXME: We should listen to XkbMapNotify events to track changes to
|
||||
// the keyboard mapping.
|
||||
@ -789,6 +796,12 @@ int _glfwPlatformInit(void)
|
||||
|
||||
void _glfwPlatformTerminate(void)
|
||||
{
|
||||
if (_glfw.x11.x11xcb.handle)
|
||||
{
|
||||
dlclose(_glfw.x11.x11xcb.handle);
|
||||
_glfw.x11.x11xcb.handle = NULL;
|
||||
}
|
||||
|
||||
if (_glfw.x11.cursor)
|
||||
{
|
||||
XFreeCursor(_glfw.x11.display, _glfw.x11.cursor);
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/keysym.h>
|
||||
@ -56,6 +57,37 @@
|
||||
#include <X11/extensions/xf86vmode.h>
|
||||
#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_time.h"
|
||||
#include "linux_joystick.h"
|
||||
@ -71,6 +103,10 @@
|
||||
#error "No supported context creation API selected"
|
||||
#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_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11
|
||||
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11
|
||||
@ -207,6 +243,11 @@ typedef struct _GLFWlibraryX11
|
||||
int minor;
|
||||
} xinerama;
|
||||
|
||||
struct {
|
||||
void* handle;
|
||||
XGETXCBCONNECTION_T XGetXCBConnection;
|
||||
} x11xcb;
|
||||
|
||||
#if defined(_GLFW_HAS_XINPUT)
|
||||
struct {
|
||||
GLFWbool available;
|
||||
|
168
src/x11_window.c
168
src/x11_window.c
@ -1470,13 +1470,21 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
Visual* visual;
|
||||
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 (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth))
|
||||
return GLFW_FALSE;
|
||||
if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth))
|
||||
return GLFW_FALSE;
|
||||
#elif defined(_GLFW_EGL)
|
||||
if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth))
|
||||
return GLFW_FALSE;
|
||||
if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth))
|
||||
return GLFW_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!createWindow(window, wndconfig, visual, depth))
|
||||
return GLFW_FALSE;
|
||||
@ -2109,6 +2117,158 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
||||
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 //////
|
||||
|
@ -2,18 +2,14 @@
|
||||
link_libraries(glfw)
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
add_definitions(-DGLFW_DLL)
|
||||
link_libraries("${MATH_LIBRARY}")
|
||||
else()
|
||||
link_libraries(${glfw_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
include_directories("${GLFW_SOURCE_DIR}/include"
|
||||
"${GLFW_SOURCE_DIR}/deps")
|
||||
include_directories("${GLFW_SOURCE_DIR}/deps")
|
||||
|
||||
set(GLAD "${GLFW_SOURCE_DIR}/deps/glad/glad.h"
|
||||
"${GLFW_SOURCE_DIR}/deps/glad.c")
|
||||
@ -48,6 +44,13 @@ set(WINDOWS_BINARIES empty sharing tearing threads transparent_threads title win
|
||||
set(CONSOLE_BINARIES clipboard events msaa gamma glfwinfo
|
||||
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
|
||||
FOLDER "GLFW3/Tests")
|
||||
|
||||
|
290
tests/glfwinfo.c
290
tests/glfwinfo.c
@ -24,6 +24,7 @@
|
||||
//========================================================================
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <stdio.h>
|
||||
@ -61,7 +62,8 @@ static void usage(void)
|
||||
printf(" -d, --debug request a debug context\n");
|
||||
printf(" -f, --forward require a forward-compatible context\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 "
|
||||
"client API version\n");
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (api == GLFW_OPENGL_API)
|
||||
@ -146,44 +164,158 @@ static const char* get_strategy_name_glfw(int strategy)
|
||||
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;
|
||||
GLint count;
|
||||
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)
|
||||
{
|
||||
PFNGLGETSTRINGIPROC glGetStringi =
|
||||
(PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi");
|
||||
if (!glGetStringi)
|
||||
{
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
puts((const char*) glGetStringi(GL_EXTENSIONS, i));
|
||||
printf(" %s\n", (const char*) glGetStringi(GL_EXTENSIONS, i));
|
||||
}
|
||||
else
|
||||
{
|
||||
extensions = glGetString(GL_EXTENSIONS);
|
||||
while (*extensions != '\0')
|
||||
{
|
||||
if (*extensions == ' ')
|
||||
putchar('\n');
|
||||
else
|
||||
putchar(*extensions);
|
||||
putchar(' ');
|
||||
|
||||
extensions++;
|
||||
while (*extensions != '\0' && *extensions != ' ')
|
||||
{
|
||||
putchar(*extensions);
|
||||
extensions++;
|
||||
}
|
||||
|
||||
while (*extensions == ' ')
|
||||
extensions++;
|
||||
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
putchar('\n');
|
||||
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)
|
||||
@ -220,10 +352,10 @@ int main(int argc, char** argv)
|
||||
{
|
||||
int ch, api, major, minor, revision, profile;
|
||||
GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits;
|
||||
int list = GLFW_FALSE;
|
||||
int list_extensions = GLFW_FALSE, list_layers = GLFW_FALSE;
|
||||
GLFWwindow* window;
|
||||
|
||||
enum { API, BEHAVIOR, DEBUG, FORWARD, HELP, EXTENSIONS,
|
||||
enum { API, BEHAVIOR, DEBUG, FORWARD, HELP, EXTENSIONS, LAYERS,
|
||||
MAJOR, MINOR, PROFILE, ROBUSTNESS, VERSION,
|
||||
REDBITS, GREENBITS, BLUEBITS, ALPHABITS, DEPTHBITS, STENCILBITS,
|
||||
ACCUMREDBITS, ACCUMGREENBITS, ACCUMBLUEBITS, ACCUMALPHABITS,
|
||||
@ -236,6 +368,7 @@ int main(int argc, char** argv)
|
||||
{ "forward", 0, NULL, FORWARD },
|
||||
{ "help", 0, NULL, HELP },
|
||||
{ "list-extensions", 0, NULL, EXTENSIONS },
|
||||
{ "list-layers", 0, NULL, LAYERS },
|
||||
{ "major", 1, NULL, MAJOR },
|
||||
{ "minor", 1, NULL, MINOR },
|
||||
{ "profile", 1, NULL, PROFILE },
|
||||
@ -318,7 +451,10 @@ int main(int argc, char** argv)
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'l':
|
||||
case EXTENSIONS:
|
||||
list = GLFW_TRUE;
|
||||
list_extensions = GLFW_TRUE;
|
||||
break;
|
||||
case LAYERS:
|
||||
list_layers = GLFW_TRUE;
|
||||
break;
|
||||
case 'm':
|
||||
case MAJOR:
|
||||
@ -568,20 +704,10 @@ int main(int argc, char** argv)
|
||||
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)
|
||||
{
|
||||
PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC
|
||||
glGetFramebufferAttachmentParameteriv =
|
||||
(PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)
|
||||
glfwGetProcAddress("glGetFramebufferAttachmentParameteriv");
|
||||
if (!glGetFramebufferAttachmentParameteriv)
|
||||
{
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
|
||||
GL_BACK_LEFT,
|
||||
GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE,
|
||||
@ -646,9 +772,103 @@ int main(int argc, char** argv)
|
||||
accumredbits, accumgreenbits, accumbluebits, accumalphabits, auxbuffers);
|
||||
}
|
||||
|
||||
// Report client API extensions
|
||||
if (list)
|
||||
list_extensions(api, major, minor);
|
||||
if (list_extensions)
|
||||
list_context_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();
|
||||
exit(EXIT_SUCCESS);
|
||||
|
2246
tests/vulkan.c
Normal file
2246
tests/vulkan.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user