Merge branch 'master' into fast_window_position_updates

This commit is contained in:
Cem Karan 2016-02-16 15:29:54 -05:00
commit fb11af9c6a
51 changed files with 9050 additions and 796 deletions

22
.appveyor.yml Normal file
View 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
View File

@ -71,4 +71,5 @@ tests/tearing
tests/threads tests/threads
tests/title tests/title
tests/version tests/version
tests/vulkan
tests/windows tests/windows

30
.travis.yml Normal file
View 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

View 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)

View File

@ -50,6 +50,13 @@ if (BUILD_SHARED_LIBS)
set(_GLFW_BUILD_DLL 1) set(_GLFW_BUILD_DLL 1)
endif() 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) if (GLFW_USE_WAYLAND)
set(GLFW_USE_EGL ON) set(GLFW_USE_EGL ON)
elseif (GLFW_USE_MIR) elseif (GLFW_USE_MIR)
@ -59,6 +66,7 @@ endif()
set(CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules") set(CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules")
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
find_package(Vulkan)
if (GLFW_BUILD_DOCS) if (GLFW_BUILD_DOCS)
set(DOXYGEN_SKIP_DOT TRUE) set(DOXYGEN_SKIP_DOT TRUE)
@ -347,7 +355,6 @@ endif()
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# Export GLFW library dependencies # Export GLFW library dependencies
#-------------------------------------------------------------------- #--------------------------------------------------------------------
set(GLFW_LIBRARIES ${glfw_LIBRARIES} CACHE STRING "Dependencies of GLFW")
foreach(arg ${glfw_PKG_DEPS}) foreach(arg ${glfw_PKG_DEPS})
set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} ${arg}") set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} ${arg}")
endforeach() endforeach()
@ -360,32 +367,24 @@ endforeach()
#-------------------------------------------------------------------- #--------------------------------------------------------------------
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
if (UNIX) set(GLFW_CONFIG_PATH "lib${LIB_SUFFIX}/cmake/glfw3")
set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/lib/cmake/glfw3/")
else()
set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/")
endif()
configure_package_config_file("${GLFW_SOURCE_DIR}/src/glfw3Config.cmake.in" configure_package_config_file(src/glfw3Config.cmake.in
"${GLFW_BINARY_DIR}/src/glfw3Config.cmake" src/glfw3Config.cmake
INSTALL_DESTINATION "${GLFW_CONFIG_PATH}" INSTALL_DESTINATION "${GLFW_CONFIG_PATH}"
PATH_VARS CMAKE_INSTALL_PREFIX
NO_CHECK_REQUIRED_COMPONENTS_MACRO) 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} VERSION ${GLFW_VERSION_FULL}
COMPATIBILITY SameMajorVersion) COMPATIBILITY SameMajorVersion)
if (GLFW_BUILD_DOCS) if (GLFW_BUILD_DOCS)
configure_file("${GLFW_SOURCE_DIR}/docs/Doxyfile.in" configure_file(docs/Doxyfile.in docs/Doxyfile @ONLY)
"${GLFW_BINARY_DIR}/docs/Doxyfile" @ONLY)
endif() endif()
configure_file("${GLFW_SOURCE_DIR}/src/glfw_config.h.in" configure_file(src/glfw_config.h.in src/glfw_config.h @ONLY)
"${GLFW_BINARY_DIR}/src/glfw_config.h" @ONLY)
configure_file("${GLFW_SOURCE_DIR}/src/glfw3.pc.in" configure_file(src/glfw3.pc.in src/glfw3.pc @ONLY)
"${GLFW_BINARY_DIR}/src/glfw3.pc" @ONLY)
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# Add subdirectories # Add subdirectories
@ -414,16 +413,18 @@ if (GLFW_INSTALL)
install(FILES "${GLFW_BINARY_DIR}/src/glfw3Config.cmake" install(FILES "${GLFW_BINARY_DIR}/src/glfw3Config.cmake"
"${GLFW_BINARY_DIR}/src/glfw3ConfigVersion.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" 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 # Only generate this target if no higher-level project already has
if (NOT TARGET uninstall) if (NOT TARGET uninstall)
configure_file("${GLFW_SOURCE_DIR}/cmake_uninstall.cmake.in" configure_file(cmake_uninstall.cmake.in
"${GLFW_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) cmake_uninstall.cmake IMMEDIATE @ONLY)
add_custom_target(uninstall add_custom_target(uninstall
"${CMAKE_COMMAND}" -P "${CMAKE_COMMAND}" -P

106
CONTRIBUTING.md Normal file
View 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.

View File

@ -1,10 +1,13 @@
# GLFW # GLFW
[![Build status](https://travis-ci.org/glfw/glfw.svg?branch=master)](https://travis-ci.org/glfw/glfw)
[![Build status](https://ci.appveyor.com/api/projects/status/0kf0ct9831i5l6sp/branch/master?svg=true)](https://ci.appveyor.com/project/elmindreda/glfw)
## Introduction ## Introduction
GLFW is a free, Open Source, multi-platform library for OpenGL and OpenGL ES GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and
application development. It provides a simple, platform-independent API for Vulkan application development. It provides a simple, platform-independent API
creating windows and contexts, reading input, handling events, etc. for creating windows, contexts and surfaces, reading input, handling events, etc.
Version 3.2 is _not yet described_. Version 3.2 is _not yet described_.
@ -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 GLFW itself needs only the headers and libraries for your window system. It
does not need the headers for any context creation API (WGL, GLX, EGL, NSGL) or does not need the headers for any context creation API (WGL, GLX, EGL, NSGL) or
client API (OpenGL, OpenGL ES) to enable support for them. rendering API (OpenGL, OpenGL ES, Vulkan) to enable support for them.
GLFW bundles a number of dependencies in the `deps/` directory. These are only GLFW bundles a number of dependencies in the `deps/` directory. These are only
used by the tests and examples and are not required to build the library. used by the tests and examples and are not required to build the library.
@ -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 - [linmath.h](https://github.com/datenwolf/linmath.h) for linear algebra in
examples examples
The Vulkan example additionally requires the Vulkan SDK to be installed, or it
will not be included in the build.
## Changelog ## Changelog
- Added `glfwVulkanSupported`, `glfwGetRequiredInstanceExtensions`,
`glfwGetInstanceProcAddress`, `glfwGetPhysicalDevicePresentationSupport` and
`glfwCreateWindowSurface` for platform independent Vulkan support
- Added `glfwSetWindowSizeLimits` and `glfwSetWindowAspectRatio` for setting - Added `glfwSetWindowSizeLimits` and `glfwSetWindowAspectRatio` for setting
absolute and relative window size limits absolute and relative window size limits
- Added `glfwGetKeyName` for querying the layout-specific name of printable - Added `glfwGetKeyName` for querying the layout-specific name of printable
keys keys
- Added `GLFW_NO_API` for creating window without contexts - Added `GLFW_NO_API` for creating window without contexts
- Added `GLFW_CONTEXT_NO_ERROR` context hint for `GL_KHR_no_error` support - Added `GLFW_CONTEXT_NO_ERROR` context hint for `GL_KHR_no_error` support
- Added `GLFW_INCLUDE_VULKAN` for including the Vulkan header
- Added `GLFW_TRUE` and `GLFW_FALSE` as client API independent boolean values - Added `GLFW_TRUE` and `GLFW_FALSE` as client API independent boolean values
- Added `glfwGetGLXWindow` to query the `GLXWindow` of a window - Added `glfwGetGLXWindow` to query the `GLXWindow` of a window
- Added icons to examples on Windows and OS X - Added icons to examples on Windows and OS X
@ -85,8 +95,10 @@ used by the tests and examples and are not required to build the library.
when no windows existed when no windows existed
- [Cocoa] Removed support for OS X 10.6 - [Cocoa] Removed support for OS X 10.6
- [Cocoa] Bugfix: Full screen windows on secondary monitors were mispositioned - [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: Monitor connection and disconnection events were not reported
- [X11] Bugfix: Decoding of UTF-8 text from XIM could continue past the end - [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` - [POSIX] Bugfix: An unrelated TLS key could be deleted by `glfwTerminate`
- [WGL] Changed extension loading to only be performed once - [WGL] Changed extension loading to only be performed once
- [WGL] Removed dependency on external WGL headers - [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` - [GLX] Bugfix: NetBSD does not provide `libGL.so.1`
- [EGL] Added `_GLFW_USE_EGLPLATFORM_H` configuration macro for controlling - [EGL] Added `_GLFW_USE_EGLPLATFORM_H` configuration macro for controlling
whether to use an existing `EGL/eglplatform.h` header 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 - [EGL] Removed dependency on external EGL headers
@ -161,6 +175,7 @@ skills.
- Osman Keskin - Osman Keskin
- Cameron King - Cameron King
- Peter Knut - Peter Knut
- Christoph Kubisch
- Eric Larson - Eric Larson
- Robin Leffmann - Robin Leffmann
- Glenn Lewis - Glenn Lewis
@ -170,6 +185,7 @@ skills.
- Martins Mozeiko - Martins Mozeiko
- Tristam MacDonald - Tristam MacDonald
- Hans Mackowiak - Hans Mackowiak
- Zbigniew Mandziejewicz
- Kyle McDonald - Kyle McDonald
- David Medlock - David Medlock
- Bryce Mehring - Bryce Mehring
@ -217,6 +233,7 @@ skills.
- urraka - urraka
- Jari Vetoniemi - Jari Vetoniemi
- Ricardo Vieira - Ricardo Vieira
- Nicholas Vitovitch
- Simon Voordouw - Simon Voordouw
- Torsten Walluhn - Torsten Walluhn
- Patrick Walton - Patrick Walton

127
deps/vulkan/vk_platform.h vendored Normal file
View 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

File diff suppressed because it is too large Load Diff

View File

@ -195,7 +195,15 @@ TAB_SIZE = 8
# will result in a user-defined paragraph with heading "Side Effects:". # 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. # 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). # 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 # 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/monitor.dox \
@GLFW_SOURCE_DIR@/docs/window.dox \ @GLFW_SOURCE_DIR@/docs/window.dox \
@GLFW_SOURCE_DIR@/docs/input.dox \ @GLFW_SOURCE_DIR@/docs/input.dox \
@GLFW_SOURCE_DIR@/docs/vulkan.dox \
@GLFW_SOURCE_DIR@/docs/rift.dox \ @GLFW_SOURCE_DIR@/docs/rift.dox \
@GLFW_SOURCE_DIR@/docs/compat.dox @GLFW_SOURCE_DIR@/docs/compat.dox
@ -1582,7 +1591,8 @@ PREDEFINED = GLFWAPI= \
GLFW_EXPOSE_NATIVE_GLX \ GLFW_EXPOSE_NATIVE_GLX \
GLFW_EXPOSE_NATIVE_COCOA \ GLFW_EXPOSE_NATIVE_COCOA \
GLFW_EXPOSE_NATIVE_NSGL \ GLFW_EXPOSE_NATIVE_NSGL \
GLFW_EXPOSE_NATIVE_EGL GLFW_EXPOSE_NATIVE_EGL \
VK_VERSION_1_0
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded. # this tag can be used to specify a list of macro names that should be expanded.

View File

@ -80,6 +80,9 @@ header instead of the regular OpenGL header.
`GLFW_INCLUDE_ES31` makes the GLFW header include the OpenGL ES 3.1 `GLES3/gl31.h` `GLFW_INCLUDE_ES31` makes the GLFW header include the OpenGL ES 3.1 `GLES3/gl31.h`
header instead of the regular OpenGL header. header instead of the regular OpenGL header.
`GLFW_INCLUDE_VULKAN` makes the GLFW header include the Vulkan `vulkan/vulkan.h`
header instead of the regular OpenGL header.
`GLFW_INCLUDE_NONE` makes the GLFW header not include any OpenGL or OpenGL ES API `GLFW_INCLUDE_NONE` makes the GLFW header not include any OpenGL or OpenGL ES API
header. This is useful in combination with an extension loading library. header. This is useful in combination with an extension loading library.
@ -148,6 +151,10 @@ uses OpenGL and `glu32` if it uses GLU.
@subsection build_link_cmake_source With CMake and GLFW source @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 With just a few changes to your `CMakeLists.txt` you can have the GLFW source
tree built along with your application. 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) add_subdirectory(path/to/glfw)
@endcode @endcode
To be able to include the GLFW header from your code, you need to tell the Once GLFW has been added to the project, link against it with the `glfw` target.
compiler where to find it. 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} @code{.cmake}
include_directories(path/to/glfw/include) target_link_libraries(myapp glfw)
@endcode @endcode
Once GLFW has been added to the project, the `GLFW_LIBRARIES` cache variable Note that it does not include GLU, as GLFW does not use it. If your application
contains all link-time dependencies of GLFW as it is currently configured. To needs GLU, you can find it by requiring the OpenGL package.
link against GLFW, link against them and the `glfw` target.
@code{.cmake} @code{.cmake}
target_link_libraries(myapp glfw ${GLFW_LIBRARIES}) find_package(OpenGL REQUIRED)
@endcode @endcode
Note that `GLFW_LIBRARIES` does not include GLU, as GLFW does not use it. If If GLU is found, the `OPENGL_GLU_FOUND` variable is true and the
your application needs GLU, you can add it to the list of dependencies with the `OPENGL_INCLUDE_DIR` and `OPENGL_glu_LIBRARY` cache variables can be used.
`OPENGL_glu_LIBRARY` cache variable, which is implicitly created when the GLFW
CMake files look for OpenGL.
@code{.cmake} @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 @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 This section is about using CMake to link GLFW after it has been built and
installed GLFW, the pkg-config file `glfw3.pc` was installed along with it. 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 With just a few changes to your `CMakeLists.txt`, you can locate the module and
install the pkg-config package for your distribution. target files generated when GLFW is installed.
@code{.cmake} @code{.cmake}
find_package(PkgConfig REQUIRED) find_package(glfw3 3.2 REQUIRED)
@endcode @endcode
This creates the CMake commands to find pkg-config packages. Then you need to Once GLFW has been located, link against it with the `glfw` target. This adds
find the GLFW package. 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} @code{.cmake}
pkg_search_module(GLFW REQUIRED glfw3) target_link_libraries(myapp glfw)
@endcode @endcode
This creates the CMake variables you need to use GLFW. To be able to include Note that it does not include GLU, as GLFW does not use it. If your application
the GLFW header, you need to tell your compiler where it is. needs GLU, you can find it by requiring the OpenGL package.
@code{.cmake} @code{.cmake}
include_directories(${GLFW_INCLUDE_DIRS}) find_package(OpenGL REQUIRED)
@endcode @endcode
You also need to link against the correct libraries. If you are using the If GLU is found, the `OPENGL_GLU_FOUND` variable is true and the
shared library version of GLFW, use the `GLFW_LIBRARIES` variable. `OPENGL_INCLUDE_DIR` and `OPENGL_glu_LIBRARY` cache variables can be used.
@code{.cmake} @code{.cmake}
target_link_libraries(simple ${GLFW_LIBRARIES}) target_include_directories(myapp ${OPENGL_INCLUDE_DIR})
@endcode target_link_libraries(myapp ${OPENGL_glu_LIBRARY})
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})
@endcode @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/), 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 and the `glfw3.pc` pkf-config file is generated when the GLFW library is built

View File

@ -186,4 +186,43 @@ setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT` hints to
a non-default value will cause @ref glfwCreateWindow to fail and the a non-default value will cause @ref glfwCreateWindow to fail and the
`GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored. `GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored.
@section compat_vulkan Vulkan loader and API
GLFW uses the standard system-wside Vulkan loader to access the Vulkan API.
This should be installed by graphics drivers and Vulkan SDKs. If this is not
available, @ref glfwVulkanSupported will return `GLFW_FALSE` and all other
Vulkan-related functions will fail with an @ref GLFW_API_UNAVAILABLE error.
@section compat_wsi Vulkan WSI extensions
The Vulkan WSI extensions are used to create Vulkan surfaces for GLFW windows on
all supported platforms.
GLFW uses the `VK_KHR_surface` and `VK_KHR_win32_surface` extensions to create
surfaces on Microsoft Windows. If any of these extensions are not available,
@ref glfwGetRequiredInstanceExtensions will return an empty list and window
surface creation will fail.
GLFW uses the `VK_KHR_surface` and either the `VK_KHR_xlib_surface` or
`VK_KHR_xcb_surface` extensions to create surfaces on X11. If `VK_KHR_surface`
or both `VK_KHR_xlib_surface` and `VK_KHR_xcb_surface` are not available, @ref
glfwGetRequiredInstanceExtensions will return an empty list and window surface
creation will fail.
GLFW uses the `VK_KHR_surface` and `VK_KHR_wayland_surface` extensions to create
surfaces on Wayland. If any of these extensions are not available, @ref
glfwGetRequiredInstanceExtensions will return an empty list and window surface
creation will fail.
GLFW uses the `VK_KHR_surface` and `VK_KHR_mir_surface` extensions to create
surfaces on Mir. If any of these extensions are not available, @ref
glfwGetRequiredInstanceExtensions will return an empty list and window surface
creation will fail.
GLFW does not support any extensions for window surface creation on OS X,
meaning@ref glfwGetRequiredInstanceExtensions will return an empty list and
window surface creation will fail.
*/ */

View File

@ -26,6 +26,11 @@ as the context handle.
To test the creation of various kinds of contexts and see their properties, run To test the creation of various kinds of contexts and see their properties, run
the `glfwinfo` test program. the `glfwinfo` test program.
@note Vulkan does not have a context and the Vulkan instance is created via the
Vulkan API itself. If you will be using Vulkan to render to a window, disable
context creation by setting the [GLFW_CLIENT_API](@ref window_hints_ctx) hint to
`GLFW_NO_API`. For more information, see the @ref vulkan.
@subsection context_hints Context creation hints @subsection context_hints Context creation hints

View File

@ -4,9 +4,9 @@
@section main_intro Introduction @section main_intro Introduction
__GLFW__ is a free, Open Source, multi-platform library for creating windows GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and
with OpenGL or OpenGL ES contexts and receiving many kinds of input. It is easy Vulkan application development. It provides a simple, platform-independent API
to integrate into existing applications and does not lay claim to the main loop. for creating windows, contexts and surfaces, reading input, handling events, etc.
See @ref news_32 for release highlights or the See @ref news_32 for release highlights or the
[version history](http://www.glfw.org/changelog.html) for details. [version history](http://www.glfw.org/changelog.html) for details.
@ -32,6 +32,8 @@ about specific functions.
There is a section on @ref guarantees_limitations for pointer lifetimes, There is a section on @ref guarantees_limitations for pointer lifetimes,
reentrancy, thread safety, event order and backward and forward compatibility. reentrancy, thread safety, event order and backward and forward compatibility.
The @ref vulkan guide fills in the gaps for how to use Vulkan with GLFW.
The @ref rift fills in the gaps for how to use LibOVR with GLFW. The @ref rift fills in the gaps for how to use LibOVR with GLFW.
The [FAQ](http://www.glfw.org/faq.html) answers many common questions about the The [FAQ](http://www.glfw.org/faq.html) answers many common questions about the

View File

@ -61,6 +61,9 @@ used from any thread and which must only be used from the main thread.
`glfwUnlockMutex`, `glfwCreateCond`, `glfwDestroyCond`, `glfwWaitCond`, `glfwUnlockMutex`, `glfwCreateCond`, `glfwDestroyCond`, `glfwWaitCond`,
`glfwSignalCond`, `glfwBroadcastCond` and `glfwGetNumberOfProcessors`. `glfwSignalCond`, `glfwBroadcastCond` and `glfwGetNumberOfProcessors`.
@par Removed types
`GLFWthreadfun`
@subsection moving_image Removal of image and texture loading @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 | | `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 | | `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 @subsection moving_renamed_tokens Renamed tokens
| GLFW 2 | GLFW 3 | Notes | | GLFW 2 | GLFW 3 | Notes |

View File

@ -17,6 +17,15 @@ GLFW now supports querying the localized name of printable keys with @ref
glfwGetKeyName, either by key token or by scancode. glfwGetKeyName, either by key token or by scancode.
@subsection news_32_vulkan Support for Vulkan
GLFW now supports basic integration with Vulkan with @ref glfwVulkanSupported,
@ref glfwGetRequiredInstanceExtensions, @ref glfwGetInstanceProcAddress, @ref
glfwGetPhysicalDevicePresentationSupport and @ref glfwCreateWindowSurface.
Vulkan header inclusion can be selected with
[GLFW_INCLUDE_VULKAN](@ref build_macros).
@section news_31 New features in 3.1 @section news_31 New features in 3.1
These are the release highlights. For a full list of changes see the These are the release highlights. For a full list of changes see the

View File

@ -64,7 +64,9 @@ successful initialization, `GLFW_TRUE` is returned. If an error occurred,
@code @code
if (!glfwInit()) if (!glfwInit())
exit(EXIT_FAILURE); {
// Initialization failed
}
@endcode @endcode
Note that `GLFW_TRUE` and `GLFW_FALSE` are and will always be just one and zero. 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 @subsection quick_create_window Creating a window and context
The window and its OpenGL context are created with a single call, which returns The window and its OpenGL context are created with a single call to @ref
a handle to the created combined window and context object. For example, this glfwCreateWindow, which returns a handle to the created combined window and
creates a 640 by 480 windowed mode window with an OpenGL context: context object
@code @code
GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL); 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) if (!window)
{ {
glfwTerminate(); // Window or OpenGL context creation failed
exit(EXIT_FAILURE); }
@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 @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 along to all window related callbacks, so they can tell which window received
the event. the event.
When a window is no longer needed, destroy it. When a window and context is no longer needed, destroy it.
@code @code
glfwDestroyWindow(window); glfwDestroyWindow(window);

185
docs/vulkan.dox Normal file
View 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.
*/

View File

@ -1,19 +1,17 @@
link_libraries(glfw) link_libraries(glfw)
include_directories(${glfw_INCLUDE_DIRS})
if (BUILD_SHARED_LIBS) if (BUILD_SHARED_LIBS)
add_definitions(-DGLFW_DLL)
link_libraries("${MATH_LIBRARY}") link_libraries("${MATH_LIBRARY}")
else()
link_libraries(${glfw_LIBRARIES})
endif() endif()
if (MSVC) if (MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif() endif()
include_directories("${GLFW_SOURCE_DIR}/include" include_directories("${GLFW_SOURCE_DIR}/deps")
"${GLFW_SOURCE_DIR}/deps")
if (WIN32) if (WIN32)
set(ICON glfw.rc) set(ICON glfw.rc)

File diff suppressed because it is too large Load Diff

View File

@ -127,11 +127,10 @@ extern "C" {
* of the specified monitor, or `NULL` if an [error](@ref error_handling) * of the specified monitor, or `NULL` if an [error](@ref error_handling)
* occurred. * occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.1.
* Added in GLFW 3.1.
* *
* @ingroup native * @ingroup native
*/ */
@ -143,11 +142,10 @@ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.1.
* Added in GLFW 3.1.
* *
* @ingroup native * @ingroup native
*/ */
@ -158,11 +156,10 @@ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
* @return The `HWND` of the specified window, or `NULL` if an * @return The `HWND` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -175,11 +172,10 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
* @return The `HGLRC` of the specified window, or `NULL` if an * @return The `HGLRC` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -192,11 +188,10 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
* @return The `CGDirectDisplayID` of the specified monitor, or * @return The `CGDirectDisplayID` of the specified monitor, or
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred. * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.1.
* Added in GLFW 3.1.
* *
* @ingroup native * @ingroup native
*/ */
@ -207,11 +202,10 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
* @return The `NSWindow` of the specified window, or `nil` if an * @return The `NSWindow` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -224,11 +218,10 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
* @return The `NSOpenGLContext` of the specified window, or `nil` if an * @return The `NSOpenGLContext` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -241,11 +234,10 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
* @return The `Display` used by GLFW, or `NULL` if an * @return The `Display` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -256,11 +248,10 @@ GLFWAPI Display* glfwGetX11Display(void);
* @return The `RRCrtc` of the specified monitor, or `None` if an * @return The `RRCrtc` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.1.
* Added in GLFW 3.1.
* *
* @ingroup native * @ingroup native
*/ */
@ -271,11 +262,10 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
* @return The `RROutput` of the specified monitor, or `None` if an * @return The `RROutput` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.1.
* Added in GLFW 3.1.
* *
* @ingroup native * @ingroup native
*/ */
@ -286,11 +276,10 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
* @return The `Window` of the specified window, or `None` if an * @return The `Window` of the specified window, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -303,11 +292,10 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
* @return The `GLXContext` of the specified window, or `NULL` if an * @return The `GLXContext` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -318,11 +306,10 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
* @return The `GLXWindow` of the specified window, or `None` if an * @return The `GLXWindow` of the specified window, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.2.
* Added in GLFW 3.2.
* *
* @ingroup native * @ingroup native
*/ */
@ -335,11 +322,10 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
* @return The `struct wl_display*` used by GLFW, or `NULL` if an * @return The `struct wl_display*` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.2.
* Added in GLFW 3.2.
* *
* @ingroup native * @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 * @return The `struct wl_output*` of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.2.
* Added in GLFW 3.2.
* *
* @ingroup native * @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 * @return The main `struct wl_surface*` of the specified window, or `NULL` if
* an [error](@ref error_handling) occurred. * an [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.2.
* Added in GLFW 3.2.
* *
* @ingroup native * @ingroup native
*/ */
@ -382,11 +366,10 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
* @return The `MirConnection*` used by GLFW, or `NULL` if an * @return The `MirConnection*` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.2.
* Added in GLFW 3.2.
* *
* @ingroup native * @ingroup native
*/ */
@ -397,11 +380,10 @@ GLFWAPI MirConnection* glfwGetMirDisplay(void);
* @return The Mir output ID of the specified monitor, or zero if an * @return The Mir output ID of the specified monitor, or zero if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.2.
* Added in GLFW 3.2.
* *
* @ingroup native * @ingroup native
*/ */
@ -412,11 +394,10 @@ GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor);
* @return The `MirSurface*` of the specified window, or `NULL` if an * @return The `MirSurface*` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.2.
* Added in GLFW 3.2.
* *
* @ingroup native * @ingroup native
*/ */
@ -429,11 +410,10 @@ GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window);
* @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -444,11 +424,10 @@ GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -459,11 +438,10 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */

View File

@ -3,7 +3,7 @@ set(common_HEADERS internal.h
"${GLFW_BINARY_DIR}/src/glfw_config.h" "${GLFW_BINARY_DIR}/src/glfw_config.h"
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h" "${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h") "${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h")
set(common_SOURCES context.c init.c input.c monitor.c window.c) set(common_SOURCES context.c init.c input.c monitor.c vulkan.c window.c)
if (_GLFW_COCOA) if (_GLFW_COCOA)
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h cocoa_joystick.h set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h cocoa_joystick.h
@ -52,12 +52,16 @@ endif()
add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS}) add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
set_target_properties(glfw PROPERTIES set_target_properties(glfw PROPERTIES
OUTPUT_NAME ${GLFW_LIB_NAME}
VERSION ${GLFW_VERSION} VERSION ${GLFW_VERSION}
SOVERSION ${GLFW_VERSION_MAJOR} SOVERSION ${GLFW_VERSION_MAJOR}
POSITION_INDEPENDENT_CODE ON POSITION_INDEPENDENT_CODE ON
FOLDER "GLFW3") FOLDER "GLFW3")
target_compile_definitions(glfw PRIVATE -D_GLFW_USE_CONFIG_H) 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 target_include_directories(glfw PRIVATE
"${GLFW_SOURCE_DIR}/src" "${GLFW_SOURCE_DIR}/src"
"${GLFW_BINARY_DIR}/src" "${GLFW_BINARY_DIR}/src"
@ -92,26 +96,22 @@ if (BUILD_SHARED_LIBS)
target_compile_options(glfw PRIVATE "-fno-common") target_compile_options(glfw PRIVATE "-fno-common")
set_target_properties(glfw PROPERTIES set_target_properties(glfw PROPERTIES
INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}") INSTALL_NAME_DIR "lib${LIB_SUFFIX}")
elseif (UNIX) elseif (UNIX)
# Hide symbols not explicitly tagged for export from the shared library # Hide symbols not explicitly tagged for export from the shared library
target_compile_options(glfw PRIVATE "-fvisibility=hidden") target_compile_options(glfw PRIVATE "-fvisibility=hidden")
endif() 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() endif()
if (MSVC) if (MSVC)
target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS) target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS)
endif() 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) if (GLFW_INSTALL)
install(TARGETS glfw EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX}) install(TARGETS glfw EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX})
endif() endif()

View File

@ -29,6 +29,7 @@
#include <unistd.h> #include <unistd.h>
#include <ctype.h> #include <ctype.h>
#include <string.h>
#include <mach/mach.h> #include <mach/mach.h>
#include <mach/mach_error.h> #include <mach/mach_error.h>
@ -287,10 +288,15 @@ static void matchCallback(void* context,
CFStringRef name = IOHIDDeviceGetProperty(deviceRef, CFStringRef name = IOHIDDeviceGetProperty(deviceRef,
CFSTR(kIOHIDProductKey)); CFSTR(kIOHIDProductKey));
if (name)
{
CFStringGetCString(name, CFStringGetCString(name,
joystick->name, joystick->name,
sizeof(joystick->name), sizeof(joystick->name),
kCFStringEncodingUTF8); kCFStringEncodingUTF8);
}
else
strncpy(joystick->name, "Unknown", sizeof(joystick->name));
joystick->axisElements = CFArrayCreateMutable(NULL, 0, NULL); joystick->axisElements = CFArrayCreateMutable(NULL, 0, NULL);
joystick->buttonElements = CFArrayCreateMutable(NULL, 0, NULL); joystick->buttonElements = CFArrayCreateMutable(NULL, 0, NULL);

View File

@ -28,6 +28,7 @@
#define _glfw3_cocoa_platform_h_ #define _glfw3_cocoa_platform_h_
#include <stdint.h> #include <stdint.h>
#include <dlfcn.h>
#if defined(__OBJC__) #if defined(__OBJC__)
#import <Carbon/Carbon.h> #import <Carbon/Carbon.h>
@ -47,6 +48,10 @@ typedef void* id;
#error "The Cocoa backend depends on NSGL platform support" #error "The Cocoa backend depends on NSGL platform support"
#endif #endif
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
#define _glfw_dlclose(handle) dlclose(handle)
#define _glfw_dlsym(handle, name) dlsym(handle, name)
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS ns #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS ns
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns
#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeNS ns_time #define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeNS ns_time

View File

@ -1351,6 +1351,27 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
return _glfw.ns.clipboardString; return _glfw.ns.clipboardString;
} }
char** _glfwPlatformGetRequiredInstanceExtensions(int* count)
{
*count = 0;
return NULL;
}
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
unsigned int queuefamily)
{
return GLFW_FALSE;
}
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
_GLFWwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface)
{
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW native API ////// ////// GLFW native API //////

View File

@ -27,6 +27,7 @@
#include "internal.h" #include "internal.h"
#include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
@ -572,6 +573,7 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
GLFWAPI void glfwSwapBuffers(GLFWwindow* handle) GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
@ -601,6 +603,8 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
{ {
_GLFWwindow* window; _GLFWwindow* window;
assert(extension);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
window = _glfwPlatformGetCurrentContext(); window = _glfwPlatformGetCurrentContext();
@ -663,6 +667,8 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname) GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
{ {
assert(procname);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (!_glfwPlatformGetCurrentContext()) if (!_glfwPlatformGetCurrentContext())

View File

@ -584,6 +584,13 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
void _glfwPlatformSwapBuffers(_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); eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);
} }

View File

@ -28,17 +28,6 @@
#ifndef _glfw3_egl_context_h_ #ifndef _glfw3_egl_context_h_
#define _glfw3_egl_context_h_ #define _glfw3_egl_context_h_
#if defined(_GLFW_WIN32)
#define _glfw_dlopen(name) LoadLibraryA(name)
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
#else
#include <dlfcn.h>
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
#define _glfw_dlclose(handle) dlclose(handle)
#define _glfw_dlsym(handle, name) dlsym(handle, name)
#endif
#if defined(_GLFW_USE_EGLPLATFORM_H) #if defined(_GLFW_USE_EGLPLATFORM_H)
#include <EGL/eglplatform.h> #include <EGL/eglplatform.h>
#elif defined(_GLFW_WIN32) #elif defined(_GLFW_WIN32)

View File

@ -1,15 +1 @@
# - Config file for the glfw3 package include("${CMAKE_CURRENT_LIST_DIR}/glfw3Targets.cmake")
# 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})

View File

@ -30,7 +30,6 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <dlfcn.h>
#ifndef GLXBadProfileARB #ifndef GLXBadProfileARB
#define GLXBadProfileARB 13 #define GLXBadProfileARB 13

View File

@ -130,6 +130,8 @@ GLFWAPI int glfwInit(void)
return GLFW_FALSE; return GLFW_FALSE;
} }
_glfwInitVulkan();
_glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount); _glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount);
_glfwInitialized = GLFW_TRUE; _glfwInitialized = GLFW_TRUE;
@ -161,6 +163,8 @@ GLFWAPI void glfwTerminate(void)
_glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp); _glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp);
} }
_glfwTerminateVulkan();
_glfwFreeMonitors(_glfw.monitors, _glfw.monitorCount); _glfwFreeMonitors(_glfw.monitors, _glfw.monitorCount);
_glfw.monitors = NULL; _glfw.monitors = NULL;
_glfw.monitorCount = 0; _glfw.monitorCount = 0;

View File

@ -27,6 +27,7 @@
#include "internal.h" #include "internal.h"
#include <assert.h>
#include <stdlib.h> #include <stdlib.h>
// Internal key state used for sticky keys // Internal key state used for sticky keys
@ -239,6 +240,7 @@ GLFWbool _glfwIsPrintable(int key)
GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode) GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(0); _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) GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
@ -288,6 +291,7 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode)
GLFWAPI int glfwGetKey(GLFWwindow* handle, int key) GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE); _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) GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE); _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) GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
if (xpos) if (xpos)
*xpos = 0; *xpos = 0;
@ -355,6 +361,7 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos) GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
@ -378,6 +385,8 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
{ {
_GLFWcursor* cursor; _GLFWcursor* cursor;
assert(image);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
cursor = calloc(1, sizeof(_GLFWcursor)); cursor = calloc(1, sizeof(_GLFWcursor));
@ -462,6 +471,7 @@ GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
{ {
_GLFWwindow* window = (_GLFWwindow*) windowHandle; _GLFWwindow* window = (_GLFWwindow*) windowHandle;
_GLFWcursor* cursor = (_GLFWcursor*) cursorHandle; _GLFWcursor* cursor = (_GLFWcursor*) cursorHandle;
assert(window);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
@ -473,6 +483,8 @@ GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun) GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.key, cbfun); _GLFW_SWAP_POINTERS(window->callbacks.key, cbfun);
return cbfun; return cbfun;
@ -481,6 +493,8 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun) GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.character, cbfun); _GLFW_SWAP_POINTERS(window->callbacks.character, cbfun);
return cbfun; return cbfun;
@ -489,6 +503,8 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun)
GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmodsfun cbfun) GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmodsfun cbfun)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.charmods, cbfun); _GLFW_SWAP_POINTERS(window->callbacks.charmods, cbfun);
return cbfun; return cbfun;
@ -498,6 +514,8 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle,
GLFWmousebuttonfun cbfun) GLFWmousebuttonfun cbfun)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.mouseButton, cbfun); _GLFW_SWAP_POINTERS(window->callbacks.mouseButton, cbfun);
return cbfun; return cbfun;
@ -507,6 +525,8 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle,
GLFWcursorposfun cbfun) GLFWcursorposfun cbfun)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.cursorPos, cbfun); _GLFW_SWAP_POINTERS(window->callbacks.cursorPos, cbfun);
return cbfun; return cbfun;
@ -516,6 +536,8 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle,
GLFWcursorenterfun cbfun) GLFWcursorenterfun cbfun)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.cursorEnter, cbfun); _GLFW_SWAP_POINTERS(window->callbacks.cursorEnter, cbfun);
return cbfun; return cbfun;
@ -525,6 +547,8 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle,
GLFWscrollfun cbfun) GLFWscrollfun cbfun)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.scroll, cbfun); _GLFW_SWAP_POINTERS(window->callbacks.scroll, cbfun);
return cbfun; return cbfun;
@ -533,6 +557,8 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle,
GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun) GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun); _GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun);
return cbfun; return cbfun;
@ -553,6 +579,7 @@ GLFWAPI int glfwJoystickPresent(int joy)
GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count) GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count)
{ {
assert(count);
*count = 0; *count = 0;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _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) GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count)
{ {
assert(count);
*count = 0; *count = 0;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
@ -597,6 +625,10 @@ GLFWAPI const char* glfwGetJoystickName(int joy)
GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string) GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
assert(string);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformSetClipboardString(window, string); _glfwPlatformSetClipboardString(window, string);
} }
@ -604,6 +636,8 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle) GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return _glfwPlatformGetClipboardString(window); return _glfwPlatformGetClipboardString(window);
} }

View File

@ -47,6 +47,26 @@
#define GLFW_INCLUDE_NONE #define GLFW_INCLUDE_NONE
#include "../include/GLFW/glfw3.h" #include "../include/GLFW/glfw3.h"
#include <stddef.h>
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef unsigned __int64 GLFWuint64;
#else
#include <stdint.h>
typedef uint64_t GLFWuint64;
#endif
typedef int GLFWbool;
typedef struct _GLFWwndconfig _GLFWwndconfig;
typedef struct _GLFWctxconfig _GLFWctxconfig;
typedef struct _GLFWfbconfig _GLFWfbconfig;
typedef struct _GLFWcontext _GLFWcontext;
typedef struct _GLFWwindow _GLFWwindow;
typedef struct _GLFWlibrary _GLFWlibrary;
typedef struct _GLFWmonitor _GLFWmonitor;
typedef struct _GLFWcursor _GLFWcursor;
#define GL_VERSION 0x1f02 #define GL_VERSION 0x1f02
#define GL_NONE 0 #define GL_NONE 0
#define GL_COLOR_BUFFER_BIT 0x00004000 #define GL_COLOR_BUFFER_BIT 0x00004000
@ -76,16 +96,66 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGPROC)(GLenum);
typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*); typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*);
typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint); typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
typedef struct _GLFWwndconfig _GLFWwndconfig; #define VK_NULL_HANDLE 0
typedef struct _GLFWctxconfig _GLFWctxconfig;
typedef struct _GLFWfbconfig _GLFWfbconfig;
typedef struct _GLFWcontext _GLFWcontext;
typedef struct _GLFWwindow _GLFWwindow;
typedef struct _GLFWlibrary _GLFWlibrary;
typedef struct _GLFWmonitor _GLFWmonitor;
typedef struct _GLFWcursor _GLFWcursor;
typedef int GLFWbool; typedef GLFWuint64 VkInstance;
typedef GLFWuint64 VkPhysicalDevice;
typedef GLFWuint64 VkSurfaceKHR;
typedef unsigned int VkFlags;
typedef unsigned int VkBool32;
typedef enum VkStructureType
{
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000,
VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000,
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR = 1000007000,
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
} VkStructureType;
typedef enum VkResult
{
VK_SUCCESS = 0,
VK_NOT_READY = 1,
VK_TIMEOUT = 2,
VK_EVENT_SET = 3,
VK_EVENT_RESET = 4,
VK_INCOMPLETE = 5,
VK_ERROR_OUT_OF_HOST_MEMORY = -1,
VK_ERROR_OUT_OF_DEVICE_MEMORY = -2,
VK_ERROR_INITIALIZATION_FAILED = -3,
VK_ERROR_DEVICE_LOST = -4,
VK_ERROR_MEMORY_MAP_FAILED = -5,
VK_ERROR_LAYER_NOT_PRESENT = -6,
VK_ERROR_EXTENSION_NOT_PRESENT = -7,
VK_ERROR_FEATURE_NOT_PRESENT = -8,
VK_ERROR_INCOMPATIBLE_DRIVER = -9,
VK_ERROR_TOO_MANY_OBJECTS = -10,
VK_ERROR_FORMAT_NOT_SUPPORTED = -11,
VK_ERROR_SURFACE_LOST_KHR = -1000000000,
VK_SUBOPTIMAL_KHR = 1000001003,
VK_ERROR_OUT_OF_DATE_KHR = -1000001004,
VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,
VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
VK_RESULT_MAX_ENUM = 0x7FFFFFFF
} VkResult;
typedef struct VkAllocationCallbacks VkAllocationCallbacks;
typedef struct VkExtensionProperties
{
char extensionName[256];
unsigned int specVersion;
} VkExtensionProperties;
typedef void (APIENTRY * PFN_vkVoidFunction)(void);
typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*);
typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,unsigned int*,VkExtensionProperties*);
#define vkEnumerateInstanceExtensionProperties _glfw.vk.EnumerateInstanceExtensionProperties
#define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr
#if defined(_GLFW_COCOA) #if defined(_GLFW_COCOA)
#include "cocoa_platform.h" #include "cocoa_platform.h"
@ -366,6 +436,21 @@ struct _GLFWlibrary
_GLFWmonitor** monitors; _GLFWmonitor** monitors;
int monitorCount; int monitorCount;
struct {
GLFWbool available;
void* handle;
char** extensions;
int extensionCount;
PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
GLFWbool KHR_surface;
GLFWbool KHR_win32_surface;
GLFWbool KHR_xlib_surface;
GLFWbool KHR_xcb_surface;
GLFWbool KHR_wayland_surface;
GLFWbool KHR_mir_surface;
} vk;
struct { struct {
GLFWmonitorfun monitor; GLFWmonitorfun monitor;
} callbacks; } callbacks;
@ -689,6 +774,18 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor);
*/ */
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor); void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor);
/*! @ingroup platform
*/
char** _glfwPlatformGetRequiredInstanceExtensions(int* count);
/*! @ingroup platform
*/
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, unsigned int queuefamily);
/*! @ingroup platform
*/
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
//======================================================================== //========================================================================
// Event API functions // Event API functions
@ -923,4 +1020,16 @@ void _glfwFreeMonitors(_GLFWmonitor** monitors, int count);
*/ */
GLFWbool _glfwIsPrintable(int key); GLFWbool _glfwIsPrintable(int key);
/*! @ingroup utility
*/
void _glfwInitVulkan(void);
/*! @ingroup utility
*/
void _glfwTerminateVulkan(void);
/*! @ingroup utility
*/
const char* _glfwGetVulkanResultString(VkResult result);
#endif // _glfw3_internal_h_ #endif // _glfw3_internal_h_

View File

@ -29,9 +29,24 @@
#include <sys/queue.h> #include <sys/queue.h>
#include <pthread.h> #include <pthread.h>
#include <dlfcn.h>
#include <mir_toolkit/mir_client_library.h> #include <mir_toolkit/mir_client_library.h>
typedef VkFlags VkMirSurfaceCreateFlagsKHR;
typedef struct VkMirSurfaceCreateInfoKHR
{
VkStructureType sType;
const void* pNext;
VkMirSurfaceCreateFlagsKHR flags;
MirConnection* connection;
MirSurface* mirSurface;
} VkMirSurfaceCreateInfoKHR;
typedef VkResult (APIENTRY *PFN_vkCreateMirSurfaceKHR)(VkInstance,const VkMirSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice,uint32_t,MirConnection*);
#include "posix_tls.h" #include "posix_tls.h"
#include "posix_time.h" #include "posix_time.h"
#include "linux_joystick.h" #include "linux_joystick.h"
@ -43,6 +58,10 @@
#error "The Mir backend depends on EGL platform support" #error "The Mir backend depends on EGL platform support"
#endif #endif
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
#define _glfw_dlclose(handle) dlclose(handle)
#define _glfw_dlsym(handle, name) dlsym(handle, name)
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->mir.window) #define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->mir.window)
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.mir.display) #define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.mir.display)

View File

@ -706,6 +706,76 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
return NULL; return NULL;
} }
char** _glfwPlatformGetRequiredInstanceExtensions(int* count)
{
char** extensions;
*count = 0;
if (!_glfw.vk.KHR_mir_surface)
return NULL;
extensions = calloc(2, sizeof(char*));
extensions[0] = strdup("VK_KHR_surface");
extensions[1] = strdup("VK_KHR_mir_surface");
*count = 2;
return extensions;
}
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
unsigned int queuefamily)
{
PFN_vkGetPhysicalDeviceMirPresentationSupportKHR vkGetPhysicalDeviceMirPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
if (!vkGetPhysicalDeviceMirPresentationSupportKHR)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Mir: Vulkan instance missing VK_KHR_mir_surface extension");
return GLFW_FALSE;
}
return vkGetPhysicalDeviceMirPresentationSupportKHR(device,
queuefamily,
_glfw.mir.connection);
}
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
_GLFWwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface)
{
VkResult err;
VkMirSurfaceCreateInfoKHR sci;
PFN_vkCreateMirSurfaceKHR vkCreateMirSurfaceKHR;
vkCreateMirSurfaceKHR = (PFN_vkCreateMirSurfaceKHR)
vkGetInstanceProcAddr(instance, "vkCreateMirSurfaceKHR");
if (!vkCreateMirSurfaceKHR)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Mir: Vulkan instance missing VK_KHR_mir_surface extension");
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
memset(&sci, 0, sizeof(sci));
sci.sType = VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR;
sci.display = _glfw.mir.connection;
sci.surface = window->mir.surface;
err = vkCreateMirSurfaceKHR(instance, &sci, allocator, surface);
if (err)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Failed to create Vulkan surface: %s",
_glfwGetVulkanResultString(err));
}
return err;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW native API ////// ////// GLFW native API //////

View File

@ -27,6 +27,7 @@
#include "internal.h" #include "internal.h"
#include <assert.h>
#include <math.h> #include <math.h>
#include <float.h> #include <float.h>
#include <string.h> #include <string.h>
@ -293,6 +294,7 @@ void _glfwSplitBPP(int bpp, int* red, int* green, int* blue)
GLFWAPI GLFWmonitor** glfwGetMonitors(int* count) GLFWAPI GLFWmonitor** glfwGetMonitors(int* count)
{ {
assert(count);
*count = 0; *count = 0;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
@ -314,6 +316,7 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void)
GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos) GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor);
if (xpos) if (xpos)
*xpos = 0; *xpos = 0;
@ -328,6 +331,7 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos)
GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM) GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor);
if (widthMM) if (widthMM)
*widthMM = 0; *widthMM = 0;
@ -345,6 +349,8 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int*
GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle) GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->name; return monitor->name;
} }
@ -359,7 +365,9 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun)
GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count) GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor);
assert(count);
*count = 0; *count = 0;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
@ -374,6 +382,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count)
GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle) GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
@ -422,6 +431,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
@ -434,6 +444,9 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp) GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor);
assert(ramp);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();

287
src/vulkan.c Normal file
View 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);
}

View File

@ -102,8 +102,8 @@ static GLFWbool loadLibraries(void)
_glfw.win32.shcore.instance = LoadLibraryA("shcore.dll"); _glfw.win32.shcore.instance = LoadLibraryA("shcore.dll");
if (_glfw.win32.shcore.instance) if (_glfw.win32.shcore.instance)
{ {
_glfw.win32.shcore.SetProcessDPIAwareness = (SETPROCESSDPIAWARENESS_T) _glfw.win32.shcore.SetProcessDpiAwareness = (SETPROCESSDPIAWARENESS_T)
GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDPIAwareness"); GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDpiAwareness");
} }
return GLFW_TRUE; return GLFW_TRUE;
@ -357,8 +357,8 @@ int _glfwPlatformInit(void)
createKeyTables(); createKeyTables();
if (_glfw_SetProcessDPIAwareness) if (_glfw_SetProcessDpiAwareness)
_glfw_SetProcessDPIAwareness(PROCESS_PER_MONITOR_DPI_AWARE); _glfw_SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
else if (_glfw_SetProcessDPIAware) else if (_glfw_SetProcessDPIAware)
_glfw_SetProcessDPIAware(); _glfw_SetProcessDPIAware();
@ -387,6 +387,9 @@ int _glfwPlatformInit(void)
void _glfwPlatformTerminate(void) void _glfwPlatformTerminate(void)
{ {
if (_glfw.win32.helperWindow)
DestroyWindow(_glfw.win32.helperWindow);
_glfwUnregisterWindowClassWin32(); _glfwUnregisterWindowClassWin32();
// Restore previous foreground lock timeout system setting // Restore previous foreground lock timeout system setting
@ -405,9 +408,6 @@ void _glfwPlatformTerminate(void)
_glfwTerminateJoysticksWin32(); _glfwTerminateJoysticksWin32();
_glfwTerminateThreadLocalStorageWin32(); _glfwTerminateThreadLocalStorageWin32();
if (_glfw.win32.helperWindow)
DestroyWindow(_glfw.win32.helperWindow);
freeLibraries(); freeLibraries();
} }

View File

@ -138,7 +138,21 @@ typedef HRESULT (WINAPI * DWMFLUSH_T)(VOID);
// shcore.dll function pointer typedefs // shcore.dll function pointer typedefs
typedef HRESULT (WINAPI * SETPROCESSDPIAWARENESS_T)(PROCESS_DPI_AWARENESS); typedef HRESULT (WINAPI * SETPROCESSDPIAWARENESS_T)(PROCESS_DPI_AWARENESS);
#define _glfw_SetProcessDPIAwareness _glfw.win32.shcore.SetProcessDPIAwareness #define _glfw_SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
typedef struct VkWin32SurfaceCreateInfoKHR
{
VkStructureType sType;
const void* pNext;
VkWin32SurfaceCreateFlagsKHR flags;
HINSTANCE hinstance;
HWND hwnd;
} VkWin32SurfaceCreateInfoKHR;
typedef VkResult (APIENTRY *PFN_vkCreateWin32SurfaceKHR)(VkInstance,const VkWin32SurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice,uint32_t);
#include "win32_joystick.h" #include "win32_joystick.h"
@ -154,6 +168,10 @@ typedef HRESULT (WINAPI * SETPROCESSDPIAWARENESS_T)(PROCESS_DPI_AWARENESS);
#define _GLFW_WNDCLASSNAME L"GLFW30" #define _GLFW_WNDCLASSNAME L"GLFW30"
#define _glfw_dlopen(name) LoadLibraryA(name)
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32 #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32 #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32
#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeWin32 win32_time #define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeWin32 win32_time
@ -218,7 +236,7 @@ typedef struct _GLFWlibraryWin32
// shcore.dll // shcore.dll
struct { struct {
HINSTANCE instance; HINSTANCE instance;
SETPROCESSDPIAWARENESS_T SetProcessDPIAwareness; SETPROCESSDPIAWARENESS_T SetProcessDpiAwareness;
} shcore; } shcore;
} _GLFWlibraryWin32; } _GLFWlibraryWin32;

View File

@ -1403,6 +1403,74 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
return _glfw.win32.clipboardString; return _glfw.win32.clipboardString;
} }
char** _glfwPlatformGetRequiredInstanceExtensions(int* count)
{
char** extensions;
*count = 0;
if (!_glfw.vk.KHR_win32_surface)
return NULL;
extensions = calloc(2, sizeof(char*));
extensions[0] = strdup("VK_KHR_surface");
extensions[1] = strdup("VK_KHR_win32_surface");
*count = 2;
return extensions;
}
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
unsigned int queuefamily)
{
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR =
(PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
if (!vkGetPhysicalDeviceWin32PresentationSupportKHR)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Win32: Vulkan instance missing VK_KHR_win32_surface extension");
return GLFW_FALSE;
}
return vkGetPhysicalDeviceWin32PresentationSupportKHR(device, queuefamily);
}
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
_GLFWwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface)
{
VkResult err;
VkWin32SurfaceCreateInfoKHR sci;
PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
vkCreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)
vkGetInstanceProcAddr(instance, "vkCreateWin32SurfaceKHR");
if (!vkCreateWin32SurfaceKHR)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Win32: Vulkan instance missing VK_KHR_win32_surface extension");
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
memset(&sci, 0, sizeof(sci));
sci.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
sci.hinstance = GetModuleHandle(NULL);
sci.hwnd = window->win32.handle;
err = vkCreateWin32SurfaceKHR(instance, &sci, allocator, surface);
if (err)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to create Vulkan surface: %s",
_glfwGetVulkanResultString(err));
}
return err;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW native API ////// ////// GLFW native API //////

View File

@ -28,6 +28,7 @@
#include "internal.h" #include "internal.h"
#include <assert.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@ -124,6 +125,8 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
_GLFWwindow* window; _GLFWwindow* window;
_GLFWwindow* previous; _GLFWwindow* previous;
assert(title);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (width <= 0 || height <= 0) if (width <= 0 || height <= 0)
@ -274,107 +277,107 @@ void glfwDefaultWindowHints(void)
_glfw.hints.refreshRate = GLFW_DONT_CARE; _glfw.hints.refreshRate = GLFW_DONT_CARE;
} }
GLFWAPI void glfwWindowHint(int target, int hint) GLFWAPI void glfwWindowHint(int hint, int value)
{ {
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
switch (target) switch (hint)
{ {
case GLFW_RED_BITS: case GLFW_RED_BITS:
_glfw.hints.framebuffer.redBits = hint; _glfw.hints.framebuffer.redBits = value;
break; break;
case GLFW_GREEN_BITS: case GLFW_GREEN_BITS:
_glfw.hints.framebuffer.greenBits = hint; _glfw.hints.framebuffer.greenBits = value;
break; break;
case GLFW_BLUE_BITS: case GLFW_BLUE_BITS:
_glfw.hints.framebuffer.blueBits = hint; _glfw.hints.framebuffer.blueBits = value;
break; break;
case GLFW_ALPHA_BITS: case GLFW_ALPHA_BITS:
_glfw.hints.framebuffer.alphaBits = hint; _glfw.hints.framebuffer.alphaBits = value;
break; break;
case GLFW_DEPTH_BITS: case GLFW_DEPTH_BITS:
_glfw.hints.framebuffer.depthBits = hint; _glfw.hints.framebuffer.depthBits = value;
break; break;
case GLFW_STENCIL_BITS: case GLFW_STENCIL_BITS:
_glfw.hints.framebuffer.stencilBits = hint; _glfw.hints.framebuffer.stencilBits = value;
break; break;
case GLFW_ACCUM_RED_BITS: case GLFW_ACCUM_RED_BITS:
_glfw.hints.framebuffer.accumRedBits = hint; _glfw.hints.framebuffer.accumRedBits = value;
break; break;
case GLFW_ACCUM_GREEN_BITS: case GLFW_ACCUM_GREEN_BITS:
_glfw.hints.framebuffer.accumGreenBits = hint; _glfw.hints.framebuffer.accumGreenBits = value;
break; break;
case GLFW_ACCUM_BLUE_BITS: case GLFW_ACCUM_BLUE_BITS:
_glfw.hints.framebuffer.accumBlueBits = hint; _glfw.hints.framebuffer.accumBlueBits = value;
break; break;
case GLFW_ACCUM_ALPHA_BITS: case GLFW_ACCUM_ALPHA_BITS:
_glfw.hints.framebuffer.accumAlphaBits = hint; _glfw.hints.framebuffer.accumAlphaBits = value;
break; break;
case GLFW_AUX_BUFFERS: case GLFW_AUX_BUFFERS:
_glfw.hints.framebuffer.auxBuffers = hint; _glfw.hints.framebuffer.auxBuffers = value;
break; break;
case GLFW_STEREO: case GLFW_STEREO:
_glfw.hints.framebuffer.stereo = hint ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE;
break; break;
case GLFW_DOUBLEBUFFER: case GLFW_DOUBLEBUFFER:
_glfw.hints.framebuffer.doublebuffer = hint ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE;
break; break;
case GLFW_TRANSPARENT: case GLFW_TRANSPARENT:
_glfw.hints.framebuffer.transparent = hint ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.framebuffer.transparent = hint ? GLFW_TRUE : GLFW_FALSE;
break; break;
case GLFW_SAMPLES: case GLFW_SAMPLES:
_glfw.hints.framebuffer.samples = hint; _glfw.hints.framebuffer.samples = value;
break; break;
case GLFW_SRGB_CAPABLE: case GLFW_SRGB_CAPABLE:
_glfw.hints.framebuffer.sRGB = hint ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE;
break; break;
case GLFW_RESIZABLE: case GLFW_RESIZABLE:
_glfw.hints.window.resizable = hint ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE;
break; break;
case GLFW_DECORATED: case GLFW_DECORATED:
_glfw.hints.window.decorated = hint ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;
break; break;
case GLFW_FOCUSED: case GLFW_FOCUSED:
_glfw.hints.window.focused = hint ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;
break; break;
case GLFW_AUTO_ICONIFY: case GLFW_AUTO_ICONIFY:
_glfw.hints.window.autoIconify = hint ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE;
break; break;
case GLFW_FLOATING: case GLFW_FLOATING:
_glfw.hints.window.floating = hint ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE;
break; break;
case GLFW_VISIBLE: case GLFW_VISIBLE:
_glfw.hints.window.visible = hint ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
break; break;
case GLFW_CLIENT_API: case GLFW_CLIENT_API:
_glfw.hints.context.api = hint; _glfw.hints.context.api = value;
break; break;
case GLFW_CONTEXT_VERSION_MAJOR: case GLFW_CONTEXT_VERSION_MAJOR:
_glfw.hints.context.major = hint; _glfw.hints.context.major = value;
break; break;
case GLFW_CONTEXT_VERSION_MINOR: case GLFW_CONTEXT_VERSION_MINOR:
_glfw.hints.context.minor = hint; _glfw.hints.context.minor = value;
break; break;
case GLFW_CONTEXT_ROBUSTNESS: case GLFW_CONTEXT_ROBUSTNESS:
_glfw.hints.context.robustness = hint; _glfw.hints.context.robustness = value;
break; break;
case GLFW_OPENGL_FORWARD_COMPAT: case GLFW_OPENGL_FORWARD_COMPAT:
_glfw.hints.context.forward = hint ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;
break; break;
case GLFW_OPENGL_DEBUG_CONTEXT: case GLFW_OPENGL_DEBUG_CONTEXT:
_glfw.hints.context.debug = hint ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
break; break;
case GLFW_CONTEXT_NO_ERROR: case GLFW_CONTEXT_NO_ERROR:
_glfw.hints.context.noerror = hint ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE;
break; break;
case GLFW_OPENGL_PROFILE: case GLFW_OPENGL_PROFILE:
_glfw.hints.context.profile = hint; _glfw.hints.context.profile = value;
break; break;
case GLFW_CONTEXT_RELEASE_BEHAVIOR: case GLFW_CONTEXT_RELEASE_BEHAVIOR:
_glfw.hints.context.release = hint; _glfw.hints.context.release = value;
break; break;
case GLFW_REFRESH_RATE: case GLFW_REFRESH_RATE:
_glfw.hints.refreshRate = hint; _glfw.hints.refreshRate = value;
break; break;
default: default:
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint"); _glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint");
@ -422,6 +425,8 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle) GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(0); _GLFW_REQUIRE_INIT_OR_RETURN(0);
return window->closed; return window->closed;
} }
@ -429,6 +434,8 @@ GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle)
GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value) GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
window->closed = value; window->closed = value;
} }
@ -436,6 +443,10 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value)
GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title) GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
assert(title);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformSetWindowTitle(window, title); _glfwPlatformSetWindowTitle(window, title);
} }
@ -443,6 +454,7 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title)
GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos) GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
if (xpos) if (xpos)
*xpos = 0; *xpos = 0;
@ -456,6 +468,7 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos)
GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos) GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT(); _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) GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
if (width) if (width)
*width = 0; *width = 0;
@ -485,6 +499,7 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height)
GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height) GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
@ -502,6 +517,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle,
int maxwidth, int maxheight) int maxwidth, int maxheight)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
@ -516,6 +532,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle,
GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom) GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT(); _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) GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
if (width) if (width)
*width = 0; *width = 0;
@ -549,6 +567,7 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle,
int* right, int* bottom) int* right, int* bottom)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
if (left) if (left)
*left = 0; *left = 0;
@ -566,6 +585,8 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle,
GLFWAPI void glfwIconifyWindow(GLFWwindow* handle) GLFWAPI void glfwIconifyWindow(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformIconifyWindow(window); _glfwPlatformIconifyWindow(window);
} }
@ -573,6 +594,8 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* handle)
GLFWAPI void glfwRestoreWindow(GLFWwindow* handle) GLFWAPI void glfwRestoreWindow(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformRestoreWindow(window); _glfwPlatformRestoreWindow(window);
} }
@ -580,6 +603,7 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow* handle)
GLFWAPI void glfwShowWindow(GLFWwindow* handle) GLFWAPI void glfwShowWindow(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
@ -592,6 +616,7 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle)
GLFWAPI void glfwHideWindow(GLFWwindow* handle) GLFWAPI void glfwHideWindow(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
@ -604,6 +629,7 @@ GLFWAPI void glfwHideWindow(GLFWwindow* handle)
GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(0); _GLFW_REQUIRE_INIT_OR_RETURN(0);
@ -650,6 +676,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle) GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return (GLFWmonitor*) window->monitor; return (GLFWmonitor*) window->monitor;
} }
@ -657,6 +685,8 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle)
GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer) GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
window->userPointer = pointer; window->userPointer = pointer;
} }
@ -664,6 +694,8 @@ GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer)
GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* handle) GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return window->userPointer; return window->userPointer;
} }
@ -672,6 +704,8 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle,
GLFWwindowposfun cbfun) GLFWwindowposfun cbfun)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.pos, cbfun); _GLFW_SWAP_POINTERS(window->callbacks.pos, cbfun);
return cbfun; return cbfun;
@ -681,6 +715,8 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle,
GLFWwindowsizefun cbfun) GLFWwindowsizefun cbfun)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.size, cbfun); _GLFW_SWAP_POINTERS(window->callbacks.size, cbfun);
return cbfun; return cbfun;
@ -690,6 +726,8 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle,
GLFWwindowclosefun cbfun) GLFWwindowclosefun cbfun)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.close, cbfun); _GLFW_SWAP_POINTERS(window->callbacks.close, cbfun);
return cbfun; return cbfun;
@ -699,6 +737,8 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle,
GLFWwindowrefreshfun cbfun) GLFWwindowrefreshfun cbfun)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.refresh, cbfun); _GLFW_SWAP_POINTERS(window->callbacks.refresh, cbfun);
return cbfun; return cbfun;
@ -708,6 +748,8 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle,
GLFWwindowfocusfun cbfun) GLFWwindowfocusfun cbfun)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.focus, cbfun); _GLFW_SWAP_POINTERS(window->callbacks.focus, cbfun);
return cbfun; return cbfun;
@ -717,6 +759,8 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle,
GLFWwindowiconifyfun cbfun) GLFWwindowiconifyfun cbfun)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.iconify, cbfun); _GLFW_SWAP_POINTERS(window->callbacks.iconify, cbfun);
return cbfun; return cbfun;
@ -726,6 +770,8 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle
GLFWframebuffersizefun cbfun) GLFWframebuffersizefun cbfun)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.fbsize, cbfun); _GLFW_SWAP_POINTERS(window->callbacks.fbsize, cbfun);
return cbfun; return cbfun;

View File

@ -36,6 +36,11 @@
#include <wayland-cursor.h> #include <wayland-cursor.h>
static inline int min(int n1, int n2)
{
return n1 < n2 ? n1 : n2;
}
static void pointerHandleEnter(void* data, static void pointerHandleEnter(void* data,
struct wl_pointer* pointer, struct wl_pointer* pointer,
uint32_t serial, uint32_t serial,
@ -380,8 +385,10 @@ static void registryHandleGlobal(void* data,
{ {
if (strcmp(interface, "wl_compositor") == 0) if (strcmp(interface, "wl_compositor") == 0)
{ {
_glfw.wl.wl_compositor_version = min(3, version);
_glfw.wl.compositor = _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) else if (strcmp(interface, "wl_shm") == 0)
{ {

View File

@ -97,6 +97,9 @@ static void scale(void* data,
struct wl_output* output, struct wl_output* output,
int32_t factor) int32_t factor)
{ {
struct _GLFWmonitor *monitor = data;
monitor->wl.scale = factor;
} }
static const struct wl_output_listener output_listener = { 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.modes = calloc(4, sizeof(_GLFWvidmodeWayland));
monitor->wl.modesSize = 4; monitor->wl.modesSize = 4;
monitor->wl.scale = 1;
monitor->wl.output = output; monitor->wl.output = output;
wl_output_add_listener(output, &output_listener, monitor); wl_output_add_listener(output, &output_listener, monitor);

View File

@ -29,6 +29,21 @@
#include <wayland-client.h> #include <wayland-client.h>
#include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon.h>
#include <dlfcn.h>
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
typedef struct VkWaylandSurfaceCreateInfoKHR
{
VkStructureType sType;
const void* pNext;
VkWaylandSurfaceCreateFlagsKHR flags;
struct wl_display* display;
struct wl_surface* surface;
} VkWaylandSurfaceCreateInfoKHR;
typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*);
#include "posix_tls.h" #include "posix_tls.h"
#include "posix_time.h" #include "posix_time.h"
@ -41,6 +56,10 @@
#error "The Wayland backend depends on EGL platform support" #error "The Wayland backend depends on EGL platform support"
#endif #endif
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
#define _glfw_dlclose(handle) dlclose(handle)
#define _glfw_dlsym(handle, name) dlsym(handle, name)
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->wl.native) #define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->wl.native)
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.wl.display) #define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.wl.display)
@ -65,8 +84,17 @@ typedef struct _GLFWwindowWayland
struct wl_egl_window* native; struct wl_egl_window* native;
struct wl_shell_surface* shell_surface; struct wl_shell_surface* shell_surface;
struct wl_callback* callback; struct wl_callback* callback;
_GLFWcursor* currentCursor; _GLFWcursor* currentCursor;
double cursorPosX, cursorPosY; 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; } _GLFWwindowWayland;
@ -83,6 +111,8 @@ typedef struct _GLFWlibraryWayland
struct wl_pointer* pointer; struct wl_pointer* pointer;
struct wl_keyboard* keyboard; struct wl_keyboard* keyboard;
int wl_compositor_version;
struct wl_cursor_theme* cursorTheme; struct wl_cursor_theme* cursorTheme;
struct wl_surface* cursorSurface; struct wl_surface* cursorSurface;
uint32_t pointerSerial; uint32_t pointerSerial;
@ -123,7 +153,7 @@ typedef struct _GLFWmonitorWayland
int x; int x;
int y; int y;
int scale;
} _GLFWmonitorWayland; } _GLFWmonitorWayland;

View File

@ -72,6 +72,84 @@ static const struct wl_shell_surface_listener shellSurfaceListener = {
handlePopupDone 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, static GLFWbool createSurface(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig) const _GLFWwndconfig* wndconfig)
{ {
@ -79,6 +157,10 @@ static GLFWbool createSurface(_GLFWwindow* window,
if (!window->wl.surface) if (!window->wl.surface)
return GLFW_FALSE; return GLFW_FALSE;
wl_surface_add_listener(window->wl.surface,
&surfaceListener,
window);
wl_surface_set_user_data(window->wl.surface, window); wl_surface_set_user_data(window->wl.surface, window);
window->wl.native = wl_egl_window_create(window->wl.surface, 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.width = wndconfig->width;
window->wl.height = wndconfig->height; window->wl.height = wndconfig->height;
window->wl.scale = 1;
return GLFW_TRUE; return GLFW_TRUE;
} }
@ -262,6 +345,10 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
window->wl.currentCursor = NULL; window->wl.currentCursor = NULL;
window->wl.monitors = calloc(1, sizeof(_GLFWmonitor*));
window->wl.monitorsCount = 0;
window->wl.monitorsSize = 1;
return GLFW_TRUE; return GLFW_TRUE;
} }
@ -288,6 +375,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
if (window->wl.surface) if (window->wl.surface)
wl_surface_destroy(window->wl.surface); wl_surface_destroy(window->wl.surface);
free(window->wl.monitors);
} }
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) 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) 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.width = width;
window->wl.height = height; window->wl.height = height;
wl_egl_window_resize(window->wl.native, scaledWidth, scaledHeight, 0, 0);
_glfwInputFramebufferSize(window, scaledWidth, scaledHeight);
} }
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
@ -344,6 +436,8 @@ void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
{ {
_glfwPlatformGetWindowSize(window, width, height); _glfwPlatformGetWindowSize(window, width, height);
*width *= window->wl.scale;
*height *= window->wl.scale;
} }
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
@ -605,6 +699,76 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
return NULL; return NULL;
} }
char** _glfwPlatformGetRequiredInstanceExtensions(int* count)
{
char** extensions;
*count = 0;
if (!_glfw.vk.KHR_wayland_surface)
return NULL;
extensions = calloc(2, sizeof(char*));
extensions[0] = strdup("VK_KHR_surface");
extensions[1] = strdup("VK_KHR_wayland_surface");
*count = 2;
return extensions;
}
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
unsigned int queuefamily)
{
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
if (!vkGetPhysicalDeviceWaylandPresentationSupportKHR)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Wayland: Vulkan instance missing VK_KHR_wayland_surface extension");
return VK_NULL_HANDLE;
}
return vkGetPhysicalDeviceWaylandPresentationSupportKHR(device,
queuefamily,
_glfw.wl.display);
}
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
_GLFWwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface)
{
VkResult err;
VkWaylandSurfaceCreateInfoKHR sci;
PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;
vkCreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR)
vkGetInstanceProcAddr(instance, "vkCreateWaylandSurfaceKHR");
if (!vkCreateWaylandSurfaceKHR)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Wayland: Vulkan instance missing VK_KHR_wayland_surface extension");
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
memset(&sci, 0, sizeof(sci));
sci.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
sci.display = _glfw.wl.display;
sci.surface = window->wl.surface;
err = vkCreateWaylandSurfaceKHR(instance, &sci, allocator, surface);
if (err)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Failed to create Vulkan surface: %s",
_glfwGetVulkanResultString(err));
}
return err;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW native API ////// ////// GLFW native API //////

View File

@ -310,7 +310,7 @@ static void createKeyTables(void)
} }
XkbFreeNames(desc, XkbKeyNamesMask, True); XkbFreeNames(desc, XkbKeyNamesMask, True);
XkbFreeClientMap(desc, 0, True); XkbFreeKeyboard(desc, 0, True);
} }
for (scancode = 0; scancode < 256; scancode++) 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 // Update the key code LUT
// FIXME: We should listen to XkbMapNotify events to track changes to // FIXME: We should listen to XkbMapNotify events to track changes to
// the keyboard mapping. // the keyboard mapping.
@ -789,6 +796,12 @@ int _glfwPlatformInit(void)
void _glfwPlatformTerminate(void) void _glfwPlatformTerminate(void)
{ {
if (_glfw.x11.x11xcb.handle)
{
dlclose(_glfw.x11.x11xcb.handle);
_glfw.x11.x11xcb.handle = NULL;
}
if (_glfw.x11.cursor) if (_glfw.x11.cursor)
{ {
XFreeCursor(_glfw.x11.display, _glfw.x11.cursor); XFreeCursor(_glfw.x11.display, _glfw.x11.cursor);

View File

@ -31,6 +31,7 @@
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
#include <stdint.h> #include <stdint.h>
#include <dlfcn.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/keysym.h> #include <X11/keysym.h>
@ -56,6 +57,37 @@
#include <X11/extensions/xf86vmode.h> #include <X11/extensions/xf86vmode.h>
#endif #endif
typedef XID xcb_window_t;
typedef XID xcb_visualid_t;
typedef struct xcb_connection_t xcb_connection_t;
typedef xcb_connection_t* (* XGETXCBCONNECTION_T)(Display*);
typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
typedef struct VkXlibSurfaceCreateInfoKHR
{
VkStructureType sType;
const void* pNext;
VkXlibSurfaceCreateFlagsKHR flags;
Display* dpy;
Window window;
} VkXlibSurfaceCreateInfoKHR;
typedef struct VkXcbSurfaceCreateInfoKHR
{
VkStructureType sType;
const void* pNext;
VkXcbSurfaceCreateFlagsKHR flags;
xcb_connection_t* connection;
xcb_window_t window;
} VkXcbSurfaceCreateInfoKHR;
typedef VkResult (APIENTRY *PFN_vkCreateXlibSurfaceKHR)(VkInstance,const VkXlibSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice,uint32_t,Display*,VisualID);
typedef VkResult (APIENTRY *PFN_vkCreateXcbSurfaceKHR)(VkInstance,const VkXcbSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice,uint32_t,xcb_connection_t*,xcb_visualid_t);
#include "posix_tls.h" #include "posix_tls.h"
#include "posix_time.h" #include "posix_time.h"
#include "linux_joystick.h" #include "linux_joystick.h"
@ -71,6 +103,10 @@
#error "No supported context creation API selected" #error "No supported context creation API selected"
#endif #endif
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
#define _glfw_dlclose(handle) dlclose(handle)
#define _glfw_dlsym(handle, name) dlsym(handle, name)
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11 #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11 #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11 #define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11
@ -207,6 +243,11 @@ typedef struct _GLFWlibraryX11
int minor; int minor;
} xinerama; } xinerama;
struct {
void* handle;
XGETXCBCONNECTION_T XGetXCBConnection;
} x11xcb;
#if defined(_GLFW_HAS_XINPUT) #if defined(_GLFW_HAS_XINPUT)
struct { struct {
GLFWbool available; GLFWbool available;

View File

@ -1470,6 +1470,13 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
Visual* visual; Visual* visual;
int depth; int depth;
if (ctxconfig->api == GLFW_NO_API)
{
visual = DefaultVisual(_glfw.x11.display, _glfw.x11.screen);
depth = DefaultDepth(_glfw.x11.display, _glfw.x11.screen);
}
else
{
#if defined(_GLFW_GLX) #if defined(_GLFW_GLX)
if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth)) if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth))
return GLFW_FALSE; return GLFW_FALSE;
@ -1477,6 +1484,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth)) if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth))
return GLFW_FALSE; return GLFW_FALSE;
#endif #endif
}
if (!createWindow(window, wndconfig, visual, depth)) if (!createWindow(window, wndconfig, visual, depth))
return GLFW_FALSE; return GLFW_FALSE;
@ -2109,6 +2117,158 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
return _glfw.x11.clipboardString; return _glfw.x11.clipboardString;
} }
char** _glfwPlatformGetRequiredInstanceExtensions(int* count)
{
char** extensions;
*count = 0;
if (!_glfw.vk.KHR_xlib_surface)
{
if (!_glfw.vk.KHR_xcb_surface || !_glfw.x11.x11xcb.handle)
return NULL;
}
extensions = calloc(2, sizeof(char*));
extensions[0] = strdup("VK_KHR_surface");
if (_glfw.vk.KHR_xlib_surface)
extensions[1] = strdup("VK_KHR_xlib_surface");
else
extensions[1] = strdup("VK_KHR_xcb_surface");
*count = 2;
return extensions;
}
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
unsigned int queuefamily)
{
VisualID visualID = XVisualIDFromVisual(DefaultVisual(_glfw.x11.display,
_glfw.x11.screen));
if (_glfw.vk.KHR_xlib_surface)
{
PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
if (!vkGetPhysicalDeviceXlibPresentationSupportKHR)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"X11: Vulkan instance missing VK_KHR_xlib_surface extension");
return GLFW_FALSE;
}
return vkGetPhysicalDeviceXlibPresentationSupportKHR(device,
queuefamily,
_glfw.x11.display,
visualID);
}
else
{
PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
if (!vkGetPhysicalDeviceXcbPresentationSupportKHR)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"X11: Vulkan instance missing VK_KHR_xcb_surface extension");
return GLFW_FALSE;
}
xcb_connection_t* connection =
_glfw.x11.x11xcb.XGetXCBConnection(_glfw.x11.display);
if (!connection)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to retrieve XCB connection");
return GLFW_FALSE;
}
return vkGetPhysicalDeviceXcbPresentationSupportKHR(device,
queuefamily,
connection,
visualID);
}
}
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
_GLFWwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface)
{
if (_glfw.vk.KHR_xlib_surface)
{
VkResult err;
VkXlibSurfaceCreateInfoKHR sci;
PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;
vkCreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR)
vkGetInstanceProcAddr(instance, "vkCreateXlibSurfaceKHR");
if (!vkCreateXlibSurfaceKHR)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"X11: Vulkan instance missing VK_KHR_xlib_surface extension");
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
memset(&sci, 0, sizeof(sci));
sci.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
sci.dpy = _glfw.x11.display;
sci.window = window->x11.handle;
err = vkCreateXlibSurfaceKHR(instance, &sci, allocator, surface);
if (err)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to create Vulkan X11 surface: %s",
_glfwGetVulkanResultString(err));
}
return err;
}
else
{
VkResult err;
VkXcbSurfaceCreateInfoKHR sci;
PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR;
xcb_connection_t* connection =
_glfw.x11.x11xcb.XGetXCBConnection(_glfw.x11.display);
if (!connection)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to retrieve XCB connection");
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
vkCreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR)
vkGetInstanceProcAddr(instance, "vkCreateXcbSurfaceKHR");
if (!vkCreateXcbSurfaceKHR)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"X11: Vulkan instance missing VK_KHR_xcb_surface extension");
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
memset(&sci, 0, sizeof(sci));
sci.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
sci.connection = connection;
sci.window = window->x11.handle;
err = vkCreateXcbSurfaceKHR(instance, &sci, allocator, surface);
if (err)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to create Vulkan XCB surface: %s",
_glfwGetVulkanResultString(err));
}
return err;
}
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW native API ////// ////// GLFW native API //////

View File

@ -2,18 +2,14 @@
link_libraries(glfw) link_libraries(glfw)
if (BUILD_SHARED_LIBS) if (BUILD_SHARED_LIBS)
add_definitions(-DGLFW_DLL)
link_libraries("${MATH_LIBRARY}") link_libraries("${MATH_LIBRARY}")
else()
link_libraries(${glfw_LIBRARIES})
endif() endif()
if (MSVC) if (MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif() endif()
include_directories("${GLFW_SOURCE_DIR}/include" include_directories("${GLFW_SOURCE_DIR}/deps")
"${GLFW_SOURCE_DIR}/deps")
set(GLAD "${GLFW_SOURCE_DIR}/deps/glad/glad.h" set(GLAD "${GLFW_SOURCE_DIR}/deps/glad/glad.h"
"${GLFW_SOURCE_DIR}/deps/glad.c") "${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 set(CONSOLE_BINARIES clipboard events msaa gamma glfwinfo
iconify joysticks monitors reopen cursor) iconify joysticks monitors reopen cursor)
if (VULKAN_FOUND)
add_executable(vulkan WIN32 vulkan.c ${ICON})
target_include_directories(vulkan PRIVATE "${VULKAN_INCLUDE_DIR}")
target_link_libraries(vulkan "${VULKAN_LIBRARY}")
list(APPEND WINDOWS_BINARIES vulkan)
endif()
set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
FOLDER "GLFW3/Tests") FOLDER "GLFW3/Tests")

View File

@ -24,6 +24,7 @@
//======================================================================== //========================================================================
#include <glad/glad.h> #include <glad/glad.h>
#include <vulkan/vulkan.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <stdio.h> #include <stdio.h>
@ -61,7 +62,8 @@ static void usage(void)
printf(" -d, --debug request a debug context\n"); printf(" -d, --debug request a debug context\n");
printf(" -f, --forward require a forward-compatible context\n"); printf(" -f, --forward require a forward-compatible context\n");
printf(" -h, --help show this help\n"); printf(" -h, --help show this help\n");
printf(" -l, --list-extensions list all client API extensions\n"); printf(" -l, --list-extensions list all Vulkan and client API extensions\n");
printf(" --list-layers list all Vulkan layers\n");
printf(" -m, --major=MAJOR the major number of the required " printf(" -m, --major=MAJOR the major number of the required "
"client API version\n"); "client API version\n");
printf(" -n, --minor=MINOR the minor number of the required " printf(" -n, --minor=MINOR the minor number of the required "
@ -96,6 +98,22 @@ static void error_callback(int error, const char* description)
fprintf(stderr, "Error: %s\n", description); fprintf(stderr, "Error: %s\n", description);
} }
static const char* get_device_type_name(VkPhysicalDeviceType type)
{
if (type == VK_PHYSICAL_DEVICE_TYPE_OTHER)
return "other";
else if (type == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)
return "integrated GPU";
else if (type == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
return "discrete GPU";
else if (type == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU)
return "virtual GPU";
else if (type == VK_PHYSICAL_DEVICE_TYPE_CPU)
return "CPU";
return "unknown";
}
static const char* get_api_name(int api) static const char* get_api_name(int api)
{ {
if (api == GLFW_OPENGL_API) if (api == GLFW_OPENGL_API)
@ -146,45 +164,159 @@ static const char* get_strategy_name_glfw(int strategy)
return "unknown"; return "unknown";
} }
static void list_extensions(int api, int major, int minor) static void list_context_extensions(int api, int major, int minor)
{ {
int i; int i;
GLint count; GLint count;
const GLubyte* extensions; const GLubyte* extensions;
printf("%s context supported extensions:\n", get_api_name(api)); printf("%s context extensions:\n", get_api_name(api));
if (api == GLFW_OPENGL_API && major > 2) if (api == GLFW_OPENGL_API && major > 2)
{ {
PFNGLGETSTRINGIPROC glGetStringi =
(PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi");
if (!glGetStringi)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glGetIntegerv(GL_NUM_EXTENSIONS, &count); glGetIntegerv(GL_NUM_EXTENSIONS, &count);
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
puts((const char*) glGetStringi(GL_EXTENSIONS, i)); printf(" %s\n", (const char*) glGetStringi(GL_EXTENSIONS, i));
} }
else else
{ {
extensions = glGetString(GL_EXTENSIONS); extensions = glGetString(GL_EXTENSIONS);
while (*extensions != '\0') while (*extensions != '\0')
{ {
if (*extensions == ' ') putchar(' ');
putchar('\n');
else
putchar(*extensions);
while (*extensions != '\0' && *extensions != ' ')
{
putchar(*extensions);
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) static int valid_version(void)
{ {
@ -220,10 +352,10 @@ int main(int argc, char** argv)
{ {
int ch, api, major, minor, revision, profile; int ch, api, major, minor, revision, profile;
GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits; GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits;
int list = GLFW_FALSE; int list_extensions = GLFW_FALSE, list_layers = GLFW_FALSE;
GLFWwindow* window; GLFWwindow* window;
enum { API, BEHAVIOR, DEBUG, FORWARD, HELP, EXTENSIONS, enum { API, BEHAVIOR, DEBUG, FORWARD, HELP, EXTENSIONS, LAYERS,
MAJOR, MINOR, PROFILE, ROBUSTNESS, VERSION, MAJOR, MINOR, PROFILE, ROBUSTNESS, VERSION,
REDBITS, GREENBITS, BLUEBITS, ALPHABITS, DEPTHBITS, STENCILBITS, REDBITS, GREENBITS, BLUEBITS, ALPHABITS, DEPTHBITS, STENCILBITS,
ACCUMREDBITS, ACCUMGREENBITS, ACCUMBLUEBITS, ACCUMALPHABITS, ACCUMREDBITS, ACCUMGREENBITS, ACCUMBLUEBITS, ACCUMALPHABITS,
@ -236,6 +368,7 @@ int main(int argc, char** argv)
{ "forward", 0, NULL, FORWARD }, { "forward", 0, NULL, FORWARD },
{ "help", 0, NULL, HELP }, { "help", 0, NULL, HELP },
{ "list-extensions", 0, NULL, EXTENSIONS }, { "list-extensions", 0, NULL, EXTENSIONS },
{ "list-layers", 0, NULL, LAYERS },
{ "major", 1, NULL, MAJOR }, { "major", 1, NULL, MAJOR },
{ "minor", 1, NULL, MINOR }, { "minor", 1, NULL, MINOR },
{ "profile", 1, NULL, PROFILE }, { "profile", 1, NULL, PROFILE },
@ -318,7 +451,10 @@ int main(int argc, char** argv)
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
case 'l': case 'l':
case EXTENSIONS: case EXTENSIONS:
list = GLFW_TRUE; list_extensions = GLFW_TRUE;
break;
case LAYERS:
list_layers = GLFW_TRUE;
break; break;
case 'm': case 'm':
case MAJOR: case MAJOR:
@ -568,20 +704,10 @@ int main(int argc, char** argv)
glGetString(GL_SHADING_LANGUAGE_VERSION)); glGetString(GL_SHADING_LANGUAGE_VERSION));
} }
printf("Framebuffer:\n"); printf("%s framebuffer:\n", get_api_name(api));
if (api == GLFW_OPENGL_API && profile == GLFW_OPENGL_CORE_PROFILE) if (api == GLFW_OPENGL_API && profile == GLFW_OPENGL_CORE_PROFILE)
{ {
PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC
glGetFramebufferAttachmentParameteriv =
(PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)
glfwGetProcAddress("glGetFramebufferAttachmentParameteriv");
if (!glGetFramebufferAttachmentParameteriv)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
GL_BACK_LEFT, GL_BACK_LEFT,
GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE,
@ -646,9 +772,103 @@ int main(int argc, char** argv)
accumredbits, accumgreenbits, accumbluebits, accumalphabits, auxbuffers); accumredbits, accumgreenbits, accumbluebits, accumalphabits, auxbuffers);
} }
// Report client API extensions if (list_extensions)
if (list) list_context_extensions(api, major, minor);
list_extensions(api, major, minor);
printf("Vulkan loader: %s\n",
glfwVulkanSupported() ? "available" : "missing");
if (glfwVulkanSupported())
{
uint32_t i, re_count, pd_count;
const char** re;
VkApplicationInfo ai = {0};
VkInstanceCreateInfo ici = {0};
VkInstance instance;
VkPhysicalDevice* pd;
PFN_vkCreateInstance vkCreateInstance = (PFN_vkCreateInstance)
glfwGetInstanceProcAddress(NULL, "vkCreateInstance");
PFN_vkDestroyInstance vkDestroyInstance;
PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
re = glfwGetRequiredInstanceExtensions((int*) &re_count);
printf("Vulkan required instance extensions:");
for (i = 0; i < re_count; i++)
printf(" %s", re[i]);
putchar('\n');
if (list_extensions)
{
list_vulkan_instance_extensions();
}
if (list_layers)
list_vulkan_instance_layers();
ai.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
ai.pApplicationName = "glfwinfo";
ai.applicationVersion = GLFW_VERSION_MAJOR;
ai.pEngineName = "GLFW";
ai.engineVersion = GLFW_VERSION_MAJOR;
ai.apiVersion = VK_API_VERSION;
ici.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
ici.pApplicationInfo = &ai;
ici.enabledExtensionCount = re_count;
ici.ppEnabledExtensionNames = re;
if (vkCreateInstance(&ici, NULL, &instance) != VK_SUCCESS)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
vkDestroyInstance = (PFN_vkDestroyInstance)
glfwGetInstanceProcAddress(instance, "vkDestroyInstance");
vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices)
glfwGetInstanceProcAddress(instance, "vkEnumeratePhysicalDevices");
vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties)
glfwGetInstanceProcAddress(instance, "vkGetPhysicalDeviceProperties");
if (vkEnumeratePhysicalDevices(instance, &pd_count, NULL) != VK_SUCCESS)
{
vkDestroyInstance(instance, NULL);
glfwTerminate();
exit(EXIT_FAILURE);
}
pd = calloc(pd_count, sizeof(VkPhysicalDevice));
if (vkEnumeratePhysicalDevices(instance, &pd_count, pd) != VK_SUCCESS)
{
free(pd);
vkDestroyInstance(instance, NULL);
glfwTerminate();
exit(EXIT_FAILURE);
}
for (i = 0; i < pd_count; i++)
{
VkPhysicalDeviceProperties pdp;
vkGetPhysicalDeviceProperties(pd[i], &pdp);
printf("Vulkan %s device: \"%s\"\n",
get_device_type_name(pdp.deviceType),
pdp.deviceName);
if (list_extensions)
list_vulkan_device_extensions(instance, pd[i]);
if (list_layers)
list_vulkan_device_layers(instance, pd[i]);
}
free(pd);
vkDestroyInstance(instance, NULL);
}
glfwTerminate(); glfwTerminate();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);

2246
tests/vulkan.c Normal file

File diff suppressed because it is too large Load Diff