diff options
| author | Lizzy Fleckenstein <lizzy@vlhl.dev> | 2026-04-12 21:37:16 +0200 |
|---|---|---|
| committer | Lizzy Fleckenstein <lizzy@vlhl.dev> | 2026-04-12 21:37:16 +0200 |
| commit | 165c94e3c1742dabaac73b20662e4d4c823dd310 (patch) | |
| tree | 957d80074c5d0c62db8a92cc97b26646280f4b32 /tools/Vulkan-Tools/cube | |
| parent | 4fd35dd290c212ed716adeb3be4dea71775e00dd (diff) | |
| download | usermoji-165c94e3c1742dabaac73b20662e4d4c823dd310.tar.xz | |
mkcube: use animtool
Diffstat (limited to 'tools/Vulkan-Tools/cube')
43 files changed, 0 insertions, 13424 deletions
diff --git a/tools/Vulkan-Tools/cube/BUILD.gn b/tools/Vulkan-Tools/cube/BUILD.gn deleted file mode 100644 index 502e3a50..00000000 --- a/tools/Vulkan-Tools/cube/BUILD.gn +++ /dev/null @@ -1,185 +0,0 @@ -# Copyright (C) 2025 The Fuchsia Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -assert(is_fuchsia, "This build file works on Fuchsia GN build only.") - -import("//build/compiled_action.gni") -import("//build/components.gni") -import("//build_overrides/vulkan_tools.gni") -import("//src/lib/vulkan/layers.gni") - -group("cube") { - testonly = true - deps = [ - ":vkcube-on-fb", - ":vkcube-on-fb-protected", - ":vkcube-on-scenic", - ] -} - -fuchsia_test_component("vkcube-on-fb-component") { - component_name = "vkcube-on-fb" - deps = [ - ":vkcube", - "//src/lib/vulkan/swapchain:image_pipe_swapchain_fb_layer", - "//src/lib/vulkan/validation_layers", - ] - manifest = "fuchsia/meta/vkcube-on-fb.cml" - test_type = "system" -} - -fuchsia_test_package("vkcube-on-fb") { - test_components = [ ":vkcube-on-fb-component" ] - test_specs = { - # vkcube runs forever, so only run manually. - environments = [] - } -} - -fuchsia_test_component("vkcube-on-fb-protected-component") { - deps = [ - ":vkcube", - "//src/lib/vulkan/swapchain:image_pipe_swapchain_fb_layer", - "//src/lib/vulkan/validation_layers", - ] - - manifest = "fuchsia/meta/vkcube-on-fb-protected.cml" - test_type = "system" -} - -fuchsia_test_package("vkcube-on-fb-protected") { - test_components = [ ":vkcube-on-fb-protected-component" ] - test_specs = { - # vkcube runs forever, so only run manually. - environments = [] - } -} - -fuchsia_component("vkcube-on-scenic-component") { - component_name = "vkcube-on-scenic" - deps = [ - ":vkcube", - "//src/lib/vulkan/swapchain:image_pipe_swapchain_layer", - "//src/lib/vulkan/validation_layers", - ] - - manifest = "fuchsia/meta/vkcube-on-scenic.cml" -} - -fuchsia_component("vkcube-on-scenic-protected-component") { - component_name = "vkcube-on-scenic-protected" - deps = [ - ":vkcube", - "//src/lib/vulkan/swapchain:image_pipe_swapchain_layer", - "//src/lib/vulkan/validation_layers", - ] - - manifest = "fuchsia/meta/vkcube-on-scenic-protected.cml" -} - -fuchsia_package("vkcube-on-scenic") { - deps = [ - ":vkcube-on-scenic-component", - ":vkcube-on-scenic-protected-component", - ] -} - -config("cube_config") { - cube_frag_inc = "$target_gen_dir/cube.frag.inc" - cube_vert_inc = "$target_gen_dir/cube.vert.inc" - - cube_frag_inc_rebased = rebase_path(cube_frag_inc, root_build_dir) - cube_vert_inc_rebased = rebase_path(cube_vert_inc, root_build_dir) - - inputs = [ - cube_frag_inc, - cube_vert_inc, - ] - - defines = [ - "CUBE_FRAG_INC=\"$cube_frag_inc_rebased\"", - "CUBE_VERT_INC=\"$cube_vert_inc_rebased\"", - "VULKAN_HPP_NO_NODISCARD_WARNINGS", - ] - - include_dirs = [ root_build_dir ] - - cflags = [ "-Wno-implicit-int-float-conversion" ] -} - -executable("vkcube") { - defines = [] - if (defined(texture_ppm_h)) { - path = rebase_path(texture_ppm_h, root_build_dir) - defines += [ "TEXTURE_PPM_H=\"$path\"" ] - } - - sources = [ - "cube.cpp", - "fuchsia/flatland_view.cpp", - "fuchsia/flatland_view.h", - ] - - configs += [ - ":cube_config", - ] - - deps = [ - ":glslang_frag", - ":glslang_vert", - "//sdk/fidl/fuchsia.ui.app:fuchsia.ui.app_cpp", - "//sdk/fidl/fuchsia.ui.composition:fuchsia.ui.composition_cpp", - "//sdk/fidl/fuchsia.ui.views:fuchsia.ui.views_cpp", - "//sdk/lib/async-loop:async-loop-cpp", - "//sdk/lib/component/incoming/cpp", - "//sdk/lib/component/outgoing/cpp", - "//sdk/lib/syslog/cpp", - "//sdk/lib/ui/scenic/cpp", - "//third_party/Vulkan-Headers/src:vulkan_headers", - "//third_party/Vulkan-Loader:libvulkan", - "//zircon/system/ulib/syslog", - ] -} - -compiled_action("glslang_frag") { - tool = "//third_party/glslang:glslang_validator" - outputs = [ "$target_gen_dir/cube.frag.inc" ] - - sources = [ "cube.frag" ] - - args = [ - "--quiet", - "-V", - "-x", - "-o", - rebase_path("$target_gen_dir/cube.frag.inc", root_build_dir), - rebase_path("cube.frag", root_build_dir), - ] -} - -compiled_action("glslang_vert") { - tool = "//third_party/glslang:glslang_validator" - outputs = [ "$target_gen_dir/cube.vert.inc" ] - - sources = [ "cube.vert" ] - - args = [ - "--quiet", - "-V", - "-x", - "-o", - rebase_path("$target_gen_dir/cube.vert.inc", root_build_dir), - rebase_path("cube.vert", root_build_dir), - ] -} diff --git a/tools/Vulkan-Tools/cube/CMakeLists.txt b/tools/Vulkan-Tools/cube/CMakeLists.txt deleted file mode 100644 index 7c9b778a..00000000 --- a/tools/Vulkan-Tools/cube/CMakeLists.txt +++ /dev/null @@ -1,371 +0,0 @@ -# ~~~ -# Copyright (c) 2018 Valve Corporation -# Copyright (c) 2018 LunarG, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ~~~ - -if(APPLE) - option(APPLE_USE_SYSTEM_ICD "Use system Vulkan ICD discovery instead of bundling MoltenVK" OFF) - - if(APPLE_USE_SYSTEM_ICD) - message(STATUS "Using system Vulkan loader for ICD discovery") - else() - set(MOLTENVK_REPO_ROOT "MOLTENVK-NOTFOUND" CACHE PATH "Absolute path to a MoltenVK repo directory") - if(NOT MOLTENVK_REPO_ROOT) - message(FATAL_ERROR "Must define location of MoltenVK repo -- see BUILD.md") - endif() - message(STATUS "Using MoltenVK repo location at ${MOLTENVK_REPO_ROOT}") - - # Source for the MoltenVK ICD library and JSON file - set(MOLTENVK_DIR ${MOLTENVK_REPO_ROOT}) - - # MoltenVK JSON File - execute_process(COMMAND mkdir -p ${PROJECT_BINARY_DIR}/staging-json) - execute_process(COMMAND sed -e "/\"library_path\":/s$:[[:space:]]*\"[[:space:]]*[\\.\\/]*$: \"..\\/..\\/..\\/Frameworks\\/$" - ${MOLTENVK_DIR}/MoltenVK/icd/MoltenVK_icd.json - OUTPUT_FILE ${PROJECT_BINARY_DIR}/staging-json/MoltenVK_icd.json) - - # ~~~ - # Modify the ICD JSON file to adjust the library path. - # The ICD JSON file goes in the Resources/vulkan/icd.d directory, so adjust the - # library_path to the relative path to the Frameworks directory in the bundle. - # The regex does: substitute ':<whitespace>"<whitespace><all occurences of . and />' with: - # ': "../../../Frameworks/' - # ~~~ - add_custom_target(MoltenVK_icd-staging-json ALL - COMMAND mkdir -p ${PROJECT_BINARY_DIR}/staging-json - COMMAND sed -e "/\"library_path\":/s$:[[:space:]]*\"[[:space:]]*[\\.\\/]*$: \"..\\/..\\/..\\/Frameworks\\/$" - ${MOLTENVK_DIR}/MoltenVK/icd/MoltenVK_icd.json > ${PROJECT_BINARY_DIR}/staging-json/MoltenVK_icd.json - VERBATIM - DEPENDS "${MOLTENVK_DIR}/MoltenVK/icd/MoltenVK_icd.json" - ) - set_source_files_properties(${PROJECT_BINARY_DIR}/staging-json/MoltenVK_icd.json PROPERTIES GENERATED TRUE) - endif() - - find_library(COCOA NAMES Cocoa) - - # Locate Interface Builder Tool, needed to build things like Storyboards outside of Xcode. - if(NOT XCODE) - # Make sure we can find the 'ibtool' program. If we can NOT find it we skip generation of this project. - find_program(IBTOOL ibtool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin") - if(${IBTOOL} STREQUAL "IBTOOL-NOTFOUND") - message(SEND_ERROR "ibtool can not be found and is needed to compile the .xib files. " - "It should have been installed with the Apple developer tools. " - "The default system paths were searched in addition to ${OSX_DEVELOPER_ROOT}/usr/bin.") - endif() - endif() -endif() - -if(ANDROID OR APPLE) - set(WSI_DISPLAY_DEFAULT_SETTING "OFF") -else() - set(WSI_DISPLAY_DEFAULT_SETTING "ON") -endif() - -option(BUILD_WSI_DISPLAY_SUPPORT "Build DISPLAY WSI support" ${WSI_DISPLAY_DEFAULT_SETTING}) - -if (CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU") - option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" ON) - option(BUILD_WSI_XLIB_SUPPORT "Build Xlib WSI support" ON) - option(BUILD_WSI_WAYLAND_SUPPORT "Build Wayland WSI support" ON) - option(BUILD_WSI_DIRECTFB_SUPPORT "Build DirectFB WSI support" OFF) - - find_package(PkgConfig REQUIRED QUIET) # Use PkgConfig to find Linux system libraries - - if(BUILD_WSI_XCB_SUPPORT) - pkg_check_modules(XCB REQUIRED QUIET IMPORTED_TARGET xcb) - pkg_get_variable(XCB_INCLUDE_DIRS xcb includedir) - message(DEBUG "XCB_INCLUDE_DIRS = ${XCB_INCLUDE_DIRS}") - endif() - - if(BUILD_WSI_XLIB_SUPPORT) - pkg_check_modules(X11 REQUIRED QUIET IMPORTED_TARGET x11) - pkg_get_variable(XLIB_INCLUDE_DIRS x11 includedir) - message(DEBUG "XLIB_INCLUDE_DIRS = ${XLIB_INCLUDE_DIRS}") - endif() - - if(BUILD_WSI_WAYLAND_SUPPORT) - pkg_check_modules(WAYLAND_CLIENT REQUIRED IMPORTED_TARGET wayland-client) - pkg_get_variable(WAYLAND_INCLUDE_DIRS wayland-client includedir) - - pkg_check_modules(WAYLAND_SCANNER REQUIRED wayland-scanner) - pkg_get_variable(WAYLAND_SCANNER_EXECUTABLE wayland-scanner wayland_scanner) - message(DEBUG "WAYLAND_SCANNER_EXECUTABLE = ${WAYLAND_SCANNER_EXECUTABLE}") - - pkg_get_variable(WAYLAND_CLIENT_PATH wayland-client pkgdatadir) - message(DEBUG "WAYLAND_CLIENT_PATH = ${WAYLAND_CLIENT_PATH}") - set(WAYLAND_CODE_PROTOCOL ${WAYLAND_CLIENT_PATH}/wayland.xml) - - pkg_check_modules(WAYLAND_PROTOCOLS REQUIRED wayland-protocols) - pkg_get_variable(WAYLAND_PROTOCOLS_PATH wayland-protocols pkgdatadir) - message(DEBUG "WAYLAND_PROTOCOLS_PATH = ${WAYLAND_PROTOCOLS_PATH}") - set(XDG_SHELL_PROTOCOL ${WAYLAND_PROTOCOLS_PATH}/stable/xdg-shell/xdg-shell.xml) - - add_custom_command(COMMENT "Generating wayland client protocol dispatch data" - OUTPUT wayland-client.c - COMMAND ${WAYLAND_SCANNER_EXECUTABLE} - private-code - ${WAYLAND_CODE_PROTOCOL} - ${CMAKE_CURRENT_BINARY_DIR}/wayland-client.c - MAIN_DEPENDENCY ${WAYLAND_CODE_PROTOCOL} - DEPENDS ${WAYLAND_CODE_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE}) - - add_custom_command(COMMENT "Generating xdg-shell protocol dispatch data" - OUTPUT xdg-shell-code.c - COMMAND ${WAYLAND_SCANNER_EXECUTABLE} - private-code - ${XDG_SHELL_PROTOCOL} - ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-code.c - MAIN_DEPENDENCY ${XDG_SHELL_PROTOCOL} - DEPENDS ${XDG_SHELL_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE}) - add_custom_command(COMMENT "Generating xdg-shell protocol header" - OUTPUT xdg-shell-client-header.h - COMMAND ${WAYLAND_SCANNER_EXECUTABLE} - client-header - ${XDG_SHELL_PROTOCOL} - ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-header.h - MAIN_DEPENDENCY ${XDG_SHELL_PROTOCOL} - DEPENDS ${XDG_SHELL_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE}) - - set(XDG_DECORATION_PROTOCOL ${WAYLAND_PROTOCOLS_PATH}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml) - add_custom_command(COMMENT "Generating xdg-decoration protocol dispatch data" - OUTPUT xdg-decoration-code.c - COMMAND ${WAYLAND_SCANNER_EXECUTABLE} - private-code - ${XDG_DECORATION_PROTOCOL} - ${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-code.c - MAIN_DEPENDENCY ${XDG_DECORATION_PROTOCOL} - DEPENDS ${XDG_DECORATION_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE}) - add_custom_command(COMMENT "Generating xdg-decoration protocol header" - OUTPUT xdg-decoration-client-header.h - COMMAND ${WAYLAND_SCANNER_EXECUTABLE} - client-header - ${XDG_DECORATION_PROTOCOL} - ${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h - MAIN_DEPENDENCY ${XDG_DECORATION_PROTOCOL} - DEPENDS ${XDG_DECORATION_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE}) - - set(WAYLAND_ADDITIONAL_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/wayland-client.c - ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-code.c - ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-header.h - ${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-code.c - ${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h) - endif() - - if(BUILD_WSI_DIRECTFB_SUPPORT) - pkg_check_modules(DirectFB REQUIRED QUIET IMPORTED_TARGET directfb) - endif() -endif() - -if(BUILD_WSI_DISPLAY_SUPPORT) - list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_DISPLAY_KHR) -endif() - -if(WIN32) - add_definitions(-DWIN32_LEAN_AND_MEAN -DNOMINMAX) - list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_WIN32_KHR) -elseif(ANDROID) - list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_ANDROID_KHR) -elseif(APPLE) - list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_METAL_EXT) -elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU") - if(BUILD_WSI_XCB_SUPPORT) - list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_XCB_KHR) - endif() - if(BUILD_WSI_XLIB_SUPPORT) - list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_XLIB_KHR) - endif() - if(BUILD_WSI_WAYLAND_SUPPORT) - list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_WAYLAND_KHR) - endif() - if(BUILD_WSI_DIRECTFB_SUPPORT) - list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_DIRECTFB_EXT) - endif() - link_libraries(${API_LOWERCASE} m) -else() - message(FATAL_ERROR "Unsupported Platform!") -endif() - -if(NOT DEFINED ENABLED_CUBE_PLATFORMS) - message(FATAL_ERROR "There are no supported WSI platforms on this system, vkcube requires a WSI platform be available to be able to render its output") -endif() - -if (COMPILE_CUBE_SHADERS) - # Try to find glslang in system paths or in an SDK if the VULKAN_SDK env-var is set - find_program(GLSLANG_VALIDATOR names glslang glslangValidator HINTS $ENV{GLSLANG_INSTALL_DIR} $ENV{VULKAN_SDK}/bin $ENV{VULKAN_SDK}/Bin) - - add_custom_command(COMMENT "Compiling cube vertex shader" - OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/cube.vert.inc - COMMAND ${GLSLANG_VALIDATOR} -V -x -o ${CMAKE_CURRENT_SOURCE_DIR}/cube.vert.inc - ${PROJECT_SOURCE_DIR}/cube/cube.vert - MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/cube/cube.vert - DEPENDS ${PROJECT_SOURCE_DIR}/cube/cube.vert ${GLSLANG_VALIDATOR}) - add_custom_command(COMMENT "Compiling cube fragment shader" - OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/cube.frag.inc - COMMAND ${GLSLANG_VALIDATOR} -V -x -o ${CMAKE_CURRENT_SOURCE_DIR}/cube.frag.inc - ${PROJECT_SOURCE_DIR}/cube/cube.frag - MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/cube/cube.frag - DEPENDS ${PROJECT_SOURCE_DIR}/cube/cube.frag ${GLSLANG_VALIDATOR}) -endif() - -if(WIN32) - add_compile_definitions(_CRT_SECURE_NO_WARNINGS) - # vkcube / vkcube make use of M_PI and various other math defines. - add_compile_definitions(_USE_MATH_DEFINES) -endif() - - -# On Ubuntu 20.04, it was found that the validation layers fail to launch in vkcube & vkcubepp due to -# a missing dependency on libpthread. While newer Ubuntu versions use a glibc version where libpthread -# is integrated into libc, older ubuntu's do not so we need to link threads directly in order for -# validation layers to be loadable. -if (CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU") - find_package(Threads REQUIRED) -endif() - -# ---------------------------------------------------------------------------- -# vkcube - -if(APPLE) - add_subdirectory(macOS/cube) -elseif (ANDROID) - add_library(vkcube MODULE) - - target_sources(vkcube PRIVATE cube.c) - - add_subdirectory(android) - -elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU") - add_executable(vkcube) - target_sources(vkcube PRIVATE - cube.c - ${PROJECT_SOURCE_DIR}/cube/cube.vert - ${PROJECT_SOURCE_DIR}/cube/cube.frag - cube.vert.inc - cube.frag.inc - ) - target_link_libraries(vkcube Threads::Threads) - if(BUILD_WSI_XCB_SUPPORT) - target_sources(vkcube PRIVATE xcb_loader.h) - target_include_directories(vkcube PRIVATE ${xcb_INCLUDE_DIRS}) - endif() - if(BUILD_WSI_XLIB_SUPPORT) - target_sources(vkcube PRIVATE xlib_loader.h) - target_include_directories(vkcube PRIVATE ${XLIB_INCLUDE_DIRS}) - endif() - if(BUILD_WSI_WAYLAND_SUPPORT) - target_include_directories(vkcube PRIVATE ${WAYLAND_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}) - target_sources(vkcube PRIVATE PRIVATE ${WAYLAND_ADDITIONAL_SOURCES}) - endif() - if(BUILD_WSI_DIRECTFB_SUPPORT) - target_link_libraries(vkcube PkgConfig::DirectFB) - endif() - include(CheckLibraryExists) - CHECK_LIBRARY_EXISTS("rt" clock_gettime "" NEED_RT) - if (NEED_RT) - target_link_libraries(vkcube rt) - endif() -elseif(WIN32) - add_executable(vkcube WIN32) - target_sources(vkcube PRIVATE - cube.c - ${PROJECT_SOURCE_DIR}/cube/cube.vert - ${PROJECT_SOURCE_DIR}/cube/cube.frag - cube.vert.inc - cube.frag.inc - ) -else() - message(FATAL_ERROR "Unsupported Platform!") -endif() - -target_compile_definitions(vkcube PRIVATE ${ENABLED_CUBE_PLATFORMS}) -target_include_directories(vkcube PRIVATE .) -target_link_libraries(vkcube ${CMAKE_DL_LIBS} Vulkan::Headers) - -if (ANDROID) - install(TARGETS vkcube DESTINATION ${CMAKE_INSTALL_LIBDIR}) -elseif(APPLE) - install( - TARGETS vkcube - # Install runtime dependencies like the Vulkan::Loader so the app is self-contained - RUNTIME_DEPENDENCIES DESTINATION "cube/vkcube.app/Contents/Frameworks/" - BUNDLE DESTINATION "cube" - ) - set_target_properties(vkcube PROPERTIES - INSTALL_RPATH @executable_path/../Frameworks - ) -else() - install(TARGETS vkcube) -endif() - -if (ANDROID) - return() -endif() - -# ---------------------------------------------------------------------------- -# vkcubepp - -if(APPLE) - add_subdirectory(macOS/cubepp) -elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU") - add_executable(vkcubepp - cube.cpp - ${PROJECT_SOURCE_DIR}/cube/cube.vert - ${PROJECT_SOURCE_DIR}/cube/cube.frag - cube.vert.inc - cube.frag.inc) - target_link_libraries(vkcubepp Threads::Threads) - - if(BUILD_WSI_XCB_SUPPORT) - target_sources(vkcubepp PRIVATE xcb_loader.h) - target_include_directories(vkcubepp PRIVATE ${xcb_INCLUDE_DIRS}) - endif() - if(BUILD_WSI_XLIB_SUPPORT) - target_sources(vkcubepp PRIVATE xlib_loader.h) - target_include_directories(vkcubepp PRIVATE ${XLIB_INCLUDE_DIRS}) - endif() - if(BUILD_WSI_WAYLAND_SUPPORT) - target_include_directories(vkcubepp PRIVATE ${WAYLAND_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}) - target_sources(vkcubepp PRIVATE ${WAYLAND_ADDITIONAL_SOURCES}) - endif() - if(BUILD_WSI_DIRECTFB_SUPPORT) - target_link_libraries(vkcubepp PkgConfig::DirectFB) - endif() -else() - add_executable(vkcubepp - WIN32 - cube.cpp - ${PROJECT_SOURCE_DIR}/cube/cube.vert - ${PROJECT_SOURCE_DIR}/cube/cube.frag - cube.vert.inc - cube.frag.inc) -endif() - -target_include_directories(vkcubepp PRIVATE .) -target_compile_definitions(vkcubepp PRIVATE ${ENABLED_CUBE_PLATFORMS}) -target_link_libraries(vkcubepp ${CMAKE_DL_LIBS} Vulkan::Headers) - -if(APPLE) - install( - TARGETS vkcubepp - # Install runtime dependencies like the Vulkan::Loader so the app is self-contained - RUNTIME_DEPENDENCIES DESTINATION "cube/vkcubepp.app/Contents/Frameworks/" - BUNDLE DESTINATION "cube" - ) - set_target_properties(vkcubepp PROPERTIES - INSTALL_RPATH @executable_path/../Frameworks - ) -else() - install(TARGETS vkcubepp) -endif() diff --git a/tools/Vulkan-Tools/cube/android/AndroidManifest.xml b/tools/Vulkan-Tools/cube/android/AndroidManifest.xml deleted file mode 100644 index fbec106d..00000000 --- a/tools/Vulkan-Tools/cube/android/AndroidManifest.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.VkCube" android:versionCode="1" android:versionName="1.0"> - - <!-- Allow this app to read and write files (for use by tracing libraries). --> - <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> - <uses-permission android:name="android.permission.INTERNET"/> - - <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="23"/> - - <!-- This .apk has no Java code itself, so set hasCode to false. --> - <application android:label="VkCube" android:hasCode="false" android:debuggable='true'> - - <!-- Our activity is the built-in NativeActivity framework class. - This will take care of integrating with our NDK code. --> - <activity android:name="android.app.NativeActivity" android:label="VkCube" android:exported="true"> - <!-- Tell NativeActivity the name of or .so --> - <meta-data android:name="android.app.lib_name" android:value="VkCube"/> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - </application> - -</manifest> diff --git a/tools/Vulkan-Tools/cube/android/CMakeLists.txt b/tools/Vulkan-Tools/cube/android/CMakeLists.txt deleted file mode 100644 index af607a55..00000000 --- a/tools/Vulkan-Tools/cube/android/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# ~~~ -# Copyright (c) 2023 Valve Corporation -# Copyright (c) 2023 LunarG, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ~~~ - -target_sources(vkcube PRIVATE - android_util.cpp - android_util.h -) - -target_include_directories(vkcube PRIVATE - . -) - -set_directory_properties(PROPERTIES "COMPILE_OPTIONS" "") # Disable compiler warnings for android glue - -set(native_app_glue_dir "${CMAKE_ANDROID_NDK}/sources/android/native_app_glue") - -if (NOT EXISTS ${native_app_glue_dir}) - message(FATAL_ERROR "Couldn't find Android Native Glue directory!") -endif() - -# https://stackoverflow.com/questions/57189936/compiling-native-app-glue-c-results-in-an-invalid-library-file/76963564#76963564 -add_library(android_glue OBJECT) - -target_include_directories(android_glue PUBLIC ${native_app_glue_dir}) -target_sources(android_glue PRIVATE - ${native_app_glue_dir}/android_native_app_glue.c - ${native_app_glue_dir}/android_native_app_glue.h -) - -set_target_properties(vkcube PROPERTIES OUTPUT_NAME "VkCube") - -target_link_libraries(vkcube - android_glue - log - android -) - -# https://stackoverflow.com/questions/76631917/cmake-how-to-install-shared-stl-libraries-for-android/76656492#76656492 -if ("${CMAKE_ANDROID_STL_TYPE}" MATCHES "shared") - file(READ "${CMAKE_ANDROID_NDK}/meta/abis.json" JSON_FILE) - string(JSON TRIPLE GET "${JSON_FILE}" "${CMAKE_ANDROID_ARCH_ABI}" "triple") - install(FILES "${CMAKE_SYSROOT}/usr/lib/${TRIPLE}/libc++_shared.so" DESTINATION "${CMAKE_INSTALL_LIBDIR}") -endif() diff --git a/tools/Vulkan-Tools/cube/android/android_util.cpp b/tools/Vulkan-Tools/cube/android/android_util.cpp deleted file mode 100644 index 173e8ab8..00000000 --- a/tools/Vulkan-Tools/cube/android/android_util.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2016 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Relicensed from the WTFPL (http://www.wtfpl.net/faq/). - */ - -#include "android_util.h" -#include <android_native_app_glue.h> -#include <cassert> -#include <cstring> -#include <vector> -#include <string> -#include <sstream> -#include <stdlib.h> - -extern "C" { - -// Convert Intents to arg list, returning argc and argv -// Note that this C routine mallocs memory that the caller must free -char **get_args(struct android_app *app, const char *intent_extra_data_key, const char *appTag, int *count) { - std::vector<std::string> args; - JavaVM &vm = *app->activity->vm; - JNIEnv *p_env; - if (vm.AttachCurrentThread(&p_env, nullptr) != JNI_OK) return nullptr; - - JNIEnv &env = *p_env; - jobject activity = app->activity->clazz; - jmethodID get_intent_method = env.GetMethodID(env.GetObjectClass(activity), "getIntent", "()Landroid/content/Intent;"); - jobject intent = env.CallObjectMethod(activity, get_intent_method); - jmethodID get_string_extra_method = - env.GetMethodID(env.GetObjectClass(intent), "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;"); - jvalue get_string_extra_args; - get_string_extra_args.l = env.NewStringUTF(intent_extra_data_key); - jstring extra_str = static_cast<jstring>(env.CallObjectMethodA(intent, get_string_extra_method, &get_string_extra_args)); - - std::string args_str; - if (extra_str) { - const char *extra_utf = env.GetStringUTFChars(extra_str, nullptr); - args_str = extra_utf; - env.ReleaseStringUTFChars(extra_str, extra_utf); - env.DeleteLocalRef(extra_str); - } - - env.DeleteLocalRef(get_string_extra_args.l); - env.DeleteLocalRef(intent); - vm.DetachCurrentThread(); - - // split args_str - std::stringstream ss(args_str); - std::string arg; - while (std::getline(ss, arg, ' ')) { - if (!arg.empty()) args.push_back(arg); - } - - // Convert our STL results to C friendly constructs - assert(count != nullptr); - *count = args.size() + 1; - char **vector = (char **)malloc(*count * sizeof(char *)); - const char *appName = appTag ? appTag : (const char *)"appTag"; - - vector[0] = (char *)malloc(strlen(appName) * sizeof(char)); - strcpy(vector[0], appName); - - for (uint32_t i = 0; i < args.size(); i++) { - vector[i + 1] = (char *)malloc(strlen(args[i].c_str()) * sizeof(char)); - strcpy(vector[i + 1], args[i].c_str()); - } - - return vector; -} - -} // extern "C" diff --git a/tools/Vulkan-Tools/cube/android/android_util.h b/tools/Vulkan-Tools/cube/android/android_util.h deleted file mode 100644 index e8966458..00000000 --- a/tools/Vulkan-Tools/cube/android/android_util.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2016 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Relicensed from the WTFPL (http://www.wtfpl.net/faq/). - */ - -#ifndef ANDROID_UTIL_H -#define ANDROID_UTIL_H - -#ifdef __cplusplus -extern "C" { -#endif - -char **get_args(struct android_app *app, const char *intent_extra_data_key, const char *appTag, int *count); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/tools/Vulkan-Tools/cube/cube.c b/tools/Vulkan-Tools/cube/cube.c deleted file mode 100644 index a5854c5f..00000000 --- a/tools/Vulkan-Tools/cube/cube.c +++ /dev/null @@ -1,5235 +0,0 @@ -/* - * Copyright (c) 2015-2019 The Khronos Group Inc. - * Copyright (c) 2015-2019 Valve Corporation - * Copyright (c) 2015-2019 LunarG, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Author: Chia-I Wu <olv@lunarg.com> - * Author: Courtney Goeltzenleuchter <courtney@LunarG.com> - * Author: Ian Elliott <ian@LunarG.com> - * Author: Ian Elliott <ianelliott@google.com> - * Author: Jon Ashburn <jon@lunarg.com> - * Author: Gwan-gyeong Mun <elongbug@gmail.com> - * Author: Tony Barbour <tony@LunarG.com> - * Author: Bill Hollings <bill.hollings@brenwill.com> - */ - -#define _GNU_SOURCE -#include <ctype.h> -#include <stdio.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <stdbool.h> -#include <assert.h> -#include <signal.h> -#if defined(VK_USE_PLATFORM_SCREEN_QNX) -#include <errno.h> -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) -#include "xlib_loader.h" -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) -#include "xcb_loader.h" -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -#include <linux/input.h> -#include "wayland_loader.h" -#endif - -#ifdef _WIN32 -#ifdef _MSC_VER -#pragma comment(linker, "/subsystem:windows") -#endif // MSVC -#define APP_NAME_STR_LEN 80 -#endif // _WIN32 - -#include "cube_functions.h" - -#include <vulkan/vulkan.h> - -#include "linmath.h" -#include "object_type_string_helper.h" - -#include "gettime.h" -#include "inttypes.h" -#define MILLION 1000000L -#define BILLION 1000000000L - -#define DEMO_TEXTURE_COUNT 1 -#define APP_SHORT_NAME "vkcube" -#define APP_LONG_NAME "Vulkan Cube" - -// Allow a maximum of two outstanding presentation operations. -#define FRAME_LAG 2 -// Need to know how big of a buffer of swapchain images, image views, and semaphores are needed -#define MAX_SWAPCHAIN_IMAGE_COUNT 8 - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) - -#if defined(NDEBUG) && defined(__GNUC__) -#define U_ASSERT_ONLY __attribute__((unused)) -#else -#define U_ASSERT_ONLY -#endif - -#if defined(__GNUC__) -#define UNUSED __attribute__((unused)) -#else -#define UNUSED -#endif - -#ifdef _WIN32 -bool in_callback = false; -#define ERR_EXIT(err_msg, err_class) \ - do { \ - if (!demo->suppress_popups) MessageBox(NULL, err_msg, err_class, MB_OK); \ - exit(1); \ - } while (0) -void DbgMsg(char *fmt, ...) { - va_list va; - va_start(va, fmt); - vprintf(fmt, va); - va_end(va); - fflush(stdout); -} - -#elif defined __ANDROID__ -#include <android/log.h> -#define ERR_EXIT(err_msg, err_class) \ - do { \ - ((void)__android_log_print(ANDROID_LOG_INFO, "Vulkan Cube", err_msg)); \ - exit(1); \ - } while (0) -#ifdef VARARGS_WORKS_ON_ANDROID -void DbgMsg(const char *fmt, ...) { - va_list va; - va_start(va, fmt); - __android_log_print(ANDROID_LOG_INFO, "Vulkan Cube", fmt, va); - va_end(va); -} -#else // VARARGS_WORKS_ON_ANDROID -#define DbgMsg(fmt, ...) \ - do { \ - ((void)__android_log_print(ANDROID_LOG_INFO, "Vulkan Cube", fmt, ##__VA_ARGS__)); \ - } while (0) -#endif // VARARGS_WORKS_ON_ANDROID -#else -#define ERR_EXIT(err_msg, err_class) \ - do { \ - printf("%s\n", err_msg); \ - fflush(stdout); \ - exit(1); \ - } while (0) -void DbgMsg(char *fmt, ...) { - va_list va; - va_start(va, fmt); - vprintf(fmt, va); - va_end(va); - fflush(stdout); -} -#endif - -/* - * structure to track all objects related to a texture. - */ -struct texture_object { - VkSampler sampler; - - VkImage image; - VkBuffer buffer; - VkImageLayout imageLayout; - - VkMemoryAllocateInfo mem_alloc; - VkDeviceMemory mem; - VkImageView view; - int32_t tex_width, tex_height; -}; - -static int validation_error = 0; - -struct vktexcube_vs_uniform { - // Must start with MVP - float mvp[4][4]; - float position[12 * 3][4]; - float attr[12 * 3][4]; -}; - -//-------------------------------------------------------------------------------------- -// Mesh and VertexFormat Data -//-------------------------------------------------------------------------------------- -// clang-format off -static const float g_vertex_buffer_data[] = { - -1.0f,-1.0f,-1.0f, // -X side - -1.0f,-1.0f, 1.0f, - -1.0f, 1.0f, 1.0f, - -1.0f, 1.0f, 1.0f, - -1.0f, 1.0f,-1.0f, - -1.0f,-1.0f,-1.0f, - - -1.0f,-1.0f,-1.0f, // -Z side - 1.0f, 1.0f,-1.0f, - 1.0f,-1.0f,-1.0f, - -1.0f,-1.0f,-1.0f, - -1.0f, 1.0f,-1.0f, - 1.0f, 1.0f,-1.0f, - - -1.0f,-1.0f,-1.0f, // -Y side - 1.0f,-1.0f,-1.0f, - 1.0f,-1.0f, 1.0f, - -1.0f,-1.0f,-1.0f, - 1.0f,-1.0f, 1.0f, - -1.0f,-1.0f, 1.0f, - - -1.0f, 1.0f,-1.0f, // +Y side - -1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, - -1.0f, 1.0f,-1.0f, - 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f,-1.0f, - - 1.0f, 1.0f,-1.0f, // +X side - 1.0f, 1.0f, 1.0f, - 1.0f,-1.0f, 1.0f, - 1.0f,-1.0f, 1.0f, - 1.0f,-1.0f,-1.0f, - 1.0f, 1.0f,-1.0f, - - -1.0f, 1.0f, 1.0f, // +Z side - -1.0f,-1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, - -1.0f,-1.0f, 1.0f, - 1.0f,-1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, -}; - -static const float g_uv_buffer_data[] = { - 0.0f, 1.0f, // -X side - 1.0f, 1.0f, - 1.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 0.0f, - 0.0f, 1.0f, - - 1.0f, 1.0f, // -Z side - 0.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, - 1.0f, 0.0f, - 0.0f, 0.0f, - - 1.0f, 0.0f, // -Y side - 1.0f, 1.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 0.0f, 0.0f, - - 1.0f, 0.0f, // +Y side - 0.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, - - 1.0f, 0.0f, // +X side - 0.0f, 0.0f, - 0.0f, 1.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, - 1.0f, 0.0f, - - 0.0f, 0.0f, // +Z side - 0.0f, 1.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, - 1.0f, 0.0f, -}; -// clang-format on - -void dumpMatrix(const char *note, mat4x4 MVP) { - int i; - - printf("%s: \n", note); - for (i = 0; i < 4; i++) { - printf("%f, %f, %f, %f\n", MVP[i][0], MVP[i][1], MVP[i][2], MVP[i][3]); - } - printf("\n"); - fflush(stdout); -} - -void dumpVec4(const char *note, vec4 vector) { - printf("%s: \n", note); - printf("%f, %f, %f, %f\n", vector[0], vector[1], vector[2], vector[3]); - printf("\n"); - fflush(stdout); -} - -char const *to_string(VkPhysicalDeviceType const type) { - switch (type) { - case VK_PHYSICAL_DEVICE_TYPE_OTHER: - return "Other"; - case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: - return "IntegratedGpu"; - case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: - return "DiscreteGpu"; - case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: - return "VirtualGpu"; - case VK_PHYSICAL_DEVICE_TYPE_CPU: - return "Cpu"; - default: - return "Unknown"; - } -} - -typedef enum WSI_PLATFORM { - WSI_PLATFORM_AUTO = 0, - WSI_PLATFORM_WIN32, - WSI_PLATFORM_METAL, - WSI_PLATFORM_ANDROID, - WSI_PLATFORM_QNX, - WSI_PLATFORM_XCB, - WSI_PLATFORM_XLIB, - WSI_PLATFORM_WAYLAND, - WSI_PLATFORM_DIRECTFB, - WSI_PLATFORM_DISPLAY, - WSI_PLATFORM_INVALID, // Sentinel just to indicate invalid user input -} WSI_PLATFORM; - -WSI_PLATFORM wsi_from_string(const char *str) { - if (strcmp(str, "auto") == 0) return WSI_PLATFORM_AUTO; -#if defined(VK_USE_PLATFORM_WIN32_KHR) - if (strcmp(str, "win32") == 0) return WSI_PLATFORM_WIN32; -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) - if (strcmp(str, "metal") == 0) return WSI_PLATFORM_METAL; -#endif -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - if (strcmp(str, "android") == 0) return WSI_PLATFORM_ANDROID; -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - if (strcmp(str, "qnx") == 0) return WSI_PLATFORM_QNX; -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - if (strcmp(str, "xcb") == 0) return WSI_PLATFORM_XCB; -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - if (strcmp(str, "xlib") == 0) return WSI_PLATFORM_XLIB; -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - if (strcmp(str, "wayland") == 0) return WSI_PLATFORM_WAYLAND; -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - if (strcmp(str, "directfb") == 0) return WSI_PLATFORM_DIRECTFB; -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - if (strcmp(str, "display") == 0) return WSI_PLATFORM_DISPLAY; -#endif - return WSI_PLATFORM_INVALID; -}; - -const char *wsi_to_string(WSI_PLATFORM wsi_platform) { - switch (wsi_platform) { - case (WSI_PLATFORM_AUTO): - return "auto"; -#if defined(VK_USE_PLATFORM_WIN32_KHR) - case (WSI_PLATFORM_WIN32): - return "win32"; -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) - case (WSI_PLATFORM_METAL): - return "metal"; -#endif -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - case (WSI_PLATFORM_ANDROID): - return "android"; -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - case (WSI_PLATFORM_QNX): - return "qnx"; -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - case (WSI_PLATFORM_XCB): - return "xcb"; -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - case (WSI_PLATFORM_XLIB): - return "xlib"; -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - case (WSI_PLATFORM_WAYLAND): - return "wayland"; -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - case (WSI_PLATFORM_DIRECTFB): - return "directfb"; -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - case (WSI_PLATFORM_DISPLAY): - return "display"; -#endif - default: - return "unknown"; - } -}; - -typedef struct { - VkFence fence; - VkSemaphore image_acquired_semaphore; - VkCommandBuffer cmd; - VkCommandBuffer graphics_to_present_cmd; - VkBuffer uniform_buffer; - VkDeviceMemory uniform_memory; - void *uniform_memory_ptr; - VkDescriptorSet descriptor_set; -} SubmissionResources; - -typedef struct { - VkImage image; - VkImageView view; - VkFramebuffer framebuffer; - VkSemaphore draw_complete_semaphore; - VkSemaphore image_ownership_semaphore; -} SwapchainImageResources; - -struct demo { -#if defined(VK_USE_PLATFORM_WIN32_KHR) -#define APP_NAME_STR_LEN 80 - HINSTANCE connection; // hInstance - Windows Instance - char name[APP_NAME_STR_LEN]; // Name to put on the window/icon - HWND window; // hWnd - window handle - POINT minsize; // minimum window size -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - void *xlib_library; - Display *xlib_display; - Window xlib_window; - Atom xlib_wm_delete_window; -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - void *xcb_library; - Display *xcb_display; - xcb_connection_t *connection; - xcb_screen_t *screen; - xcb_window_t xcb_window; - xcb_intern_atom_reply_t *atom_wm_delete_window; -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - void *wayland_library; // Dynamic library for wayland - struct wl_display *wayland_display; - struct wl_registry *registry; - struct wl_compositor *compositor; - struct wl_surface *window; - struct xdg_wm_base *xdg_wm_base; - struct zxdg_decoration_manager_v1 *xdg_decoration_mgr; - struct zxdg_toplevel_decoration_v1 *toplevel_decoration; - struct xdg_surface *xdg_surface; - int xdg_surface_has_been_configured; - struct xdg_toplevel *xdg_toplevel; - struct wl_seat *seat; - struct wl_pointer *pointer; - struct wl_keyboard *keyboard; - int pending_width, pending_height; -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - IDirectFB *dfb; - IDirectFBSurface *directfb_window; - IDirectFBEventBuffer *event_buffer; -#endif -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - struct ANativeWindow *window; -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) - void *caMetalLayer; -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - screen_context_t screen_context; - screen_window_t screen_window; - screen_event_t screen_event; -#endif - WSI_PLATFORM wsi_platform; - VkSurfaceKHR surface; - bool initialized; - bool swapchain_ready; - bool is_minimized; - bool use_staging_buffer; - bool separate_present_queue; - bool invalid_gpu_selection; - int32_t gpu_number; - - bool VK_KHR_incremental_present_enabled; - - bool VK_GOOGLE_display_timing_enabled; - bool syncd_with_actual_presents; - uint64_t refresh_duration; - uint64_t refresh_duration_multiplier; - uint64_t target_IPD; // image present duration (inverse of frame rate) - uint64_t prev_desired_present_time; - uint32_t next_present_id; - uint32_t last_early_id; // 0 if no early images - uint32_t last_late_id; // 0 if no late images - - VkInstance inst; - VkPhysicalDevice gpu; - VkDevice device; - VkQueue graphics_queue; - VkQueue present_queue; - uint32_t graphics_queue_family_index; - uint32_t present_queue_family_index; - VkPhysicalDeviceProperties gpu_props; - VkQueueFamilyProperties *queue_props; - VkPhysicalDeviceMemoryProperties memory_properties; - SubmissionResources submission_resources[FRAME_LAG]; - uint32_t current_submission_index; - - uint32_t enabled_extension_count; - uint32_t enabled_layer_count; - char *extension_names[64]; - char *enabled_layers[64]; - - int width, height; - VkFormat format; - VkColorSpaceKHR color_space; - - uint32_t swapchainImageCount; - VkSwapchainKHR swapchain; - SwapchainImageResources swapchain_resources[MAX_SWAPCHAIN_IMAGE_COUNT]; - VkPresentModeKHR presentMode; - bool first_swapchain_frame; - - VkCommandPool cmd_pool; - VkCommandPool present_cmd_pool; - - struct { - VkFormat format; - - VkImage image; - VkMemoryAllocateInfo mem_alloc; - VkDeviceMemory mem; - VkImageView view; - } depth; - - char *tex_file; - struct texture_object textures[DEMO_TEXTURE_COUNT]; - struct texture_object staging_texture; - - VkCommandBuffer cmd; // Buffer for initialization commands - VkPipelineLayout pipeline_layout; - VkDescriptorSetLayout desc_layout; - VkPipelineCache pipelineCache; - VkRenderPass render_pass; - VkPipeline pipeline; - - mat4x4 projection_matrix; - mat4x4 view_matrix; - mat4x4 model_matrix; - - float spin_angle; - float spin_increment; - bool pause; - - VkShaderModule vert_shader_module; - VkShaderModule frag_shader_module; - - VkDescriptorPool desc_pool; - - bool quit; - int32_t curFrame; - int32_t frameCount; - bool validate; - bool use_break; - bool suppress_popups; - bool force_errors; - - VkDebugUtilsMessengerEXT dbg_messenger; - - uint32_t queue_family_count; -}; - -VKAPI_ATTR VkBool32 VKAPI_CALL debug_messenger_callback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, - VkDebugUtilsMessageTypeFlagsEXT messageType, - const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, - void *pUserData) { - char prefix[64] = ""; - char *message = (char *)malloc(strlen(pCallbackData->pMessage) + 5000); - assert(message); - struct demo *demo = (struct demo *)pUserData; - - if (demo->use_break) { -#ifndef WIN32 - raise(SIGTRAP); -#else - DebugBreak(); -#endif - } - - if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) { - strcat(prefix, "VERBOSE : "); - } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) { - strcat(prefix, "INFO : "); - } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) { - strcat(prefix, "WARNING : "); - } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { - strcat(prefix, "ERROR : "); - } - - if (messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT) { - strcat(prefix, "GENERAL"); - } else { - if (messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) { - strcat(prefix, "VALIDATION"); - validation_error = 1; - } - if (messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) { - if (messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) { - strcat(prefix, "|"); - } - strcat(prefix, "PERFORMANCE"); - } - } - - sprintf(message, "%s - Message Id Number: %d | Message Id Name: %s\n\t%s\n", prefix, pCallbackData->messageIdNumber, - pCallbackData->pMessageIdName == NULL ? "" : pCallbackData->pMessageIdName, pCallbackData->pMessage); - if (pCallbackData->objectCount > 0) { - char tmp_message[500]; - sprintf(tmp_message, "\n\tObjects - %d\n", pCallbackData->objectCount); - strcat(message, tmp_message); - for (uint32_t object = 0; object < pCallbackData->objectCount; ++object) { - sprintf(tmp_message, "\t\tObject[%d] - %s", object, string_VkObjectType(pCallbackData->pObjects[object].objectType)); - strcat(message, tmp_message); - - VkObjectType t = pCallbackData->pObjects[object].objectType; - if (t == VK_OBJECT_TYPE_INSTANCE || t == VK_OBJECT_TYPE_PHYSICAL_DEVICE || t == VK_OBJECT_TYPE_DEVICE || - t == VK_OBJECT_TYPE_COMMAND_BUFFER || t == VK_OBJECT_TYPE_QUEUE) { - sprintf(tmp_message, ", Handle %p", (void *)(uintptr_t)(pCallbackData->pObjects[object].objectHandle)); - strcat(message, tmp_message); - } else { - sprintf(tmp_message, ", Handle Ox%" PRIx64, (pCallbackData->pObjects[object].objectHandle)); - strcat(message, tmp_message); - } - - if (NULL != pCallbackData->pObjects[object].pObjectName && strlen(pCallbackData->pObjects[object].pObjectName) > 0) { - sprintf(tmp_message, ", Name \"%s\"", pCallbackData->pObjects[object].pObjectName); - strcat(message, tmp_message); - } - sprintf(tmp_message, "\n"); - strcat(message, tmp_message); - } - } - if (pCallbackData->cmdBufLabelCount > 0) { - char tmp_message[500]; - sprintf(tmp_message, "\n\tCommand Buffer Labels - %d\n", pCallbackData->cmdBufLabelCount); - strcat(message, tmp_message); - for (uint32_t cmd_buf_label = 0; cmd_buf_label < pCallbackData->cmdBufLabelCount; ++cmd_buf_label) { - sprintf(tmp_message, "\t\tLabel[%d] - %s { %f, %f, %f, %f}\n", cmd_buf_label, - pCallbackData->pCmdBufLabels[cmd_buf_label].pLabelName, pCallbackData->pCmdBufLabels[cmd_buf_label].color[0], - pCallbackData->pCmdBufLabels[cmd_buf_label].color[1], pCallbackData->pCmdBufLabels[cmd_buf_label].color[2], - pCallbackData->pCmdBufLabels[cmd_buf_label].color[3]); - strcat(message, tmp_message); - } - } - -#ifdef _WIN32 - - in_callback = true; - if (!demo->suppress_popups) MessageBox(NULL, message, "Alert", MB_OK); - in_callback = false; - -#elif defined(ANDROID) - - if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) { - __android_log_print(ANDROID_LOG_INFO, APP_SHORT_NAME, "%s", message); - } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) { - __android_log_print(ANDROID_LOG_WARN, APP_SHORT_NAME, "%s", message); - } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { - __android_log_print(ANDROID_LOG_ERROR, APP_SHORT_NAME, "%s", message); - } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) { - __android_log_print(ANDROID_LOG_VERBOSE, APP_SHORT_NAME, "%s", message); - } else { - __android_log_print(ANDROID_LOG_INFO, APP_SHORT_NAME, "%s", message); - } - -#else - - printf("%s\n", message); - fflush(stdout); - -#endif - - free(message); - - // Don't bail out, but keep going. - return false; -} - -bool ActualTimeLate(uint64_t desired, uint64_t actual, uint64_t rdur) { - // The desired time was the earliest time that the present should have - // occured. In almost every case, the actual time should be later than the - // desired time. We should only consider the actual time "late" if it is - // after "desired + rdur". - if (actual <= desired) { - // The actual time was before or equal to the desired time. This will - // probably never happen, but in case it does, return false since the - // present was obviously NOT late. - return false; - } - uint64_t deadline = desired + rdur; - if (actual > deadline) { - return true; - } else { - return false; - } -} -bool CanPresentEarlier(uint64_t earliest, uint64_t actual, uint64_t margin, uint64_t rdur) { - if (earliest < actual) { - // Consider whether this present could have occured earlier. Make sure - // that earliest time was at least 2msec earlier than actual time, and - // that the margin was at least 2msec: - uint64_t diff = actual - earliest; - if ((diff >= (2 * MILLION)) && (margin >= (2 * MILLION))) { - // This present could have occured earlier because both: 1) the - // earliest time was at least 2 msec before actual time, and 2) the - // margin was at least 2msec. - return true; - } - } - return false; -} - -// Forward declarations: -static void demo_resize(struct demo *demo); - -static void demo_create_surface(struct demo *demo); - -#if defined(__GNUC__) || defined(__clang__) -#define DECORATE_PRINTF(_fmt_argnum, _first_param_num) __attribute__((format(printf, _fmt_argnum, _first_param_num))) -#else -#define DECORATE_PRINTF(_fmt_num, _first_param_num) -#endif - -DECORATE_PRINTF(4, 5) -static void demo_name_object(struct demo *demo, VkObjectType object_type, uint64_t vulkan_handle, const char *format, ...) { - if (!demo->validate) { - return; - } - VkResult U_ASSERT_ONLY err; - char name[1024]; - va_list argptr; - va_start(argptr, format); - vsnprintf(name, sizeof(name), format, argptr); - va_end(argptr); - name[sizeof(name) - 1] = '\0'; - - VkDebugUtilsObjectNameInfoEXT obj_name = { - .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, - .pNext = NULL, - .objectType = object_type, - .objectHandle = vulkan_handle, - .pObjectName = name, - }; - err = vkSetDebugUtilsObjectNameEXT(demo->device, &obj_name); - assert(!err); -} - -DECORATE_PRINTF(4, 5) -static void demo_push_cb_label(struct demo *demo, VkCommandBuffer cb, const float *color, const char *format, ...) { - if (!demo->validate) { - return; - } - char name[1024]; - va_list argptr; - va_start(argptr, format); - vsnprintf(name, sizeof(name), format, argptr); - va_end(argptr); - name[sizeof(name) - 1] = '\0'; - - VkDebugUtilsLabelEXT label = { - .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, - .pNext = NULL, - .pLabelName = name, - }; - if (color) { - memcpy(label.color, color, sizeof(label.color)); - } - - vkCmdBeginDebugUtilsLabelEXT(cb, &label); -} - -static void demo_pop_cb_label(struct demo *demo, VkCommandBuffer cb) { - if (!demo->validate) { - return; - } - vkCmdEndDebugUtilsLabelEXT(cb); -} - -static bool memory_type_from_properties(struct demo *demo, uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex) { - // Search memtypes to find first index with those properties - for (uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; i++) { - if ((typeBits & 1) == 1) { - // Type is available, does it match user properties? - if ((demo->memory_properties.memoryTypes[i].propertyFlags & requirements_mask) == requirements_mask) { - *typeIndex = i; - return true; - } - } - typeBits >>= 1; - } - // No memory types matched, return failure - return false; -} - -static void demo_flush_init_cmd(struct demo *demo) { - VkResult U_ASSERT_ONLY err; - - // This function could get called twice if the texture uses a staging buffer - // In that case the second call should be ignored - if (demo->cmd == VK_NULL_HANDLE) return; - - err = vkEndCommandBuffer(demo->cmd); - assert(!err); - - VkFence fence; - VkFenceCreateInfo fence_ci = {.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, .pNext = NULL, .flags = 0}; - if (demo->force_errors) { - // Remove sType to intentionally force validation layer errors. - fence_ci.sType = 0; - } - err = vkCreateFence(demo->device, &fence_ci, NULL, &fence); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_FENCE, (uint64_t)fence, "InitFence"); - - const VkCommandBuffer cmd_bufs[] = {demo->cmd}; - VkSubmitInfo submit_info = {.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, - .pNext = NULL, - .waitSemaphoreCount = 0, - .pWaitSemaphores = NULL, - .pWaitDstStageMask = NULL, - .commandBufferCount = 1, - .pCommandBuffers = cmd_bufs, - .signalSemaphoreCount = 0, - .pSignalSemaphores = NULL}; - - err = vkQueueSubmit(demo->graphics_queue, 1, &submit_info, fence); - assert(!err); - - err = vkWaitForFences(demo->device, 1, &fence, VK_TRUE, UINT64_MAX); - assert(!err); - - vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, cmd_bufs); - vkDestroyFence(demo->device, fence, NULL); - demo->cmd = VK_NULL_HANDLE; -} - -static void demo_set_image_layout(struct demo *demo, VkImage image, VkImageAspectFlags aspectMask, VkImageLayout old_image_layout, - VkImageLayout new_image_layout, VkAccessFlagBits srcAccessMask, VkPipelineStageFlags src_stages, - VkPipelineStageFlags dest_stages) { - assert(demo->cmd); - - VkImageMemoryBarrier image_memory_barrier = {.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = NULL, - .srcAccessMask = srcAccessMask, - .dstAccessMask = 0, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .oldLayout = old_image_layout, - .newLayout = new_image_layout, - .image = image, - .subresourceRange = {aspectMask, 0, 1, 0, 1}}; - - switch (new_image_layout) { - case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: - /* Make sure anything that was copying from this image has completed */ - image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - break; - - case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: - image_memory_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - break; - - case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: - image_memory_barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - break; - - case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: - image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; - break; - - case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: - image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - break; - - case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: - image_memory_barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; - break; - - default: - image_memory_barrier.dstAccessMask = 0; - break; - } - - VkImageMemoryBarrier *pmemory_barrier = &image_memory_barrier; - - vkCmdPipelineBarrier(demo->cmd, src_stages, dest_stages, 0, 0, NULL, 0, NULL, 1, pmemory_barrier); -} - -static void demo_draw_build_cmd(struct demo *demo, SubmissionResources *submission_resource, - SwapchainImageResources *swapchain_resource) { - const VkCommandBufferBeginInfo cmd_buf_info = { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - .pNext = NULL, - .flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, - .pInheritanceInfo = NULL, - }; - const VkClearValue clear_values[2] = { - [0] = {.color.float32 = {0.0f, 1.0f, 0.0f, 1.0f}}, - [1] = {.depthStencil = {1.0f, 0}}, - }; - const VkRenderPassBeginInfo rp_begin = { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .pNext = NULL, - .renderPass = demo->render_pass, - .framebuffer = swapchain_resource->framebuffer, - .renderArea.offset.x = 0, - .renderArea.offset.y = 0, - .renderArea.extent.width = demo->width, - .renderArea.extent.height = demo->height, - .clearValueCount = 2, - .pClearValues = clear_values, - }; - VkResult U_ASSERT_ONLY err; - - err = vkResetCommandBuffer(submission_resource->cmd, 0 /* VK_COMMAND_BUFFER_RESET_FLAGS */); - err = vkBeginCommandBuffer(submission_resource->cmd, &cmd_buf_info); - - demo_name_object(demo, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)submission_resource->cmd, "CubeDrawCommandBuf"); - - const float begin_color[4] = {0.4f, 0.3f, 0.2f, 0.1f}; - demo_push_cb_label(demo, submission_resource->cmd, begin_color, "DrawBegin"); - - assert(!err); - vkCmdBeginRenderPass(submission_resource->cmd, &rp_begin, VK_SUBPASS_CONTENTS_INLINE); - - const float renderpass_color[4] = {8.4f, 7.3f, 6.2f, 7.1f}; - demo_push_cb_label(demo, submission_resource->cmd, renderpass_color, "InsideRenderPass"); - - vkCmdBindPipeline(submission_resource->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, demo->pipeline); - vkCmdBindDescriptorSets(submission_resource->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, demo->pipeline_layout, 0, 1, - &submission_resource->descriptor_set, 0, NULL); - VkViewport viewport; - memset(&viewport, 0, sizeof(viewport)); - float viewport_dimension; - if (demo->width < demo->height) { - viewport_dimension = (float)demo->width; - viewport.y = (demo->height - demo->width) / 2.0f; - } else { - viewport_dimension = (float)demo->height; - viewport.x = (demo->width - demo->height) / 2.0f; - } - viewport.height = viewport_dimension; - viewport.width = viewport_dimension; - viewport.minDepth = (float)0.0f; - viewport.maxDepth = (float)1.0f; - vkCmdSetViewport(submission_resource->cmd, 0, 1, &viewport); - - VkRect2D scissor; - memset(&scissor, 0, sizeof(scissor)); - scissor.extent.width = demo->width; - scissor.extent.height = demo->height; - scissor.offset.x = 0; - scissor.offset.y = 0; - vkCmdSetScissor(submission_resource->cmd, 0, 1, &scissor); - - const float draw_color[4] = {-0.4f, -0.3f, -0.2f, -0.1f}; - demo_push_cb_label(demo, submission_resource->cmd, draw_color, "ActualDraw"); - vkCmdDraw(submission_resource->cmd, 12 * 3, 1, 0, 0); - demo_pop_cb_label(demo, submission_resource->cmd); - - // Note that ending the renderpass changes the image's layout from - // COLOR_ATTACHMENT_OPTIMAL to PRESENT_SRC_KHR - vkCmdEndRenderPass(submission_resource->cmd); - demo_pop_cb_label(demo, submission_resource->cmd); - - if (demo->separate_present_queue) { - // We have to transfer ownership from the graphics queue family to the - // present queue family to be able to present. Note that we don't have - // to transfer from present queue family back to graphics queue family at - // the start of the next frame because we don't care about the image's - // contents at that point. - VkImageMemoryBarrier image_ownership_barrier = {.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = NULL, - .srcAccessMask = 0, - .dstAccessMask = 0, - .oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - .srcQueueFamilyIndex = demo->graphics_queue_family_index, - .dstQueueFamilyIndex = demo->present_queue_family_index, - .image = swapchain_resource->image, - .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; - - vkCmdPipelineBarrier(submission_resource->cmd, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - 0, 0, NULL, 0, NULL, 1, &image_ownership_barrier); - } - demo_pop_cb_label(demo, submission_resource->cmd); - err = vkEndCommandBuffer(submission_resource->cmd); - assert(!err); -} - -void demo_build_image_ownership_cmd(struct demo *demo, SubmissionResources *submission_resource, - SwapchainImageResources *swapchain_resource) { - VkResult U_ASSERT_ONLY err; - - err = vkResetCommandBuffer(submission_resource->graphics_to_present_cmd, 0 /* VK_COMMAND_BUFFER_RESET_FLAGS */); - assert(!err); - - const VkCommandBufferBeginInfo cmd_buf_info = { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - .pNext = NULL, - .flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, - .pInheritanceInfo = NULL, - }; - err = vkBeginCommandBuffer(submission_resource->graphics_to_present_cmd, &cmd_buf_info); - assert(!err); - - VkImageMemoryBarrier image_ownership_barrier = {.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = NULL, - .srcAccessMask = 0, - .dstAccessMask = 0, - .oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - .srcQueueFamilyIndex = demo->graphics_queue_family_index, - .dstQueueFamilyIndex = demo->present_queue_family_index, - .image = swapchain_resource->image, - .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; - - vkCmdPipelineBarrier(submission_resource->graphics_to_present_cmd, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, NULL, 0, NULL, 1, &image_ownership_barrier); - err = vkEndCommandBuffer(submission_resource->graphics_to_present_cmd); - assert(!err); -} - -void demo_update_data_buffer(struct demo *demo, void *uniform_memory_ptr) { - mat4x4 MVP, Model, VP; - int matrixSize = sizeof(MVP); - - mat4x4_mul(VP, demo->projection_matrix, demo->view_matrix); - - static struct timespec ts_old; - static bool ts_first = true; - - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - - double dtime = ts_first ? false : - (double)(ts.tv_sec - ts_old.tv_sec) + (double) (ts.tv_nsec - ts_old.tv_nsec) / 1.0e9; - ts_old = ts; - ts_first = false; - - // Rotate around the Y axis - mat4x4_dup(Model, demo->model_matrix); - mat4x4_rotate_Y(demo->model_matrix, Model, (float)degreesToRadians(dtime * demo->spin_angle)); - mat4x4_orthonormalize(demo->model_matrix, demo->model_matrix); - mat4x4_mul(MVP, VP, demo->model_matrix); - - memcpy(uniform_memory_ptr, (const void *)&MVP[0][0], matrixSize); -} - -void DemoUpdateTargetIPD(struct demo *demo) { - // Look at what happened to previous presents, and make appropriate - // adjustments in timing: - VkResult U_ASSERT_ONLY err; - VkPastPresentationTimingGOOGLE *past = NULL; - uint32_t count = 0; - - err = vkGetPastPresentationTimingGOOGLE(demo->device, demo->swapchain, &count, NULL); - assert(!err); - if (count) { - past = (VkPastPresentationTimingGOOGLE *)malloc(sizeof(VkPastPresentationTimingGOOGLE) * count); - assert(past); - err = vkGetPastPresentationTimingGOOGLE(demo->device, demo->swapchain, &count, past); - assert(!err); - - bool early = false; - bool late = false; - bool calibrate_next = false; - for (uint32_t i = 0; i < count; i++) { - if (!demo->syncd_with_actual_presents) { - // This is the first time that we've received an - // actualPresentTime for this swapchain. In order to not - // perceive these early frames as "late", we need to sync-up - // our future desiredPresentTime's with the - // actualPresentTime(s) that we're receiving now. - calibrate_next = true; - - // So that we don't suspect any pending presents as late, - // record them all as suspected-late presents: - demo->last_late_id = demo->next_present_id - 1; - demo->last_early_id = 0; - demo->syncd_with_actual_presents = true; - break; - } else if (CanPresentEarlier(past[i].earliestPresentTime, past[i].actualPresentTime, past[i].presentMargin, - demo->refresh_duration)) { - // This image could have been presented earlier. We don't want - // to decrease the target_IPD until we've seen early presents - // for at least two seconds. - if (demo->last_early_id == past[i].presentID) { - // We've now seen two seconds worth of early presents. - // Flag it as such, and reset the counter: - early = true; - demo->last_early_id = 0; - } else if (demo->last_early_id == 0) { - // This is the first early present we've seen. - // Calculate the presentID for two seconds from now. - uint64_t lastEarlyTime = past[i].actualPresentTime + (2 * BILLION); - uint32_t howManyPresents = (uint32_t)((lastEarlyTime - past[i].actualPresentTime) / demo->target_IPD); - demo->last_early_id = past[i].presentID + howManyPresents; - } else { - // We are in the midst of a set of early images, - // and so we won't do anything. - } - late = false; - demo->last_late_id = 0; - } else if (ActualTimeLate(past[i].desiredPresentTime, past[i].actualPresentTime, demo->refresh_duration)) { - // This image was presented after its desired time. Since - // there's a delay between calling vkQueuePresentKHR and when - // we get the timing data, several presents may have been late. - // Thus, we need to threat all of the outstanding presents as - // being likely late, so that we only increase the target_IPD - // once for all of those presents. - if ((demo->last_late_id == 0) || (demo->last_late_id < past[i].presentID)) { - late = true; - // Record the last suspected-late present: - demo->last_late_id = demo->next_present_id - 1; - } else { - // We are in the midst of a set of likely-late images, - // and so we won't do anything. - } - early = false; - demo->last_early_id = 0; - } else { - // Since this image was not presented early or late, reset - // any sets of early or late presentIDs: - early = false; - late = false; - calibrate_next = true; - demo->last_early_id = 0; - demo->last_late_id = 0; - } - } - - if (early) { - // Since we've seen at least two-seconds worth of presnts that - // could have occured earlier than desired, let's decrease the - // target_IPD (i.e. increase the frame rate): - // - // TODO(ianelliott): Try to calculate a better target_IPD based - // on the most recently-seen present (this is overly-simplistic). - demo->refresh_duration_multiplier--; - if (demo->refresh_duration_multiplier == 0) { - // This should never happen, but in case it does, don't - // try to go faster. - demo->refresh_duration_multiplier = 1; - } - demo->target_IPD = demo->refresh_duration * demo->refresh_duration_multiplier; - } - if (late) { - // Since we found a new instance of a late present, we want to - // increase the target_IPD (i.e. decrease the frame rate): - // - // TODO(ianelliott): Try to calculate a better target_IPD based - // on the most recently-seen present (this is overly-simplistic). - demo->refresh_duration_multiplier++; - demo->target_IPD = demo->refresh_duration * demo->refresh_duration_multiplier; - } - - if (calibrate_next) { - int64_t multiple = demo->next_present_id - past[count - 1].presentID - 1; - demo->prev_desired_present_time = (past[count - 1].actualPresentTime + (multiple * demo->target_IPD)); - } - free(past); - } -} - -static void demo_draw(struct demo *demo) { - // Don't draw if initialization isn't complete, if the swapchain became outdated, or if the window is minimized - if (!demo->initialized || !demo->swapchain_ready || demo->is_minimized) { - return; - } - - VkResult U_ASSERT_ONLY err; - - SubmissionResources current_submission = demo->submission_resources[demo->current_submission_index]; - - // Ensure no more than FRAME_LAG renderings are outstanding - vkWaitForFences(demo->device, 1, ¤t_submission.fence, VK_TRUE, UINT64_MAX); - - uint32_t current_swapchain_image_index; - do { - // Get the index of the next available swapchain image: - err = vkAcquireNextImageKHR(demo->device, demo->swapchain, UINT64_MAX, current_submission.image_acquired_semaphore, - VK_NULL_HANDLE, ¤t_swapchain_image_index); - - if (err == VK_ERROR_OUT_OF_DATE_KHR) { - // demo->swapchain is out of date (e.g. the window was resized) and - // must be recreated: - demo_resize(demo); - } else if (err == VK_SUBOPTIMAL_KHR) { - // demo->swapchain is not as optimal as it could be, but the platform's - // presentation engine will still present the image correctly. - break; - } else if (err == VK_ERROR_SURFACE_LOST_KHR) { - vkDestroySurfaceKHR(demo->inst, demo->surface, NULL); - demo_create_surface(demo); - demo_resize(demo); - } else { - assert(!err); - } - - // Stop drawing if we resized but didn't successfully create a new swapchain. - if (!demo->swapchain_ready) { - return; - } - } while (err != VK_SUCCESS); - - SwapchainImageResources current_swapchain_resource = demo->swapchain_resources[current_swapchain_image_index]; - - demo_update_data_buffer(demo, current_submission.uniform_memory_ptr); - - if (demo->VK_GOOGLE_display_timing_enabled) { - // Look at what happened to previous presents, and make appropriate - // adjustments in timing: - DemoUpdateTargetIPD(demo); - - // Note: a real application would position its geometry to that it's in - // the correct locatoin for when the next image is presented. It might - // also wait, so that there's less latency between any input and when - // the next image is rendered/presented. This demo program is so - // simple that it doesn't do either of those. - } - - demo_draw_build_cmd(demo, ¤t_submission, ¤t_swapchain_resource); - - if (demo->separate_present_queue) { - demo_build_image_ownership_cmd(demo, ¤t_submission, ¤t_swapchain_resource); - } - - // Only reset right before submitting so we can't deadlock on an un-signalled fence that has nothing submitted to it - vkResetFences(demo->device, 1, ¤t_submission.fence); - - // Wait for the image acquired semaphore to be signaled to ensure - // that the image won't be rendered to until the presentation - // engine has fully released ownership to the application, and it is - // okay to render to the image. - VkPipelineStageFlags pipe_stage_flags; - VkSubmitInfo submit_info; - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submit_info.pNext = NULL; - pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - submit_info.pWaitDstStageMask = &pipe_stage_flags; - submit_info.waitSemaphoreCount = 1; - submit_info.pWaitSemaphores = ¤t_submission.image_acquired_semaphore; - submit_info.commandBufferCount = 1; - submit_info.pCommandBuffers = ¤t_submission.cmd; - submit_info.signalSemaphoreCount = 1; - submit_info.pSignalSemaphores = ¤t_swapchain_resource.draw_complete_semaphore; - err = vkQueueSubmit(demo->graphics_queue, 1, &submit_info, current_submission.fence); - assert(!err); - - if (demo->separate_present_queue) { - // If we are using separate queues, change image ownership to the - // present queue before presenting, waiting for the draw complete - // semaphore and signalling the ownership released semaphore when finished - VkFence nullFence = VK_NULL_HANDLE; - pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - submit_info.waitSemaphoreCount = 1; - submit_info.pWaitSemaphores = ¤t_swapchain_resource.draw_complete_semaphore; - submit_info.commandBufferCount = 1; - submit_info.pCommandBuffers = ¤t_submission.graphics_to_present_cmd; - submit_info.signalSemaphoreCount = 1; - submit_info.pSignalSemaphores = ¤t_swapchain_resource.image_ownership_semaphore; - err = vkQueueSubmit(demo->present_queue, 1, &submit_info, nullFence); - assert(!err); - } - - // If we are using separate queues we have to wait for image ownership, - // otherwise wait for draw complete - VkPresentInfoKHR present = { - .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, - .pNext = NULL, - .waitSemaphoreCount = 1, - .pWaitSemaphores = (demo->separate_present_queue) ? ¤t_swapchain_resource.image_ownership_semaphore - : ¤t_swapchain_resource.draw_complete_semaphore, - .swapchainCount = 1, - .pSwapchains = &demo->swapchain, - .pImageIndices = ¤t_swapchain_image_index, - }; - - VkRectLayerKHR rect; - VkPresentRegionKHR region; - VkPresentRegionsKHR regions; - if (demo->VK_KHR_incremental_present_enabled) { - // If using VK_KHR_incremental_present, we provide a hint of the region - // that contains changed content relative to the previously-presented - // image. The implementation can use this hint in order to save - // work/power (by only copying the region in the hint). The - // implementation is free to ignore the hint though, and so we must - // ensure that the entire image has the correctly-drawn content. - uint32_t eighthOfWidth = demo->width / 8; - uint32_t eighthOfHeight = demo->height / 8; - - if (demo->first_swapchain_frame) { - rect.offset.x = 0; - rect.offset.y = 0; - rect.extent.width = demo->width; - rect.extent.height = demo->height; - } else { - rect.offset.x = eighthOfWidth; - rect.offset.y = eighthOfHeight; - rect.extent.width = eighthOfWidth * 6; - rect.extent.height = eighthOfHeight * 6; - } - rect.layer = 0; - - region.rectangleCount = 1; - region.pRectangles = ▭ - - regions.sType = VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR; - regions.pNext = present.pNext; - regions.swapchainCount = present.swapchainCount; - regions.pRegions = ®ion; - present.pNext = ®ions; - } - - VkPresentTimesInfoGOOGLE present_time; - VkPresentTimeGOOGLE ptime; - if (demo->VK_GOOGLE_display_timing_enabled) { - if (demo->prev_desired_present_time == 0) { - // This must be the first present for this swapchain. - // - // We don't know where we are relative to the presentation engine's - // display's refresh cycle. We also don't know how long rendering - // takes. Let's make a grossly-simplified assumption that the - // desiredPresentTime should be half way between now and - // now+target_IPD. We will adjust over time. - uint64_t curtime = getTimeInNanoseconds(); - if (curtime == 0) { - // Since we didn't find out the current time, don't give a - // desiredPresentTime: - ptime.desiredPresentTime = 0; - } else { - ptime.desiredPresentTime = curtime + (demo->target_IPD >> 1); - } - } else { - ptime.desiredPresentTime = (demo->prev_desired_present_time + demo->target_IPD); - } - ptime.presentID = demo->next_present_id++; - demo->prev_desired_present_time = ptime.desiredPresentTime; - - present_time = (VkPresentTimesInfoGOOGLE){ - .sType = VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE, - .pNext = present.pNext, - .swapchainCount = present.swapchainCount, - .pTimes = &ptime, - }; - - present.pNext = &present_time; - } - - err = vkQueuePresentKHR(demo->present_queue, &present); - demo->current_submission_index += 1; - demo->current_submission_index %= FRAME_LAG; - demo->first_swapchain_frame = false; - - if (err == VK_ERROR_OUT_OF_DATE_KHR) { - // demo->swapchain is out of date (e.g. the window was resized) and - // must be recreated: - demo_resize(demo); - } else if (err == VK_SUBOPTIMAL_KHR) { - // SUBOPTIMAL could be due to a resize - VkSurfaceCapabilitiesKHR surfCapabilities; - err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(demo->gpu, demo->surface, &surfCapabilities); - assert(!err); - if (surfCapabilities.currentExtent.width != (uint32_t)demo->width || - surfCapabilities.currentExtent.height != (uint32_t)demo->height) { - demo_resize(demo); - } - } else if (err == VK_ERROR_SURFACE_LOST_KHR) { - vkDestroySurfaceKHR(demo->inst, demo->surface, NULL); - demo_create_surface(demo); - demo_resize(demo); - } else { - assert(!err); - } -} - -// Forward decls for that demo_prepare_swapchain needs -static void demo_prepare_depth(struct demo *demo); -static void demo_prepare_framebuffers(struct demo *demo); - -// Creates the swapchain, swapchain image views, depth buffer, framebuffers, and sempahores. -// This function returns early if it fails to create a swapchain, setting swapchain_ready to false. -static void demo_prepare_swapchain(struct demo *demo) { - VkResult U_ASSERT_ONLY err; - VkSwapchainKHR oldSwapchain = demo->swapchain; - -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - if (demo->wsi_platform == WSI_PLATFORM_WAYLAND && !demo->xdg_surface_has_been_configured) { - return; - } -#endif - - // Check the surface capabilities and formats - VkSurfaceCapabilitiesKHR surfCapabilities; - err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(demo->gpu, demo->surface, &surfCapabilities); - assert(!err); - - uint32_t presentModeCount; - err = vkGetPhysicalDeviceSurfacePresentModesKHR(demo->gpu, demo->surface, &presentModeCount, NULL); - assert(!err); - VkPresentModeKHR *presentModes = (VkPresentModeKHR *)malloc(presentModeCount * sizeof(VkPresentModeKHR)); - assert(presentModes); - err = vkGetPhysicalDeviceSurfacePresentModesKHR(demo->gpu, demo->surface, &presentModeCount, presentModes); - assert(!err); - - VkExtent2D swapchainExtent; - // width and height are either both 0xFFFFFFFF, or both not 0xFFFFFFFF. - if (surfCapabilities.currentExtent.width == 0xFFFFFFFF) { - // If the surface size is undefined, the size is set to the size - // of the images requested, which must fit within the minimum and - // maximum values. - swapchainExtent.width = demo->width; - swapchainExtent.height = demo->height; - - if (swapchainExtent.width < surfCapabilities.minImageExtent.width) { - swapchainExtent.width = surfCapabilities.minImageExtent.width; - } else if (swapchainExtent.width > surfCapabilities.maxImageExtent.width) { - swapchainExtent.width = surfCapabilities.maxImageExtent.width; - } - - if (swapchainExtent.height < surfCapabilities.minImageExtent.height) { - swapchainExtent.height = surfCapabilities.minImageExtent.height; - } else if (swapchainExtent.height > surfCapabilities.maxImageExtent.height) { - swapchainExtent.height = surfCapabilities.maxImageExtent.height; - } - } else { - // If the surface size is defined, the swap chain size must match - swapchainExtent = surfCapabilities.currentExtent; - demo->width = surfCapabilities.currentExtent.width; - demo->height = surfCapabilities.currentExtent.height; - } - - if (surfCapabilities.maxImageExtent.width == 0 || surfCapabilities.maxImageExtent.height == 0) { - demo->is_minimized = true; - return; - } else { - demo->is_minimized = false; - } - - // The FIFO present mode is guaranteed by the spec to be supported - // and to have no tearing. It's a great default present mode to use. - VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR; - - // There are times when you may wish to use another present mode. The - // following code shows how to select them, and the comments provide some - // reasons you may wish to use them. - // - // It should be noted that Vulkan 1.0 doesn't provide a method for - // synchronizing rendering with the presentation engine's display. There - // is a method provided for throttling rendering with the display, but - // there are some presentation engines for which this method will not work. - // If an application doesn't throttle its rendering, and if it renders much - // faster than the refresh rate of the display, this can waste power on - // mobile devices. That is because power is being spent rendering images - // that may never be seen. - - // VK_PRESENT_MODE_IMMEDIATE_KHR is for applications that don't care about - // tearing, or have some way of synchronizing their rendering with the - // display. - // VK_PRESENT_MODE_MAILBOX_KHR may be useful for applications that - // generally render a new presentable image every refresh cycle, but are - // occasionally early. In this case, the application wants the new image - // to be displayed instead of the previously-queued-for-presentation image - // that has not yet been displayed. - // VK_PRESENT_MODE_FIFO_RELAXED_KHR is for applications that generally - // render a new presentable image every refresh cycle, but are occasionally - // late. In this case (perhaps because of stuttering/latency concerns), - // the application wants the late image to be immediately displayed, even - // though that may mean some tearing. - - if (demo->presentMode != swapchainPresentMode) { - for (size_t i = 0; i < presentModeCount; ++i) { - if (presentModes[i] == demo->presentMode) { - swapchainPresentMode = demo->presentMode; - break; - } - } - } - if (swapchainPresentMode != demo->presentMode) { - ERR_EXIT("Present mode specified is not supported\n", "Present mode unsupported"); - } - - // Determine the number of VkImages to use in the swap chain. - // Application desires to acquire 3 images at a time for triple - // buffering - uint32_t desiredNumOfSwapchainImages = 3; - if (desiredNumOfSwapchainImages < surfCapabilities.minImageCount) { - desiredNumOfSwapchainImages = surfCapabilities.minImageCount; - } - // If maxImageCount is 0, we can ask for as many images as we want; - // otherwise we're limited to maxImageCount - if ((surfCapabilities.maxImageCount > 0) && (desiredNumOfSwapchainImages > surfCapabilities.maxImageCount)) { - // Application must settle for fewer images than desired: - desiredNumOfSwapchainImages = surfCapabilities.maxImageCount; - } - - VkSurfaceTransformFlagsKHR preTransform; - if (surfCapabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { - preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; - } else { - preTransform = surfCapabilities.currentTransform; - } - - // Find a supported composite alpha mode - one of these is guaranteed to be set - VkCompositeAlphaFlagBitsKHR compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - VkCompositeAlphaFlagBitsKHR compositeAlphaFlags[4] = { - VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, - VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR, - VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR, - VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR, - }; - for (uint32_t i = 0; i < ARRAY_SIZE(compositeAlphaFlags); i++) { - if (surfCapabilities.supportedCompositeAlpha & compositeAlphaFlags[i]) { - compositeAlpha = compositeAlphaFlags[i]; - break; - } - } - - VkSwapchainCreateInfoKHR swapchain_ci = { - .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, - .pNext = NULL, - .surface = demo->surface, - .minImageCount = desiredNumOfSwapchainImages, - .imageFormat = demo->format, - .imageColorSpace = demo->color_space, - .imageExtent = - { - .width = swapchainExtent.width, - .height = swapchainExtent.height, - }, - .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - .preTransform = preTransform, - .compositeAlpha = compositeAlpha, - .imageArrayLayers = 1, - .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE, - .queueFamilyIndexCount = 0, - .pQueueFamilyIndices = NULL, - .presentMode = swapchainPresentMode, - .oldSwapchain = oldSwapchain, - .clipped = true, - }; - uint32_t i; - err = vkCreateSwapchainKHR(demo->device, &swapchain_ci, NULL, &demo->swapchain); - assert(!err); - - // If we just re-created an existing swapchain, we should destroy the old - // swapchain at this point. - // Note: destroying the swapchain also cleans up all its associated - // presentable images once the platform is done with them. - if (oldSwapchain != VK_NULL_HANDLE) { - vkDestroySwapchainKHR(demo->device, oldSwapchain, NULL); - } - - err = vkGetSwapchainImagesKHR(demo->device, demo->swapchain, &demo->swapchainImageCount, NULL); - assert(!err); - - VkImage *swapchainImages = (VkImage *)malloc(demo->swapchainImageCount * sizeof(VkImage)); - assert(swapchainImages); - err = vkGetSwapchainImagesKHR(demo->device, demo->swapchain, &demo->swapchainImageCount, swapchainImages); - assert(!err); - - for (i = 0; i < demo->swapchainImageCount; i++) { - demo_name_object(demo, VK_OBJECT_TYPE_IMAGE, (uint64_t)swapchainImages[i], "SwapchainImage(%u)", i); - } - for (i = 0; i < demo->swapchainImageCount; i++) { - VkImageViewCreateInfo color_image_view = { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .pNext = NULL, - .format = demo->format, - .components = - { - .r = VK_COMPONENT_SWIZZLE_IDENTITY, - .g = VK_COMPONENT_SWIZZLE_IDENTITY, - .b = VK_COMPONENT_SWIZZLE_IDENTITY, - .a = VK_COMPONENT_SWIZZLE_IDENTITY, - }, - .subresourceRange = - {.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .baseMipLevel = 0, .levelCount = 1, .baseArrayLayer = 0, .layerCount = 1}, - .viewType = VK_IMAGE_VIEW_TYPE_2D, - .flags = 0, - }; - - demo->swapchain_resources[i].image = swapchainImages[i]; - - color_image_view.image = demo->swapchain_resources[i].image; - - err = vkCreateImageView(demo->device, &color_image_view, NULL, &demo->swapchain_resources[i].view); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)demo->swapchain_resources[i].view, "SwapchainView(%u)", i); - } - - // Create semaphores to synchronize acquiring presentable buffers before - // rendering and waiting for drawing to be complete before presenting - VkSemaphoreCreateInfo semaphoreCreateInfo = { - .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, - .pNext = NULL, - .flags = 0, - }; - for (i = 0; i < demo->swapchainImageCount; i++) { - err = vkCreateSemaphore(demo->device, &semaphoreCreateInfo, NULL, &demo->swapchain_resources[i].draw_complete_semaphore); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_SEMAPHORE, (uint64_t)demo->swapchain_resources[i].draw_complete_semaphore, - "DrawCompleteSem(%u)", i); - - if (demo->separate_present_queue) { - err = vkCreateSemaphore(demo->device, &semaphoreCreateInfo, NULL, - &demo->swapchain_resources[i].image_ownership_semaphore); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_SEMAPHORE, (uint64_t)demo->swapchain_resources[i].image_ownership_semaphore, - "ImageOwnerSem(%u)", i); - } - } - - if (demo->VK_GOOGLE_display_timing_enabled) { - VkRefreshCycleDurationGOOGLE rc_dur; - err = vkGetRefreshCycleDurationGOOGLE(demo->device, demo->swapchain, &rc_dur); - assert(!err); - demo->refresh_duration = rc_dur.refreshDuration; - - demo->syncd_with_actual_presents = false; - // Initially target 1X the refresh duration: - demo->target_IPD = demo->refresh_duration; - demo->refresh_duration_multiplier = 1; - demo->prev_desired_present_time = 0; - demo->next_present_id = 1; - } - - if (NULL != swapchainImages) { - free(swapchainImages); - } - - if (NULL != presentModes) { - free(presentModes); - } - - demo_prepare_depth(demo); - demo_prepare_framebuffers(demo); - demo->swapchain_ready = true; - demo->first_swapchain_frame = true; -} - -static void demo_prepare_depth(struct demo *demo) { - demo->depth.format = VK_FORMAT_D16_UNORM; - - const VkImageCreateInfo image = { - .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - .pNext = NULL, - .imageType = VK_IMAGE_TYPE_2D, - .format = demo->depth.format, - .extent = {demo->width, demo->height, 1}, - .mipLevels = 1, - .arrayLayers = 1, - .samples = VK_SAMPLE_COUNT_1_BIT, - .tiling = VK_IMAGE_TILING_OPTIMAL, - .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - .flags = 0, - }; - - VkImageViewCreateInfo view = { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .pNext = NULL, - .image = VK_NULL_HANDLE, - .format = demo->depth.format, - .subresourceRange = - {.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT, .baseMipLevel = 0, .levelCount = 1, .baseArrayLayer = 0, .layerCount = 1}, - .flags = 0, - .viewType = VK_IMAGE_VIEW_TYPE_2D, - }; - - if (demo->force_errors) { - // Intentionally force a bad pNext value to generate a validation layer error - view.pNext = ℑ - } - - VkMemoryRequirements mem_reqs; - VkResult U_ASSERT_ONLY err; - bool U_ASSERT_ONLY pass; - - /* create image */ - err = vkCreateImage(demo->device, &image, NULL, &demo->depth.image); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_IMAGE, (uint64_t)demo->depth.image, "DepthImage"); - - vkGetImageMemoryRequirements(demo->device, demo->depth.image, &mem_reqs); - assert(!err); - - demo->depth.mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - demo->depth.mem_alloc.pNext = NULL; - demo->depth.mem_alloc.allocationSize = mem_reqs.size; - demo->depth.mem_alloc.memoryTypeIndex = 0; - - pass = memory_type_from_properties(demo, mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - &demo->depth.mem_alloc.memoryTypeIndex); - assert(pass); - - /* allocate memory */ - err = vkAllocateMemory(demo->device, &demo->depth.mem_alloc, NULL, &demo->depth.mem); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_DEVICE_MEMORY, (uint64_t)demo->depth.mem, "DepthMem"); - - /* bind memory */ - err = vkBindImageMemory(demo->device, demo->depth.image, demo->depth.mem, 0); - assert(!err); - - /* create image view */ - view.image = demo->depth.image; - err = vkCreateImageView(demo->device, &view, NULL, &demo->depth.view); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)demo->depth.view, "DepthView"); -} - -/* Convert ppm image data from file into RGBA texture image */ -bool loadTexture(const char *filename, uint8_t *rgba_data, VkSubresourceLayout *layout, int32_t *width, int32_t *height) { - FILE *file = fopen(filename, "rb"); - if (!file) - return false; - if (fseek(file, 0, SEEK_END) == -1) - return false; - long size = ftell(file); - if (size == -1) - return false; - if (fseek(file, 0, SEEK_SET) == -1) - return false; - char *buffer = malloc(size); - if (!buffer) - return false; - if (fread(buffer, 1, size, file) != (size_t) size) - return false; - fclose(file); - char *cPtr; - cPtr = buffer; - if (cPtr >= (buffer + size) || strncmp(cPtr, "P6\n", 3)) { - return false; - } - while (strncmp(cPtr++, "\n", 1)); - sscanf(cPtr, "%u %u", width, height); - if (rgba_data == NULL) { - return true; - } - while (strncmp(cPtr++, "\n", 1)); - if (cPtr >= (buffer + size) || strncmp(cPtr, "255\n", 4)) { - return false; - } - while (strncmp(cPtr++, "\n", 1)); - for (int y = 0; y < *height; y++) { - uint8_t *rowPtr = rgba_data; - for (int x = 0; x < *width; x++) { - memcpy(rowPtr, cPtr, 3); - rowPtr[3] = 255; /* Alpha of 1 */ - rowPtr += 4; - cPtr += 3; - } - rgba_data += layout->rowPitch; - } - free(buffer); - return true; -} - -static void demo_prepare_texture_buffer(struct demo *demo, const char *filename, struct texture_object *tex_obj) { - int32_t tex_width; - int32_t tex_height; - VkResult U_ASSERT_ONLY err; - bool U_ASSERT_ONLY pass; - - if (!loadTexture(filename, NULL, NULL, &tex_width, &tex_height)) { - ERR_EXIT("Failed to load textures", "Load Texture Failure"); - } - - tex_obj->tex_width = tex_width; - tex_obj->tex_height = tex_height; - - const VkBufferCreateInfo buffer_create_info = {.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .pNext = NULL, - .flags = 0, - .size = tex_width * tex_height * 4, - .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - .queueFamilyIndexCount = 0, - .pQueueFamilyIndices = NULL}; - - err = vkCreateBuffer(demo->device, &buffer_create_info, NULL, &tex_obj->buffer); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_BUFFER, (uint64_t)tex_obj->buffer, "TexBuffer(%s)", filename); - - VkMemoryRequirements mem_reqs; - vkGetBufferMemoryRequirements(demo->device, tex_obj->buffer, &mem_reqs); - - tex_obj->mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - tex_obj->mem_alloc.pNext = NULL; - tex_obj->mem_alloc.allocationSize = mem_reqs.size; - tex_obj->mem_alloc.memoryTypeIndex = 0; - - VkFlags requirements = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - pass = memory_type_from_properties(demo, mem_reqs.memoryTypeBits, requirements, &tex_obj->mem_alloc.memoryTypeIndex); - assert(pass); - - err = vkAllocateMemory(demo->device, &tex_obj->mem_alloc, NULL, &(tex_obj->mem)); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_DEVICE_MEMORY, (uint64_t)tex_obj->mem, "TexBufMemory(%s)", filename); - - /* bind memory */ - err = vkBindBufferMemory(demo->device, tex_obj->buffer, tex_obj->mem, 0); - assert(!err); - - VkSubresourceLayout layout; - memset(&layout, 0, sizeof(layout)); - layout.rowPitch = tex_width * 4; - - void *data; - err = vkMapMemory(demo->device, tex_obj->mem, 0, tex_obj->mem_alloc.allocationSize, 0, &data); - assert(!err); - - if (!loadTexture(filename, data, &layout, &tex_width, &tex_height)) { - fprintf(stderr, "Error loading texture: %s\n", filename); - } - - vkUnmapMemory(demo->device, tex_obj->mem); -} - -static void demo_prepare_texture_image(struct demo *demo, const char *filename, struct texture_object *tex_obj, - VkImageTiling tiling, VkImageUsageFlags usage, VkFlags required_props) { - const VkFormat tex_format = VK_FORMAT_R8G8B8A8_SRGB; - int32_t tex_width; - int32_t tex_height; - VkResult U_ASSERT_ONLY err; - bool U_ASSERT_ONLY pass; - - if (!loadTexture(filename, NULL, NULL, &tex_width, &tex_height)) { - ERR_EXIT("Failed to load textures", "Load Texture Failure"); - } - - tex_obj->tex_width = tex_width; - tex_obj->tex_height = tex_height; - - const VkImageCreateInfo image_create_info = { - .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - .pNext = NULL, - .imageType = VK_IMAGE_TYPE_2D, - .format = tex_format, - .extent = {tex_width, tex_height, 1}, - .mipLevels = 1, - .arrayLayers = 1, - .samples = VK_SAMPLE_COUNT_1_BIT, - .tiling = tiling, - .usage = usage, - .flags = 0, - .initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED, - }; - - VkMemoryRequirements mem_reqs; - - err = vkCreateImage(demo->device, &image_create_info, NULL, &tex_obj->image); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_IMAGE, (uint64_t)tex_obj->image, "TexImage(%s)", filename); - - vkGetImageMemoryRequirements(demo->device, tex_obj->image, &mem_reqs); - - tex_obj->mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - tex_obj->mem_alloc.pNext = NULL; - tex_obj->mem_alloc.allocationSize = mem_reqs.size; - tex_obj->mem_alloc.memoryTypeIndex = 0; - - pass = memory_type_from_properties(demo, mem_reqs.memoryTypeBits, required_props, &tex_obj->mem_alloc.memoryTypeIndex); - assert(pass); - - /* allocate memory */ - err = vkAllocateMemory(demo->device, &tex_obj->mem_alloc, NULL, &(tex_obj->mem)); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_DEVICE_MEMORY, (uint64_t)tex_obj->mem, "TexImageMem(%s)", filename); - - /* bind memory */ - err = vkBindImageMemory(demo->device, tex_obj->image, tex_obj->mem, 0); - assert(!err); - - if (required_props & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { - const VkImageSubresource subres = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .mipLevel = 0, - .arrayLayer = 0, - }; - VkSubresourceLayout layout; - void *data; - - vkGetImageSubresourceLayout(demo->device, tex_obj->image, &subres, &layout); - - err = vkMapMemory(demo->device, tex_obj->mem, 0, tex_obj->mem_alloc.allocationSize, 0, &data); - assert(!err); - - if (!loadTexture(filename, data, &layout, &tex_width, &tex_height)) { - fprintf(stderr, "Error loading texture: %s\n", filename); - } - - vkUnmapMemory(demo->device, tex_obj->mem); - } - - tex_obj->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; -} - -static void demo_destroy_texture(struct demo *demo, struct texture_object *tex_objs) { - /* clean up staging resources */ - vkFreeMemory(demo->device, tex_objs->mem, NULL); - if (tex_objs->image) vkDestroyImage(demo->device, tex_objs->image, NULL); - if (tex_objs->buffer) vkDestroyBuffer(demo->device, tex_objs->buffer, NULL); -} - -static void demo_prepare_textures(struct demo *demo) { - const VkFormat tex_format = VK_FORMAT_R8G8B8A8_SRGB; - VkFormatProperties props; - uint32_t i; - - vkGetPhysicalDeviceFormatProperties(demo->gpu, tex_format, &props); - - for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { - VkResult U_ASSERT_ONLY err; - - if ((props.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) && !demo->use_staging_buffer) { - demo_push_cb_label(demo, demo->cmd, NULL, "DirectTexture(%u)", i); - /* Device can texture using linear textures */ - demo_prepare_texture_image(demo, demo->tex_file, &demo->textures[i], VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_SAMPLED_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - // Nothing in the pipeline needs to be complete to start, and don't allow fragment - // shader to run until layout transition completes - demo_set_image_layout(demo, demo->textures[i].image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, - demo->textures[i].imageLayout, 0, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - demo->staging_texture.image = 0; - demo_pop_cb_label(demo, demo->cmd); // "DirectTexture" - } else if (props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) { - /* Must use staging buffer to copy linear texture to optimized */ - demo_push_cb_label(demo, demo->cmd, NULL, "StagingTexture(%u)", i); - - memset(&demo->staging_texture, 0, sizeof(demo->staging_texture)); - demo_prepare_texture_buffer(demo, demo->tex_file, &demo->staging_texture); - - demo_prepare_texture_image(demo, demo->tex_file, &demo->textures[i], VK_IMAGE_TILING_OPTIMAL, - (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT), - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - - demo_set_image_layout(demo, demo->textures[i].image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT); - - demo_push_cb_label(demo, demo->cmd, NULL, "StagingBufferCopy(%u)", i); - - VkBufferImageCopy copy_region = { - .bufferOffset = 0, - .bufferRowLength = demo->staging_texture.tex_width, - .bufferImageHeight = demo->staging_texture.tex_height, - .imageSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, - .imageOffset = {0, 0, 0}, - .imageExtent = {demo->staging_texture.tex_width, demo->staging_texture.tex_height, 1}, - }; - - vkCmdCopyBufferToImage(demo->cmd, demo->staging_texture.buffer, demo->textures[i].image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©_region); - demo_pop_cb_label(demo, demo->cmd); // "StagingBufferCopy" - - demo_set_image_layout(demo, demo->textures[i].image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - demo->textures[i].imageLayout, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - demo_pop_cb_label(demo, demo->cmd); // "StagingTexture" - - } else { - /* Can't support VK_FORMAT_R8G8B8A8_SRGB !? */ - assert(!"No support for R8G8B8A8_SRGB as texture image format"); - } - - const VkSamplerCreateInfo sampler = { - .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, - .pNext = NULL, - .magFilter = VK_FILTER_NEAREST, - .minFilter = VK_FILTER_NEAREST, - .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST, - .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - .addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - .mipLodBias = 0.0f, - .anisotropyEnable = VK_FALSE, - .maxAnisotropy = 1, - .compareOp = VK_COMPARE_OP_NEVER, - .minLod = 0.0f, - .maxLod = 0.0f, - .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE, - .unnormalizedCoordinates = VK_FALSE, - }; - - VkImageViewCreateInfo view = { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .pNext = NULL, - .image = VK_NULL_HANDLE, - .viewType = VK_IMAGE_VIEW_TYPE_2D, - .format = tex_format, - .components = - { - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY, - }, - .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, - .flags = 0, - }; - - /* create sampler */ - err = vkCreateSampler(demo->device, &sampler, NULL, &demo->textures[i].sampler); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_SAMPLER, (uint64_t)demo->textures[i].sampler, "Sampler(%u)", i); - - /* create image view */ - view.image = demo->textures[i].image; - err = vkCreateImageView(demo->device, &view, NULL, &demo->textures[i].view); - demo_name_object(demo, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)demo->textures[i].view, "TexImageView(%u)", i); - assert(!err); - } -} - -void demo_prepare_cube_data_buffers(struct demo *demo) { - VkBufferCreateInfo buf_info; - VkMemoryRequirements mem_reqs; - VkMemoryAllocateInfo mem_alloc; - mat4x4 MVP, VP; - VkResult U_ASSERT_ONLY err; - bool U_ASSERT_ONLY pass; - struct vktexcube_vs_uniform data; - - mat4x4_mul(VP, demo->projection_matrix, demo->view_matrix); - mat4x4_mul(MVP, VP, demo->model_matrix); - memcpy(data.mvp, MVP, sizeof(MVP)); - // dumpMatrix("MVP", MVP); - - for (unsigned int i = 0; i < 12 * 3; i++) { - data.position[i][0] = g_vertex_buffer_data[i * 3]; - data.position[i][1] = g_vertex_buffer_data[i * 3 + 1]; - data.position[i][2] = g_vertex_buffer_data[i * 3 + 2]; - data.position[i][3] = 1.0f; - data.attr[i][0] = g_uv_buffer_data[2 * i]; - data.attr[i][1] = g_uv_buffer_data[2 * i + 1]; - data.attr[i][2] = 0; - data.attr[i][3] = 0; - } - - memset(&buf_info, 0, sizeof(buf_info)); - buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; - buf_info.size = sizeof(data); - - for (unsigned int i = 0; i < FRAME_LAG; i++) { - err = vkCreateBuffer(demo->device, &buf_info, NULL, &demo->submission_resources[i].uniform_buffer); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_BUFFER, (uint64_t)demo->submission_resources[i].uniform_buffer, "UniformBuf(%u)", i); - - vkGetBufferMemoryRequirements(demo->device, demo->submission_resources[i].uniform_buffer, &mem_reqs); - - mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - mem_alloc.pNext = NULL; - mem_alloc.allocationSize = mem_reqs.size; - mem_alloc.memoryTypeIndex = 0; - - pass = memory_type_from_properties(demo, mem_reqs.memoryTypeBits, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - &mem_alloc.memoryTypeIndex); - assert(pass); - - err = vkAllocateMemory(demo->device, &mem_alloc, NULL, &demo->submission_resources[i].uniform_memory); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_DEVICE_MEMORY, (uint64_t)demo->submission_resources[i].uniform_memory, - "UniformMem(%u)", i); - - err = vkMapMemory(demo->device, demo->submission_resources[i].uniform_memory, 0, VK_WHOLE_SIZE, 0, - &demo->submission_resources[i].uniform_memory_ptr); - assert(!err); - - memcpy(demo->submission_resources[i].uniform_memory_ptr, &data, sizeof data); - - err = vkBindBufferMemory(demo->device, demo->submission_resources[i].uniform_buffer, - demo->submission_resources[i].uniform_memory, 0); - assert(!err); - } -} - -static void demo_prepare_descriptor_layout(struct demo *demo) { - const VkDescriptorSetLayoutBinding layout_bindings[2] = { - [0] = - { - .binding = 0, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, - .pImmutableSamplers = NULL, - }, - [1] = - { - .binding = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .descriptorCount = DEMO_TEXTURE_COUNT, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - .pImmutableSamplers = NULL, - }, - }; - const VkDescriptorSetLayoutCreateInfo descriptor_layout = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .pNext = NULL, - .bindingCount = 2, - .pBindings = layout_bindings, - }; - VkResult U_ASSERT_ONLY err; - - err = vkCreateDescriptorSetLayout(demo->device, &descriptor_layout, NULL, &demo->desc_layout); - assert(!err); - - const VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .pNext = NULL, - .setLayoutCount = 1, - .pSetLayouts = &demo->desc_layout, - }; - - err = vkCreatePipelineLayout(demo->device, &pPipelineLayoutCreateInfo, NULL, &demo->pipeline_layout); - assert(!err); -} - -static void demo_prepare_render_pass(struct demo *demo) { - // The initial layout for the color and depth attachments will be LAYOUT_UNDEFINED - // because at the start of the renderpass, we don't care about their contents. - // At the start of the subpass, the color attachment's layout will be transitioned - // to LAYOUT_COLOR_ATTACHMENT_OPTIMAL and the depth stencil attachment's layout - // will be transitioned to LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL. At the end of - // the renderpass, the color attachment's layout will be transitioned to - // LAYOUT_PRESENT_SRC_KHR to be ready to present. This is all done as part of - // the renderpass, no barriers are necessary. - const VkAttachmentDescription attachments[2] = { - [0] = - { - .format = demo->format, - .flags = 0, - .samples = VK_SAMPLE_COUNT_1_BIT, - .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - }, - [1] = - { - .format = demo->depth.format, - .flags = 0, - .samples = VK_SAMPLE_COUNT_1_BIT, - .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, - .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - }, - }; - const VkAttachmentReference color_reference = { - .attachment = 0, - .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - }; - const VkAttachmentReference depth_reference = { - .attachment = 1, - .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - }; - const VkSubpassDescription subpass = { - .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, - .flags = 0, - .inputAttachmentCount = 0, - .pInputAttachments = NULL, - .colorAttachmentCount = 1, - .pColorAttachments = &color_reference, - .pResolveAttachments = NULL, - .pDepthStencilAttachment = &depth_reference, - .preserveAttachmentCount = 0, - .pPreserveAttachments = NULL, - }; - - VkSubpassDependency attachmentDependencies[2] = { - [0] = - { - // Depth buffer is shared between swapchain images - .srcSubpass = VK_SUBPASS_EXTERNAL, - .dstSubpass = 0, - .srcStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - .dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - .srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .dependencyFlags = 0, - }, - [1] = - { - // Image Layout Transition - .srcSubpass = VK_SUBPASS_EXTERNAL, - .dstSubpass = 0, - .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - .srcAccessMask = 0, - .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, - .dependencyFlags = 0, - }, - }; - - const VkRenderPassCreateInfo rp_info = { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, - .pNext = NULL, - .flags = 0, - .attachmentCount = 2, - .pAttachments = attachments, - .subpassCount = 1, - .pSubpasses = &subpass, - .dependencyCount = 2, - .pDependencies = attachmentDependencies, - }; - VkResult U_ASSERT_ONLY err; - - err = vkCreateRenderPass(demo->device, &rp_info, NULL, &demo->render_pass); - assert(!err); -} - -static VkShaderModule demo_prepare_shader_module(const char *name, struct demo *demo, const uint32_t *code, size_t size) { - VkShaderModule module; - VkShaderModuleCreateInfo moduleCreateInfo; - VkResult U_ASSERT_ONLY err; - - moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - moduleCreateInfo.pNext = NULL; - moduleCreateInfo.flags = 0; - moduleCreateInfo.codeSize = size; - moduleCreateInfo.pCode = code; - - err = vkCreateShaderModule(demo->device, &moduleCreateInfo, NULL, &module); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_SHADER_MODULE, (uint64_t)module, "%s", name); - - return module; -} - -static void demo_prepare_vs(struct demo *demo) { - const uint32_t vs_code[] = { -#include "cube.vert.inc" - }; - demo->vert_shader_module = demo_prepare_shader_module("cube.vert", demo, vs_code, sizeof(vs_code)); -} - -static void demo_prepare_fs(struct demo *demo) { - const uint32_t fs_code[] = { -#include "cube.frag.inc" - }; - demo->frag_shader_module = demo_prepare_shader_module("cube.frag", demo, fs_code, sizeof(fs_code)); -} - -static void demo_prepare_pipeline(struct demo *demo) { -#define NUM_DYNAMIC_STATES 2 /*Viewport + Scissor*/ - - VkGraphicsPipelineCreateInfo pipeline; - VkPipelineCacheCreateInfo pipelineCache; - VkPipelineVertexInputStateCreateInfo vi; - VkPipelineInputAssemblyStateCreateInfo ia; - VkPipelineRasterizationStateCreateInfo rs; - VkPipelineColorBlendStateCreateInfo cb; - VkPipelineDepthStencilStateCreateInfo ds; - VkPipelineViewportStateCreateInfo vp; - VkPipelineMultisampleStateCreateInfo ms; - VkDynamicState dynamicStateEnables[NUM_DYNAMIC_STATES]; - VkPipelineDynamicStateCreateInfo dynamicState; - VkResult U_ASSERT_ONLY err; - - memset(dynamicStateEnables, 0, sizeof dynamicStateEnables); - memset(&dynamicState, 0, sizeof dynamicState); - dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynamicState.pDynamicStates = dynamicStateEnables; - - memset(&pipeline, 0, sizeof(pipeline)); - pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - pipeline.layout = demo->pipeline_layout; - - memset(&vi, 0, sizeof(vi)); - vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - - memset(&ia, 0, sizeof(ia)); - ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - - memset(&rs, 0, sizeof(rs)); - rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rs.polygonMode = VK_POLYGON_MODE_FILL; - rs.cullMode = VK_CULL_MODE_BACK_BIT; - rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; - rs.depthClampEnable = VK_FALSE; - rs.rasterizerDiscardEnable = VK_FALSE; - rs.depthBiasEnable = VK_FALSE; - rs.lineWidth = 1.0f; - - memset(&cb, 0, sizeof(cb)); - cb.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - VkPipelineColorBlendAttachmentState att_state[1]; - memset(att_state, 0, sizeof(att_state)); - att_state[0].colorWriteMask = 0xf; - att_state[0].blendEnable = VK_FALSE; - cb.attachmentCount = 1; - cb.pAttachments = att_state; - - memset(&vp, 0, sizeof(vp)); - vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - vp.viewportCount = 1; - dynamicStateEnables[dynamicState.dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT; - vp.scissorCount = 1; - dynamicStateEnables[dynamicState.dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR; - - memset(&ds, 0, sizeof(ds)); - ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - ds.depthTestEnable = VK_TRUE; - ds.depthWriteEnable = VK_TRUE; - ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; - ds.depthBoundsTestEnable = VK_FALSE; - ds.back.failOp = VK_STENCIL_OP_KEEP; - ds.back.passOp = VK_STENCIL_OP_KEEP; - ds.back.compareOp = VK_COMPARE_OP_ALWAYS; - ds.stencilTestEnable = VK_FALSE; - ds.front = ds.back; - - memset(&ms, 0, sizeof(ms)); - ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - ms.pSampleMask = NULL; - ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - - demo_prepare_vs(demo); - demo_prepare_fs(demo); - - // Two stages: vs and fs - VkPipelineShaderStageCreateInfo shaderStages[2]; - memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo)); - - shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; - shaderStages[0].module = demo->vert_shader_module; - shaderStages[0].pName = "main"; - - shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; - shaderStages[1].module = demo->frag_shader_module; - shaderStages[1].pName = "main"; - - memset(&pipelineCache, 0, sizeof(pipelineCache)); - pipelineCache.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; - - err = vkCreatePipelineCache(demo->device, &pipelineCache, NULL, &demo->pipelineCache); - assert(!err); - - pipeline.pVertexInputState = &vi; - pipeline.pInputAssemblyState = &ia; - pipeline.pRasterizationState = &rs; - pipeline.pColorBlendState = &cb; - pipeline.pMultisampleState = &ms; - pipeline.pViewportState = &vp; - pipeline.pDepthStencilState = &ds; - pipeline.stageCount = ARRAY_SIZE(shaderStages); - pipeline.pStages = shaderStages; - pipeline.renderPass = demo->render_pass; - pipeline.pDynamicState = &dynamicState; - - err = vkCreateGraphicsPipelines(demo->device, demo->pipelineCache, 1, &pipeline, NULL, &demo->pipeline); - assert(!err); - - vkDestroyShaderModule(demo->device, demo->frag_shader_module, NULL); - vkDestroyShaderModule(demo->device, demo->vert_shader_module, NULL); -} - -static void demo_prepare_descriptor_pool(struct demo *demo) { - const VkDescriptorPoolSize type_counts[2] = { - [0] = - { - .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = FRAME_LAG, - }, - [1] = - { - .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .descriptorCount = FRAME_LAG * DEMO_TEXTURE_COUNT, - }, - }; - const VkDescriptorPoolCreateInfo descriptor_pool = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .pNext = NULL, - .maxSets = FRAME_LAG, - .poolSizeCount = 2, - .pPoolSizes = type_counts, - }; - VkResult U_ASSERT_ONLY err; - - err = vkCreateDescriptorPool(demo->device, &descriptor_pool, NULL, &demo->desc_pool); - assert(!err); -} - -static void demo_prepare_descriptor_set(struct demo *demo) { - VkDescriptorImageInfo tex_descs[DEMO_TEXTURE_COUNT]; - VkWriteDescriptorSet writes[2]; - VkResult U_ASSERT_ONLY err; - - VkDescriptorSetAllocateInfo alloc_info = {.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .pNext = NULL, - .descriptorPool = demo->desc_pool, - .descriptorSetCount = 1, - .pSetLayouts = &demo->desc_layout}; - - VkDescriptorBufferInfo buffer_info; - buffer_info.offset = 0; - buffer_info.range = sizeof(struct vktexcube_vs_uniform); - - memset(&tex_descs, 0, sizeof(tex_descs)); - for (unsigned int i = 0; i < DEMO_TEXTURE_COUNT; i++) { - tex_descs[i].sampler = demo->textures[i].sampler; - tex_descs[i].imageView = demo->textures[i].view; - tex_descs[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - } - - memset(&writes, 0, sizeof(writes)); - - writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writes[0].descriptorCount = 1; - writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - writes[0].pBufferInfo = &buffer_info; - - writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writes[1].dstBinding = 1; - writes[1].descriptorCount = DEMO_TEXTURE_COUNT; - writes[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - writes[1].pImageInfo = tex_descs; - - for (unsigned int i = 0; i < FRAME_LAG; i++) { - err = vkAllocateDescriptorSets(demo->device, &alloc_info, &demo->submission_resources[i].descriptor_set); - assert(!err); - buffer_info.buffer = demo->submission_resources[i].uniform_buffer; - writes[0].dstSet = demo->submission_resources[i].descriptor_set; - writes[1].dstSet = demo->submission_resources[i].descriptor_set; - vkUpdateDescriptorSets(demo->device, 2, writes, 0, NULL); - } -} - -static void demo_prepare_framebuffers(struct demo *demo) { - VkImageView attachments[2]; - attachments[1] = demo->depth.view; - - const VkFramebufferCreateInfo fb_info = { - .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, - .pNext = NULL, - .renderPass = demo->render_pass, - .attachmentCount = 2, - .pAttachments = attachments, - .width = demo->width, - .height = demo->height, - .layers = 1, - }; - VkResult U_ASSERT_ONLY err; - uint32_t i; - - for (i = 0; i < demo->swapchainImageCount; i++) { - attachments[0] = demo->swapchain_resources[i].view; - err = vkCreateFramebuffer(demo->device, &fb_info, NULL, &demo->swapchain_resources[i].framebuffer); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_FRAMEBUFFER, (uint64_t)demo->swapchain_resources[i].framebuffer, "Framebuffer(%u)", - i); - } -} - -static void demo_prepare_submission_sync_objects(struct demo *demo) { - VkSemaphoreCreateInfo semaphoreCreateInfo = { - .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, - .pNext = NULL, - .flags = 0, - }; - // Create fences that we can use to throttle if we get too far - // ahead of the image presents - VkFenceCreateInfo fence_ci = { - .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, .pNext = NULL, .flags = VK_FENCE_CREATE_SIGNALED_BIT}; - VkResult U_ASSERT_ONLY err; - for (uint32_t i = 0; i < FRAME_LAG; i++) { - err = vkCreateFence(demo->device, &fence_ci, NULL, &demo->submission_resources[i].fence); - assert(!err); - - err = vkCreateSemaphore(demo->device, &semaphoreCreateInfo, NULL, &demo->submission_resources[i].image_acquired_semaphore); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_SEMAPHORE, (uint64_t)demo->submission_resources[i].image_acquired_semaphore, - "AcquireSem(%u)", i); - } -} - -static void demo_prepare(struct demo *demo) { - VkResult U_ASSERT_ONLY err; - if (demo->cmd_pool == VK_NULL_HANDLE) { - const VkCommandPoolCreateInfo cmd_pool_info = { - .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, - .pNext = NULL, - .queueFamilyIndex = demo->graphics_queue_family_index, - .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, - }; - err = vkCreateCommandPool(demo->device, &cmd_pool_info, NULL, &demo->cmd_pool); - assert(!err); - } - - const VkCommandBufferAllocateInfo cmd = { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, - .pNext = NULL, - .commandPool = demo->cmd_pool, - .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, - .commandBufferCount = 1, - }; - err = vkAllocateCommandBuffers(demo->device, &cmd, &demo->cmd); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)demo->cmd, "PrepareCB"); - VkCommandBufferBeginInfo cmd_buf_info = { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - .pNext = NULL, - .flags = 0, - .pInheritanceInfo = NULL, - }; - err = vkBeginCommandBuffer(demo->cmd, &cmd_buf_info); - demo_push_cb_label(demo, demo->cmd, NULL, "Prepare"); - assert(!err); - - demo_prepare_textures(demo); - demo_prepare_cube_data_buffers(demo); - - demo_prepare_descriptor_layout(demo); - - // Only need to know the format of the depth buffer before we create the renderpass - demo->depth.format = VK_FORMAT_D16_UNORM; - demo_prepare_render_pass(demo); - demo_prepare_pipeline(demo); - - for (uint32_t i = 0; i < FRAME_LAG; i++) { - err = vkAllocateCommandBuffers(demo->device, &cmd, &demo->submission_resources[i].cmd); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)demo->submission_resources[i].cmd, "MainCommandBuffer(%u)", - i); - } - - if (demo->separate_present_queue) { - const VkCommandPoolCreateInfo present_cmd_pool_info = { - .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, - .pNext = NULL, - .queueFamilyIndex = demo->present_queue_family_index, - .flags = 0, - }; - err = vkCreateCommandPool(demo->device, &present_cmd_pool_info, NULL, &demo->present_cmd_pool); - assert(!err); - const VkCommandBufferAllocateInfo present_cmd_info = { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, - .pNext = NULL, - .commandPool = demo->present_cmd_pool, - .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, - .commandBufferCount = 1, - }; - for (uint32_t i = 0; i < FRAME_LAG; i++) { - err = vkAllocateCommandBuffers(demo->device, &present_cmd_info, &demo->submission_resources[i].graphics_to_present_cmd); - assert(!err); - demo_name_object(demo, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)demo->submission_resources[i].graphics_to_present_cmd, - "GfxToPresent(%u)", i); - } - } - - demo_prepare_descriptor_pool(demo); - demo_prepare_descriptor_set(demo); - - demo_prepare_submission_sync_objects(demo); - - /* - * Prepare functions above may generate pipeline commands - * that need to be flushed before beginning the render loop. - */ - demo_pop_cb_label(demo, demo->cmd); // "Prepare" - demo_flush_init_cmd(demo); - if (demo->staging_texture.buffer) { - demo_destroy_texture(demo, &demo->staging_texture); - } - demo->current_submission_index = 0; - demo->initialized = true; - demo_prepare_swapchain(demo); -} - -static void demo_cleanup(struct demo *demo) { - uint32_t i; - - demo->initialized = false; - vkDeviceWaitIdle(demo->device); - - // Wait for fences from present operations - for (i = 0; i < FRAME_LAG; i++) { - vkWaitForFences(demo->device, 1, &demo->submission_resources[i].fence, VK_TRUE, UINT64_MAX); - } - - // If the window is currently minimized, demo_resize has already done some cleanup for us. - if (!demo->is_minimized) { - vkDestroyDescriptorPool(demo->device, demo->desc_pool, NULL); - - vkDestroyPipeline(demo->device, demo->pipeline, NULL); - vkDestroyPipelineCache(demo->device, demo->pipelineCache, NULL); - vkDestroyRenderPass(demo->device, demo->render_pass, NULL); - vkDestroyPipelineLayout(demo->device, demo->pipeline_layout, NULL); - vkDestroyDescriptorSetLayout(demo->device, demo->desc_layout, NULL); - - for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { - vkDestroyImageView(demo->device, demo->textures[i].view, NULL); - vkDestroyImage(demo->device, demo->textures[i].image, NULL); - vkFreeMemory(demo->device, demo->textures[i].mem, NULL); - vkDestroySampler(demo->device, demo->textures[i].sampler, NULL); - } - vkDestroySwapchainKHR(demo->device, demo->swapchain, NULL); - - vkDestroyImageView(demo->device, demo->depth.view, NULL); - vkDestroyImage(demo->device, demo->depth.image, NULL); - vkFreeMemory(demo->device, demo->depth.mem, NULL); - - for (i = 0; i < demo->swapchainImageCount; i++) { - vkDestroyImageView(demo->device, demo->swapchain_resources[i].view, NULL); - vkDestroyFramebuffer(demo->device, demo->swapchain_resources[i].framebuffer, NULL); - vkDestroySemaphore(demo->device, demo->swapchain_resources[i].draw_complete_semaphore, NULL); - if (demo->separate_present_queue) { - vkDestroySemaphore(demo->device, demo->swapchain_resources[i].image_ownership_semaphore, NULL); - } - } - - for (i = 0; i < FRAME_LAG; i++) { - vkDestroyFence(demo->device, demo->submission_resources[i].fence, NULL); - vkDestroySemaphore(demo->device, demo->submission_resources[i].image_acquired_semaphore, NULL); - vkDestroyBuffer(demo->device, demo->submission_resources[i].uniform_buffer, NULL); - vkUnmapMemory(demo->device, demo->submission_resources[i].uniform_memory); - vkFreeMemory(demo->device, demo->submission_resources[i].uniform_memory, NULL); - } - free(demo->queue_props); - vkDestroyCommandPool(demo->device, demo->cmd_pool, NULL); - - if (demo->separate_present_queue) { - vkDestroyCommandPool(demo->device, demo->present_cmd_pool, NULL); - } - } - vkDeviceWaitIdle(demo->device); - vkDestroyDevice(demo->device, NULL); - if (demo->validate) { - vkDestroyDebugUtilsMessengerEXT(demo->inst, demo->dbg_messenger, NULL); - } - vkDestroySurfaceKHR(demo->inst, demo->surface, NULL); - -#if defined(VK_USE_PLATFORM_XLIB_KHR) - if (demo->wsi_platform == WSI_PLATFORM_XLIB) { - XDestroyWindow(demo->xlib_display, demo->xlib_window); - XCloseDisplay(demo->xlib_display); - } -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - if (demo->wsi_platform == WSI_PLATFORM_XCB) { - xcb_destroy_window(demo->connection, demo->xcb_window); - xcb_disconnect(demo->connection); - free(demo->atom_wm_delete_window); - } -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - if (demo->wsi_platform == WSI_PLATFORM_WAYLAND) { - if (demo->keyboard) wl_keyboard_destroy(demo->keyboard); - if (demo->pointer) wl_pointer_destroy(demo->pointer); - if (demo->seat) wl_seat_destroy(demo->seat); - xdg_toplevel_destroy(demo->xdg_toplevel); - xdg_surface_destroy(demo->xdg_surface); - wl_surface_destroy(demo->window); - xdg_wm_base_destroy(demo->xdg_wm_base); - if (demo->xdg_decoration_mgr) { - zxdg_toplevel_decoration_v1_destroy(demo->toplevel_decoration); - zxdg_decoration_manager_v1_destroy(demo->xdg_decoration_mgr); - } - wl_compositor_destroy(demo->compositor); - wl_registry_destroy(demo->registry); - wl_display_disconnect(demo->wayland_display); - } -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - if (demo->wsi_platform == WSI_PLATFORM_DIRECTFB) { - demo->event_buffer->Release(demo->event_buffer); - demo->directfb_window->Release(demo->directfb_window); - demo->dfb->Release(demo->dfb); - } -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - if (demo->wsi_platform == WSI_PLATFORM_QNX) { - screen_destroy_event(demo->screen_event); - screen_destroy_window(demo->screen_window); - screen_destroy_context(demo->screen_context); - } -#endif - - vkDestroyInstance(demo->inst, NULL); - unload_vulkan_library(); -} - -static void demo_resize(struct demo *demo) { - uint32_t i; - - // Don't react to resize until after first initialization. - if (!demo->initialized) { - return; - } - - // Don't do anything if the surface has zero size, as vulkan disallows creating swapchains with zero area - // We use is_minimized to track this because zero size window usually occurs from minimizing - if (demo->width == 0 || demo->height == 0) { - demo->is_minimized = true; - return; - } else { - demo->is_minimized = false; - } - - // In order to properly resize the window, we must re-create the - // swapchain - // - // First, destroy the old swapchain and its associated resources, setting swapchain_ready to false to prevent draw from running - - if (demo->swapchain_ready) { - demo->swapchain_ready = false; - vkDeviceWaitIdle(demo->device); - - vkDestroyImageView(demo->device, demo->depth.view, NULL); - vkDestroyImage(demo->device, demo->depth.image, NULL); - vkFreeMemory(demo->device, demo->depth.mem, NULL); - memset(&(demo->depth), 0, sizeof(demo->depth)); - - for (i = 0; i < demo->swapchainImageCount; i++) { - vkDestroyImageView(demo->device, demo->swapchain_resources[i].view, NULL); - vkDestroyFramebuffer(demo->device, demo->swapchain_resources[i].framebuffer, NULL); - vkDestroySemaphore(demo->device, demo->swapchain_resources[i].draw_complete_semaphore, NULL); - if (demo->separate_present_queue) { - vkDestroySemaphore(demo->device, demo->swapchain_resources[i].image_ownership_semaphore, NULL); - } - } - memset(&(demo->swapchain_resources), 0, sizeof(SwapchainImageResources) * MAX_SWAPCHAIN_IMAGE_COUNT); - } - - // Second, recreate the swapchain, depth buffer, and framebuffers. - demo_prepare_swapchain(demo); -} - -// On MS-Windows, make this a global, so it's available to WndProc() -struct demo demo; - -#if defined(VK_USE_PLATFORM_WIN32_KHR) -static void demo_run(struct demo *demo) { - if (!demo->initialized || !demo->swapchain_ready) return; - - demo_draw(demo); - if (!demo->is_minimized) { - demo->curFrame++; - } - if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount) { - PostQuitMessage(validation_error); - } -} - -// MS-Windows event handling function: -LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - switch (uMsg) { - case WM_CLOSE: - PostQuitMessage(validation_error); - break; - case WM_PAINT: - // The validation callback calls MessageBox which can generate paint - // events - don't make more Vulkan calls if we got here from the - // callback - if (!in_callback) { - demo_run(&demo); - } - break; - case WM_GETMINMAXINFO: // set window's minimum size - ((MINMAXINFO *)lParam)->ptMinTrackSize = demo.minsize; - return 0; - case WM_ERASEBKGND: - return 1; - case WM_SIZE: - // Resize the application to the new window size, except when - // it was minimized. Vulkan doesn't support images or swapchains - // with width=0 and height=0. - if (wParam != SIZE_MINIMIZED) { - demo.width = lParam & 0xffff; - demo.height = (lParam & 0xffff0000) >> 16; - demo_resize(&demo); - } - break; - case WM_KEYDOWN: - switch (wParam) { - case VK_ESCAPE: - PostQuitMessage(validation_error); - break; - case VK_LEFT: - demo.spin_angle -= demo.spin_increment; - break; - case VK_RIGHT: - demo.spin_angle += demo.spin_increment; - break; - case VK_SPACE: - demo.pause = !demo.pause; - break; - } - return 0; - default: - break; - } - return (DefWindowProc(hWnd, uMsg, wParam, lParam)); -} - -static void demo_create_window(struct demo *demo) { - WNDCLASSEX win_class; - - // Initialize the window class structure: - win_class.cbSize = sizeof(WNDCLASSEX); - win_class.style = CS_HREDRAW | CS_VREDRAW; - win_class.lpfnWndProc = WndProc; - win_class.cbClsExtra = 0; - win_class.cbWndExtra = 0; - win_class.hInstance = demo->connection; // hInstance - win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION); - win_class.hCursor = LoadCursor(NULL, IDC_ARROW); - win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); - win_class.lpszMenuName = NULL; - win_class.lpszClassName = demo->name; - win_class.hIconSm = LoadIcon(NULL, IDI_WINLOGO); - // Register window class: - if (!RegisterClassEx(&win_class)) { - // It didn't work, so try to give a useful error: - printf("Unexpected error trying to start the application!\n"); - fflush(stdout); - exit(1); - } - // Create window with the registered class: - RECT wr = {0, 0, demo->width, demo->height}; - AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); - demo->window = CreateWindowEx(0, - demo->name, // class name - demo->name, // app name - WS_OVERLAPPEDWINDOW | // window style - WS_VISIBLE | WS_SYSMENU, - 100, 100, // x/y coords - wr.right - wr.left, // width - wr.bottom - wr.top, // height - NULL, // handle to parent - NULL, // handle to menu - demo->connection, // hInstance - NULL); // no extra parameters - if (!demo->window) { - // It didn't work, so try to give a useful error: - printf("Cannot create a window in which to draw!\n"); - fflush(stdout); - exit(1); - } - // Window client area size must be at least 1 pixel high, to prevent crash. - demo->minsize.x = GetSystemMetrics(SM_CXMINTRACK); - demo->minsize.y = GetSystemMetrics(SM_CYMINTRACK) + 1; -} -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) -static void demo_create_xlib_window(struct demo *demo) { - const char *display_envar = getenv("DISPLAY"); - if (display_envar == NULL || display_envar[0] == '\0') { - printf("Environment variable DISPLAY requires a valid value.\nExiting ...\n"); - fflush(stdout); - exit(1); - } - - XInitThreads(); - demo->xlib_display = XOpenDisplay(NULL); - long visualMask = VisualScreenMask; - int numberOfVisuals; - XVisualInfo vInfoTemplate = {}; - vInfoTemplate.screen = DefaultScreen(demo->xlib_display); - XVisualInfo *visualInfo = XGetVisualInfo(demo->xlib_display, visualMask, &vInfoTemplate, &numberOfVisuals); - - Colormap colormap = - XCreateColormap(demo->xlib_display, RootWindow(demo->xlib_display, vInfoTemplate.screen), visualInfo->visual, AllocNone); - - XSetWindowAttributes windowAttributes = {}; - windowAttributes.colormap = colormap; - windowAttributes.background_pixel = 0xFFFFFFFF; - windowAttributes.border_pixel = 0; - windowAttributes.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask | ExposureMask; - - demo->xlib_window = XCreateWindow(demo->xlib_display, RootWindow(demo->xlib_display, vInfoTemplate.screen), 0, 0, demo->width, - demo->height, 0, visualInfo->depth, InputOutput, visualInfo->visual, - CWBackPixel | CWBorderPixel | CWEventMask | CWColormap, &windowAttributes); - - XSelectInput(demo->xlib_display, demo->xlib_window, ExposureMask | KeyPressMask); - XMapWindow(demo->xlib_display, demo->xlib_window); - XFlush(demo->xlib_display); - demo->xlib_wm_delete_window = XInternAtom(demo->xlib_display, "WM_DELETE_WINDOW", False); - XSetWMProtocols(demo->xlib_display, demo->xlib_window, &demo->xlib_wm_delete_window, 1); -} -static void demo_handle_xlib_event(struct demo *demo, const XEvent *event) { - switch (event->type) { - case ClientMessage: - if ((Atom)event->xclient.data.l[0] == demo->xlib_wm_delete_window) demo->quit = true; - break; - case KeyPress: - switch (event->xkey.keycode) { - case 0x9: // Escape - demo->quit = true; - break; - case 0x71: // left arrow key - demo->spin_angle -= demo->spin_increment; - break; - case 0x72: // right arrow key - demo->spin_angle += demo->spin_increment; - break; - case 0x41: // space bar - demo->pause = !demo->pause; - break; - } - break; - case ConfigureNotify: - if ((demo->width != event->xconfigure.width) || (demo->height != event->xconfigure.height)) { - demo->width = event->xconfigure.width; - demo->height = event->xconfigure.height; - demo_resize(demo); - } - break; - default: - break; - } -} - -static void demo_run_xlib(struct demo *demo) { - while (!demo->quit) { - XEvent event; - - if (demo->pause) { - XNextEvent(demo->xlib_display, &event); - demo_handle_xlib_event(demo, &event); - } - while (XPending(demo->xlib_display) > 0) { - XNextEvent(demo->xlib_display, &event); - demo_handle_xlib_event(demo, &event); - } - if (demo->initialized && demo->swapchain_ready) { - demo_draw(demo); - if (!demo->is_minimized) { - demo->curFrame++; - } - if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount) demo->quit = true; - } - } -} -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) -static void demo_handle_xcb_event(struct demo *demo, const xcb_generic_event_t *event) { - uint8_t event_code = event->response_type & 0x7f; - switch (event_code) { - case XCB_EXPOSE: - // TODO: Resize window - break; - case XCB_CLIENT_MESSAGE: - if ((*(xcb_client_message_event_t *)event).data.data32[0] == (*demo->atom_wm_delete_window).atom) { - demo->quit = true; - } - break; - case XCB_KEY_RELEASE: { - const xcb_key_release_event_t *key = (const xcb_key_release_event_t *)event; - - switch (key->detail) { - case 0x9: // Escape - demo->quit = true; - break; - case 0x71: // left arrow key - demo->spin_angle -= demo->spin_increment; - break; - case 0x72: // right arrow key - demo->spin_angle += demo->spin_increment; - break; - case 0x41: // space bar - demo->pause = !demo->pause; - break; - } - } break; - case XCB_CONFIGURE_NOTIFY: { - const xcb_configure_notify_event_t *cfg = (const xcb_configure_notify_event_t *)event; - if ((demo->width != cfg->width) || (demo->height != cfg->height)) { - demo->width = cfg->width; - demo->height = cfg->height; - demo_resize(demo); - } - } break; - default: - break; - } -} - -static void demo_run_xcb(struct demo *demo) { - xcb_flush(demo->connection); - - while (!demo->quit) { - xcb_generic_event_t *event; - - if (demo->pause) { - event = xcb_wait_for_event(demo->connection); - } else { - event = xcb_poll_for_event(demo->connection); - } - while (event) { - demo_handle_xcb_event(demo, event); - free(event); - event = xcb_poll_for_event(demo->connection); - } - if (demo->initialized && demo->swapchain_ready) { - demo_draw(demo); - if (!demo->is_minimized) { - demo->curFrame++; - } - if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount) demo->quit = true; - } - } -} - -static void demo_create_xcb_window(struct demo *demo) { - uint32_t value_mask, value_list[32]; - - demo->xcb_window = xcb_generate_id(demo->connection); - - value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; - value_list[0] = demo->screen->black_pixel; - value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY; - - xcb_create_window(demo->connection, XCB_COPY_FROM_PARENT, demo->xcb_window, demo->screen->root, 0, 0, demo->width, demo->height, - 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, demo->screen->root_visual, value_mask, value_list); - - char *name = "Vkcube X11"; - xcb_intern_atom_cookie_t net_wm_name_cookie = xcb_intern_atom(demo->connection, 0, strlen("_NET_WM_NAME"), "_NET_WM_NAME"); - xcb_intern_atom_cookie_t utf8_string_cookie = xcb_intern_atom(demo->connection, 0, strlen("UTF8_STRING"), "UTF8_STRING"); - xcb_intern_atom_reply_t *net_wm_name_reply = xcb_intern_atom_reply(demo->connection, net_wm_name_cookie, NULL); - xcb_intern_atom_reply_t *utf8_string_reply = xcb_intern_atom_reply(demo->connection, utf8_string_cookie, NULL); - xcb_change_property(demo->connection, XCB_PROP_MODE_REPLACE, - demo->xcb_window, net_wm_name_reply->atom, - utf8_string_reply->atom, 8, strlen(name), name); - - /* Magic code that will send notification when window is destroyed */ - xcb_intern_atom_cookie_t cookie = xcb_intern_atom(demo->connection, 1, 12, "WM_PROTOCOLS"); - xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(demo->connection, cookie, 0); - - xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(demo->connection, 0, 16, "WM_DELETE_WINDOW"); - demo->atom_wm_delete_window = xcb_intern_atom_reply(demo->connection, cookie2, 0); - - xcb_change_property(demo->connection, XCB_PROP_MODE_REPLACE, demo->xcb_window, (*reply).atom, 4, 32, 1, - &(*demo->atom_wm_delete_window).atom); - free(reply); - - xcb_map_window(demo->connection, demo->xcb_window); - - // Force the x/y coordinates to 100,100 results are identical in consecutive - // runs - const uint32_t coords[] = {100, 100}; - xcb_configure_window(demo->connection, demo->xcb_window, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, coords); -} -// VK_USE_PLATFORM_XCB_KHR -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -static void demo_run(struct demo *demo) { - while (!demo->quit) { - // Flush any commands to the server - wl_display_flush(demo->wayland_display); - - if (demo->pause) { - // block and wait for input - wl_display_dispatch(demo->wayland_display); - } else { - // Lock the display event queue in case the driver is doing something on another thread - // while we wait, keep pumping events - while (wl_display_prepare_read(demo->wayland_display) != 0) { - wl_display_dispatch_pending(demo->wayland_display); - } - // Actually do the read from the socket - wl_display_read_events(demo->wayland_display); - - // Pump events - wl_display_dispatch_pending(demo->wayland_display); - if (demo->initialized && demo->swapchain_ready) { - demo_draw(demo); - if (!demo->is_minimized) { - demo->curFrame++; - } - if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount) demo->quit = true; - } - } - } -} - -static void handle_surface_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial) { - struct demo *demo = (struct demo *)data; - xdg_surface_ack_configure(xdg_surface, serial); - demo->xdg_surface_has_been_configured = 1; - if (demo->pending_width > 0) { - demo->width = demo->pending_width; - } - if (demo->pending_height > 0) { - demo->height = demo->pending_height; - } - demo_resize(demo); -} - -static const struct xdg_surface_listener xdg_surface_listener = {handle_surface_configure}; - -static void handle_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel UNUSED, int32_t width, int32_t height, - struct wl_array *states UNUSED) { - struct demo *demo = (struct demo *)data; - /* zero values imply the program may choose its own size, so in that case - * stay with the existing value (which on startup is the default) */ - if (width > 0) { - demo->pending_width = width; - } - if (height > 0) { - demo->pending_height = height; - } - /* This should be followed by a surface configure */ -} - -static void handle_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel UNUSED) { - struct demo *demo = (struct demo *)data; - demo->quit = true; -} - -static const struct xdg_toplevel_listener xdg_toplevel_listener = {handle_toplevel_configure, handle_toplevel_close}; - -static void demo_create_wayland_window(struct demo *demo) { - if (!demo->xdg_wm_base) { - printf("Compositor did not provide the standard protocol xdg-wm-base\n"); - fflush(stdout); - exit(1); - } - - demo->window = wl_compositor_create_surface(demo->compositor); - if (!demo->window) { - printf("Can not create wayland_surface from compositor!\n"); - fflush(stdout); - exit(1); - } - - demo->xdg_surface = xdg_wm_base_get_xdg_surface(demo->xdg_wm_base, demo->window); - if (!demo->xdg_surface) { - printf("Can not get xdg_surface from wayland_surface!\n"); - fflush(stdout); - exit(1); - } - demo->xdg_toplevel = xdg_surface_get_toplevel(demo->xdg_surface); - if (!demo->xdg_toplevel) { - printf("Can not allocate xdg_toplevel for xdg_surface!\n"); - fflush(stdout); - exit(1); - } - xdg_surface_add_listener(demo->xdg_surface, &xdg_surface_listener, demo); - xdg_toplevel_add_listener(demo->xdg_toplevel, &xdg_toplevel_listener, demo); - xdg_toplevel_set_title(demo->xdg_toplevel, APP_SHORT_NAME); - if (demo->xdg_decoration_mgr) { - // if supported, let the compositor render titlebars for us - demo->toplevel_decoration = - zxdg_decoration_manager_v1_get_toplevel_decoration(demo->xdg_decoration_mgr, demo->xdg_toplevel); - zxdg_toplevel_decoration_v1_set_mode(demo->toplevel_decoration, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); - } - - wl_surface_commit(demo->window); -} -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -static void demo_create_directfb_window(struct demo *demo) { - DFBResult ret; - - ret = DirectFBInit(NULL, NULL); - if (ret) { - printf("DirectFBInit failed to initialize DirectFB!\n"); - fflush(stdout); - exit(1); - } - - ret = DirectFBCreate(&demo->dfb); - if (ret) { - printf("DirectFBCreate failed to create main interface of DirectFB!\n"); - fflush(stdout); - exit(1); - } - - DFBSurfaceDescription desc; - desc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT; - desc.caps = DSCAPS_PRIMARY; - desc.width = demo->width; - desc.height = demo->height; - ret = demo->dfb->CreateSurface(demo->dfb, &desc, &demo->directfb_window); - if (ret) { - printf("CreateSurface failed to create DirectFB surface interface!\n"); - fflush(stdout); - exit(1); - } - - ret = demo->dfb->CreateInputEventBuffer(demo->dfb, DICAPS_KEYS, DFB_FALSE, &demo->event_buffer); - if (ret) { - printf("CreateInputEventBuffer failed to create DirectFB event buffer interface!\n"); - fflush(stdout); - exit(1); - } -} - -static void demo_handle_directfb_event(struct demo *demo, const DFBInputEvent *event) { - if (event->type != DIET_KEYPRESS) return; - switch (event->key_symbol) { - case DIKS_ESCAPE: // Escape - demo->quit = true; - break; - case DIKS_CURSOR_LEFT: // left arrow key - demo->spin_angle -= demo->spin_increment; - break; - case DIKS_CURSOR_RIGHT: // right arrow key - demo->spin_angle += demo->spin_increment; - break; - case DIKS_SPACE: // space bar - demo->pause = !demo->pause; - break; - default: - break; - } -} - -static void demo_run_directfb(struct demo *demo) { - while (!demo->quit) { - DFBInputEvent event; - - if (demo->pause) { - demo->event_buffer->WaitForEvent(demo->event_buffer); - if (!demo->event_buffer->GetEvent(demo->event_buffer, DFB_EVENT(&event))) demo_handle_directfb_event(demo, &event); - } else { - if (!demo->event_buffer->GetEvent(demo->event_buffer, DFB_EVENT(&event))) demo_handle_directfb_event(demo, &event); - if (demo->initialized && demo->swapchain_ready) { - demo_draw(demo); - if (!demo->is_minimized) { - demo->curFrame++; - } - if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount) demo->quit = true; - } - } - } -} -#endif -#if defined(VK_USE_PLATFORM_ANDROID_KHR) -static void demo_run(struct demo *demo) { - if (!demo->initialized || !demo->swapchain_ready) return; - - demo_draw(demo); - if (!demo->is_minimized) { - demo->curFrame++; - } -} -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) -static void demo_run(struct demo *demo) { - if (!demo->initialized || !demo->swapchain_ready) return; - - demo_draw(demo); - if (!demo->is_minimized) { - demo->curFrame++; - } - if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount) { - demo->quit = TRUE; - } -} -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -static VkResult demo_create_display_surface(struct demo *demo) { - VkResult U_ASSERT_ONLY err; - uint32_t display_count; - uint32_t mode_count; - uint32_t plane_count; - VkDisplayPropertiesKHR display_props; - VkDisplayKHR display; - VkDisplayModePropertiesKHR mode_props; - VkDisplayPlanePropertiesKHR *plane_props; - VkBool32 found_plane = VK_FALSE; - uint32_t plane_index; - VkExtent2D image_extent; - VkDisplaySurfaceCreateInfoKHR create_info; - - // Get the first display - display_count = 1; - err = vkGetPhysicalDeviceDisplayPropertiesKHR(demo->gpu, &display_count, &display_props); - assert(!err || (err == VK_INCOMPLETE)); - - display = display_props.display; - - // Get the first mode of the display - err = vkGetDisplayModePropertiesKHR(demo->gpu, display, &mode_count, NULL); - assert(!err); - - if (mode_count == 0) { - printf("Cannot find any mode for the display!\n"); - fflush(stdout); - exit(1); - } - - mode_count = 1; - err = vkGetDisplayModePropertiesKHR(demo->gpu, display, &mode_count, &mode_props); - assert(!err || (err == VK_INCOMPLETE)); - - // Get the list of planes - err = vkGetPhysicalDeviceDisplayPlanePropertiesKHR(demo->gpu, &plane_count, NULL); - assert(!err); - - if (plane_count == 0) { - printf("Cannot find any plane!\n"); - fflush(stdout); - exit(1); - } - - plane_props = malloc(sizeof(VkDisplayPlanePropertiesKHR) * plane_count); - assert(plane_props); - - err = vkGetPhysicalDeviceDisplayPlanePropertiesKHR(demo->gpu, &plane_count, plane_props); - assert(!err); - - // Find a plane compatible with the display - for (plane_index = 0; plane_index < plane_count; plane_index++) { - uint32_t supported_count; - VkDisplayKHR *supported_displays; - - // Disqualify planes that are bound to a different display - if ((plane_props[plane_index].currentDisplay != VK_NULL_HANDLE) && (plane_props[plane_index].currentDisplay != display)) { - continue; - } - - err = vkGetDisplayPlaneSupportedDisplaysKHR(demo->gpu, plane_index, &supported_count, NULL); - assert(!err); - - if (supported_count == 0) { - continue; - } - - supported_displays = malloc(sizeof(VkDisplayKHR) * supported_count); - assert(supported_displays); - - err = vkGetDisplayPlaneSupportedDisplaysKHR(demo->gpu, plane_index, &supported_count, supported_displays); - assert(!err); - - for (uint32_t i = 0; i < supported_count; i++) { - if (supported_displays[i] == display) { - found_plane = VK_TRUE; - break; - } - } - - free(supported_displays); - - if (found_plane) { - break; - } - } - - if (!found_plane) { - printf("Cannot find a plane compatible with the display!\n"); - fflush(stdout); - exit(1); - } - - VkDisplayPlaneCapabilitiesKHR planeCaps; - vkGetDisplayPlaneCapabilitiesKHR(demo->gpu, mode_props.displayMode, plane_index, &planeCaps); - // Find a supported alpha mode - VkDisplayPlaneAlphaFlagBitsKHR alphaMode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR; - VkDisplayPlaneAlphaFlagBitsKHR alphaModes[4] = { - VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR, - VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR, - VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR, - VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR, - }; - for (uint32_t i = 0; i < sizeof(alphaModes); i++) { - if (planeCaps.supportedAlpha & alphaModes[i]) { - alphaMode = alphaModes[i]; - break; - } - } - image_extent.width = mode_props.parameters.visibleRegion.width; - image_extent.height = mode_props.parameters.visibleRegion.height; - - create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR; - create_info.pNext = NULL; - create_info.flags = 0; - create_info.displayMode = mode_props.displayMode; - create_info.planeIndex = plane_index; - create_info.planeStackIndex = plane_props[plane_index].currentStackIndex; - create_info.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; - create_info.alphaMode = alphaMode; - create_info.globalAlpha = 1.0f; - create_info.imageExtent = image_extent; - - free(plane_props); - - return vkCreateDisplayPlaneSurfaceKHR(demo->inst, &create_info, NULL, &demo->surface); -} - -static void demo_run_display(struct demo *demo) { - while (!demo->quit) { - demo_draw(demo); - demo->curFrame++; - - if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount) { - demo->quit = true; - } - } -} -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - -#include <sys/keycodes.h> - -static void demo_run(struct demo *demo) { - int size[2] = {0, 0}; - screen_window_t win; - int val; - int rc; - - while (!demo->quit) { - while (!screen_get_event(demo->screen_context, demo->screen_event, demo->pause ? ~0 : 0)) { - rc = screen_get_event_property_iv(demo->screen_event, SCREEN_PROPERTY_TYPE, &val); - if (rc) { - printf("Cannot get SCREEN_PROPERTY_TYPE of the event! (%s)\n", strerror(errno)); - fflush(stdout); - demo->quit = true; - break; - } - if (val == SCREEN_EVENT_NONE) { - break; - } - switch (val) { - case SCREEN_EVENT_KEYBOARD: - rc = screen_get_event_property_iv(demo->screen_event, SCREEN_PROPERTY_FLAGS, &val); - if (rc) { - printf("Cannot get SCREEN_PROPERTY_FLAGS of the event! (%s)\n", strerror(errno)); - fflush(stdout); - demo->quit = true; - break; - } - if (val & KEY_DOWN) { - rc = screen_get_event_property_iv(demo->screen_event, SCREEN_PROPERTY_SYM, &val); - if (rc) { - printf("Cannot get SCREEN_PROPERTY_SYM of the event! (%s)\n", strerror(errno)); - fflush(stdout); - demo->quit = true; - break; - } - switch (val) { - case KEYCODE_ESCAPE: - demo->quit = true; - break; - case KEYCODE_SPACE: - demo->pause = !demo->pause; - break; - case KEYCODE_LEFT: - demo->spin_angle -= demo->spin_increment; - break; - case KEYCODE_RIGHT: - demo->spin_angle += demo->spin_increment; - break; - default: - break; - } - } - break; - case SCREEN_EVENT_PROPERTY: - rc = screen_get_event_property_pv(demo->screen_event, SCREEN_PROPERTY_WINDOW, (void **)&win); - if (rc) { - printf("Cannot get SCREEN_PROPERTY_WINDOW of the event! (%s)\n", strerror(errno)); - fflush(stdout); - demo->quit = true; - break; - } - rc = screen_get_event_property_iv(demo->screen_event, SCREEN_PROPERTY_NAME, &val); - if (rc) { - printf("Cannot get SCREEN_PROPERTY_NAME of the event! (%s)\n", strerror(errno)); - fflush(stdout); - demo->quit = true; - break; - } - if (win == demo->screen_window) { - switch (val) { - case SCREEN_PROPERTY_SIZE: - rc = screen_get_window_property_iv(win, SCREEN_PROPERTY_SIZE, size); - if (rc) { - printf("Cannot get SCREEN_PROPERTY_SIZE of the window in the event! (%s)\n", strerror(errno)); - fflush(stdout); - demo->quit = true; - break; - } - demo->width = size[0]; - demo->height = size[1]; - demo_resize(demo); - break; - default: - /* We are not interested in any other events for now */ - break; - } - } - break; - } - } - - if (demo->pause || !demo->initialized || !demo->swapchain_ready) { - } else { - demo_draw(demo); - if (!demo->is_minimized) { - demo->curFrame++; - } - if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount) { - demo->quit = true; - } - } - } -} - -static void demo_create_screen_window(struct demo *demo) { - const char *idstr = APP_SHORT_NAME; - int size[2]; - int usage = SCREEN_USAGE_VULKAN; - int rc; - - rc = screen_create_context(&demo->screen_context, 0); - if (rc) { - printf("Cannot create QNX Screen context!\n"); - fflush(stdout); - exit(EXIT_FAILURE); - } - rc = screen_create_window(&demo->screen_window, demo->screen_context); - if (rc) { - printf("Cannot create QNX Screen window!\n"); - fflush(stdout); - exit(EXIT_FAILURE); - } - rc = screen_create_event(&demo->screen_event); - if (rc) { - printf("Cannot create QNX Screen event!\n"); - fflush(stdout); - exit(EXIT_FAILURE); - } - - /* Set window caption */ - screen_set_window_property_cv(demo->screen_window, SCREEN_PROPERTY_ID_STRING, strlen(idstr), idstr); - - /* Setup VULKAN usage flags */ - rc = screen_set_window_property_iv(demo->screen_window, SCREEN_PROPERTY_USAGE, &usage); - if (rc) { - printf("Cannot set SCREEN_USAGE_VULKAN flag!\n"); - fflush(stdout); - exit(EXIT_FAILURE); - } - - /* Setup window size */ - if ((demo->width == 0) || (demo->height == 0)) { - /* Obtain automatically set window size provided by WM */ - rc = screen_get_window_property_iv(demo->screen_window, SCREEN_PROPERTY_SIZE, size); - if (rc) { - printf("Cannot obtain current window size!\n"); - fflush(stdout); - exit(EXIT_FAILURE); - } - demo->width = size[0]; - demo->height = size[1]; - } else { - size[0] = demo->width; - size[1] = demo->height; - rc = screen_set_window_property_iv(demo->screen_window, SCREEN_PROPERTY_SIZE, size); - if (rc) { - printf("Cannot set window size!\n"); - fflush(stdout); - exit(EXIT_FAILURE); - } - } -} -#endif - -/* - * Return 1 (true) if all layer names specified in check_names - * can be found in given layer properties. - */ -static VkBool32 demo_check_layers(uint32_t check_count, char **check_names, uint32_t layer_count, VkLayerProperties *layers) { - for (uint32_t i = 0; i < check_count; i++) { - VkBool32 found = 0; - for (uint32_t j = 0; j < layer_count; j++) { - if (!strcmp(check_names[i], layers[j].layerName)) { - found = 1; - break; - } - } - if (!found) { - fprintf(stderr, "Cannot find layer: %s\n", check_names[i]); - return 0; - } - } - return 1; -} -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -int find_display_gpu(int gpu_number, uint32_t gpu_count, VkPhysicalDevice *physical_devices) { - uint32_t display_count = 0; - VkResult U_ASSERT_ONLY result; - int gpu_return = gpu_number; - if (gpu_number >= 0) { - result = vkGetPhysicalDeviceDisplayPropertiesKHR(physical_devices[gpu_number], &display_count, NULL); - assert(!result); - } else { - for (uint32_t i = 0; i < gpu_count; i++) { - result = vkGetPhysicalDeviceDisplayPropertiesKHR(physical_devices[i], &display_count, NULL); - assert(!result); - if (display_count) { - gpu_return = i; - break; - } - } - } - if (display_count > 0) - return gpu_return; - else - return -1; -} -#endif - -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -static void pointer_handle_enter(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t sx, - wl_fixed_t sy) {} - -static void pointer_handle_leave(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface) {} - -static void pointer_handle_motion(void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy) {} - -static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, - uint32_t state) { - struct demo *demo = data; - if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED) { - xdg_toplevel_move(demo->xdg_toplevel, demo->seat, serial); - } -} - -static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) {} - -static const struct wl_pointer_listener pointer_listener = { - pointer_handle_enter, pointer_handle_leave, pointer_handle_motion, pointer_handle_button, pointer_handle_axis, -}; - -static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size) {} - -static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, - struct wl_array *keys) {} - -static void keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface) {} - -static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, - uint32_t state) { - if (state != WL_KEYBOARD_KEY_STATE_RELEASED) return; - struct demo *demo = data; - switch (key) { - case KEY_ESC: // Escape - demo->quit = true; - break; - case KEY_LEFT: // left arrow key - demo->spin_angle -= demo->spin_increment; - break; - case KEY_RIGHT: // right arrow key - demo->spin_angle += demo->spin_increment; - break; - case KEY_SPACE: // space bar - demo->pause = !demo->pause; - break; - } -} - -static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, - uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {} - -static const struct wl_keyboard_listener keyboard_listener = { - keyboard_handle_keymap, keyboard_handle_enter, keyboard_handle_leave, keyboard_handle_key, keyboard_handle_modifiers, -}; - -static void seat_handle_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps) { - // Subscribe to pointer events - struct demo *demo = data; - if ((caps & WL_SEAT_CAPABILITY_POINTER) && !demo->pointer) { - demo->pointer = wl_seat_get_pointer(seat); - wl_pointer_add_listener(demo->pointer, &pointer_listener, demo); - } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && demo->pointer) { - wl_pointer_destroy(demo->pointer); - demo->pointer = NULL; - } - // Subscribe to keyboard events - if (caps & WL_SEAT_CAPABILITY_KEYBOARD) { - demo->keyboard = wl_seat_get_keyboard(seat); - wl_keyboard_add_listener(demo->keyboard, &keyboard_listener, demo); - } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && demo->keyboard) { - wl_keyboard_destroy(demo->keyboard); - demo->keyboard = NULL; - } -} - -static const struct wl_seat_listener seat_listener = { - seat_handle_capabilities, -}; - -static void wm_base_ping(void *data UNUSED, struct xdg_wm_base *xdg_wm_base, uint32_t serial) { - xdg_wm_base_pong(xdg_wm_base, serial); -} - -static const struct xdg_wm_base_listener wm_base_listener = {wm_base_ping}; - -static void registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, - uint32_t version UNUSED) { - struct demo *demo = data; - // pickup wayland objects when they appear - if (strcmp(interface, wl_compositor_interface.name) == 0) { - uint32_t minVersion = version < 4 ? version : 4; - demo->compositor = wl_registry_bind(registry, id, &wl_compositor_interface, minVersion); - if (demo->VK_KHR_incremental_present_enabled && minVersion < 4) { - fprintf(stderr, "Wayland compositor doesn't support VK_KHR_incremental_present, disabling.\n"); - demo->VK_KHR_incremental_present_enabled = false; - } - } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) { - demo->xdg_wm_base = wl_registry_bind(registry, id, &xdg_wm_base_interface, 1); - xdg_wm_base_add_listener(demo->xdg_wm_base, &wm_base_listener, NULL); - } else if (strcmp(interface, wl_seat_interface.name) == 0) { - demo->seat = wl_registry_bind(registry, id, &wl_seat_interface, 1); - wl_seat_add_listener(demo->seat, &seat_listener, demo); - } else if (strcmp(interface, zxdg_decoration_manager_v1_interface.name) == 0) { - demo->xdg_decoration_mgr = wl_registry_bind(registry, id, &zxdg_decoration_manager_v1_interface, 1); - } -} - -static void registry_handle_global_remove(void *data UNUSED, struct wl_registry *registry UNUSED, uint32_t name UNUSED) {} - -static const struct wl_registry_listener registry_listener = {registry_handle_global, registry_handle_global_remove}; -#endif - -#if defined(VK_USE_PLATFORM_XCB_KHR) -static const char *demo_init_xcb_connection(struct demo *demo) { - demo->xcb_library = initialize_xcb(); - if (NULL == demo->xcb_library) { - return "Cannot load XCB dynamic library."; - } - - const xcb_setup_t *setup; - xcb_screen_iterator_t iter; - int scr; - - const char *display_envar = getenv("DISPLAY"); - if (display_envar == NULL || display_envar[0] == '\0') { - return "Environment variable DISPLAY requires a valid value.n"; - } - - demo->connection = xcb_connect(NULL, &scr); - if (xcb_connection_has_error(demo->connection) > 0) { - return "Cannot connect to XCB."; - } - - setup = xcb_get_setup(demo->connection); - iter = xcb_setup_roots_iterator(setup); - while (scr-- > 0) xcb_screen_next(&iter); - - demo->screen = iter.data; - return NULL; -} -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) -static const char *demo_init_xlib_connection(struct demo *demo) { - demo->xlib_library = initialize_xlib(); - if (NULL == demo->xlib_library) { - return "Cannot load XLIB dynamic library."; - } - return NULL; -} -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -static const char *demo_init_wayland_connection(struct demo *demo) { - demo->wayland_library = initialize_wayland(); - if (NULL == demo->wayland_library) { - return "Cannot load wayland dynamic library."; - } - - demo->wayland_display = wl_display_connect(NULL); - - if (demo->wayland_display == NULL) { - return "Cannot connect to wayland."; - } - - demo->registry = wl_display_get_registry(demo->wayland_display); - wl_registry_add_listener(demo->registry, ®istry_listener, demo); - wl_display_roundtrip(demo->wayland_display); - return NULL; -} -#endif - -// Check that WSI platforms are available - only necessary when multiple WSI platforms exist, like on linux -// If the wsi_platform is AUTO, this function also sets wsi_platform to the first available WSI platform -// Otherwise, it errors out if the specified wsi_platform isn't available -static void demo_check_and_set_wsi_platform(struct demo *demo) { -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - if (demo->wsi_platform == WSI_PLATFORM_WAYLAND || demo->wsi_platform == WSI_PLATFORM_AUTO) { - bool wayland_extension_available = false; - for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { - if (strcmp(demo->extension_names[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) { - wayland_extension_available = true; - break; - } - } - if (wayland_extension_available) { - const char *error_msg = demo_init_wayland_connection(demo); - if (error_msg != NULL) { - if (demo->wsi_platform == WSI_PLATFORM_WAYLAND) { - fprintf(stderr, "%s\nExiting ...\n", error_msg); - fflush(stdout); - exit(1); - } - } else { - demo->wsi_platform = WSI_PLATFORM_WAYLAND; - return; - } - } - } -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - if (demo->wsi_platform == WSI_PLATFORM_XCB || demo->wsi_platform == WSI_PLATFORM_AUTO) { - bool xcb_extension_available = false; - for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { - if (strcmp(demo->extension_names[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) { - xcb_extension_available = true; - break; - } - } - if (xcb_extension_available) { - const char *error_msg = demo_init_xcb_connection(demo); - if (error_msg != NULL) { - if (demo->wsi_platform == WSI_PLATFORM_XCB) { - fprintf(stderr, "%s\nExiting ...\n", error_msg); - fflush(stdout); - exit(1); - } - } else { - demo->wsi_platform = WSI_PLATFORM_XCB; - return; - } - } - } -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - if (demo->wsi_platform == WSI_PLATFORM_XLIB || demo->wsi_platform == WSI_PLATFORM_AUTO) { - bool xlib_extension_available = false; - for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { - if (strcmp(demo->extension_names[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) { - xlib_extension_available = true; - break; - } - } - if (xlib_extension_available) { - const char *error_msg = demo_init_xlib_connection(demo); - if (error_msg != NULL) { - if (demo->wsi_platform == WSI_PLATFORM_XLIB) { - fprintf(stderr, "%s\nExiting ...\n", error_msg); - fflush(stdout); - exit(1); - } - } else { - demo->wsi_platform = WSI_PLATFORM_XLIB; - return; - } - } - } -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - if (demo->wsi_platform == WSI_PLATFORM_DIRECTFB || demo->wsi_platform == WSI_PLATFORM_AUTO) { - bool direftfb_extension_available = false; - for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { - if (strcmp(demo->extension_names[i], VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME) == 0) { - direftfb_extension_available = true; - break; - } - } - if (direftfb_extension_available) { - // Because DirectFB is still linked in, we can assume that it works if we got here - demo->wsi_platform = WSI_PLATFORM_DIRECTFB; - return; - } - } -#endif -#if defined(VK_USE_PLATFORM_WIN32_KHR) - if (demo->wsi_platform == WSI_PLATFORM_WIN32 || demo->wsi_platform == WSI_PLATFORM_AUTO) { - bool win32_extension_available = false; - for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { - if (strcmp(demo->extension_names[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) { - win32_extension_available = true; - break; - } - } - if (win32_extension_available) { - demo->wsi_platform = WSI_PLATFORM_WIN32; - return; - } - } -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) - if (demo->wsi_platform == WSI_PLATFORM_METAL || demo->wsi_platform == WSI_PLATFORM_AUTO) { - bool metal_extension_available = false; - for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { - if (strcmp(demo->extension_names[i], VK_EXT_METAL_SURFACE_EXTENSION_NAME) == 0) { - metal_extension_available = true; - break; - } - } - if (metal_extension_available) { - demo->wsi_platform = WSI_PLATFORM_METAL; - return; - } - } -#endif -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - if (demo->wsi_platform == WSI_PLATFORM_ANDROID || demo->wsi_platform == WSI_PLATFORM_AUTO) { - bool android_extension_available = false; - for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { - if (strcmp(demo->extension_names[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) { - android_extension_available = true; - break; - } - } - if (android_extension_available) { - demo->wsi_platform = WSI_PLATFORM_ANDROID; - return; - } - } -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - if (demo->wsi_platform == WSI_PLATFORM_QNX || demo->wsi_platform == WSI_PLATFORM_AUTO) { - bool qnx_extension_available = false; - for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { - if (strcmp(demo->extension_names[i], VK_QNX_SCREEN_SURFACE_EXTENSION_NAME) == 0) { - qnx_extension_available = true; - break; - } - } - if (qnx_extension_available) { - demo->wsi_platform = WSI_PLATFORM_QNX; - return; - } - } -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - if (demo->wsi_platform == WSI_PLATFORM_DISPLAY || demo->wsi_platform == WSI_PLATFORM_AUTO) { - bool display_extension_available = false; - for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { - if (strcmp(demo->extension_names[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) { - display_extension_available = true; - break; - } - } - if (display_extension_available) { - // Because DISPLAY doesn't require additional libraries, we can assume that it works if we got here - demo->wsi_platform = WSI_PLATFORM_DISPLAY; - return; - } - } -#endif -} - -static void demo_init_vk(struct demo *demo) { - VkResult err; - uint32_t instance_extension_count = 0; - uint32_t instance_layer_count = 0; - char *instance_validation_layers[] = {"VK_LAYER_KHRONOS_validation"}; - demo->enabled_extension_count = 0; - demo->enabled_layer_count = 0; - demo->is_minimized = false; - demo->cmd_pool = VK_NULL_HANDLE; - - err = load_vulkan_library(); - if (err != VK_SUCCESS) { - ERR_EXIT( - "Unable to find the Vulkan runtime on the system.\n\n" - "This likely indicates that no Vulkan capable drivers are installed.", - "Installation Failure"); - } - // Look for validation layers - VkBool32 validation_found = 0; - if (demo->validate) { - err = vkEnumerateInstanceLayerProperties(&instance_layer_count, NULL); - assert(!err); - - if (instance_layer_count > 0) { - VkLayerProperties *instance_layers = malloc(sizeof(VkLayerProperties) * instance_layer_count); - err = vkEnumerateInstanceLayerProperties(&instance_layer_count, instance_layers); - assert(!err); - - validation_found = demo_check_layers(ARRAY_SIZE(instance_validation_layers), instance_validation_layers, - instance_layer_count, instance_layers); - if (validation_found) { - demo->enabled_layer_count = ARRAY_SIZE(instance_validation_layers); - demo->enabled_layers[0] = "VK_LAYER_KHRONOS_validation"; - } - free(instance_layers); - } - - if (!validation_found) { - ERR_EXIT( - "vkEnumerateInstanceLayerProperties failed to find required validation layer.\n\n" - "Please look at the Getting Started guide for additional information.\n", - "vkCreateInstance Failure"); - } - } - - /* Look for instance extensions */ - VkBool32 surfaceExtFound = false; - VkBool32 platformSurfaceExtFound = false; - bool portabilityEnumerationActive = false; - memset(demo->extension_names, 0, sizeof(demo->extension_names)); - - err = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL); - assert(!err); - - if (instance_extension_count > 0) { - VkExtensionProperties *instance_extensions = malloc(sizeof(VkExtensionProperties) * instance_extension_count); - err = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, instance_extensions); - assert(!err); - for (uint32_t i = 0; i < instance_extension_count; i++) { - if (!strcmp(VK_KHR_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName)) { - surfaceExtFound = true; - demo->extension_names[demo->enabled_extension_count++] = VK_KHR_SURFACE_EXTENSION_NAME; - } -#if defined(VK_USE_PLATFORM_WIN32_KHR) - if (!strcmp(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName) && - (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_WIN32)) { - platformSurfaceExtFound = true; - demo->extension_names[demo->enabled_extension_count++] = VK_KHR_WIN32_SURFACE_EXTENSION_NAME; - } -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - if (!strcmp(VK_KHR_XLIB_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName) && - (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_XLIB)) { - platformSurfaceExtFound = true; - demo->extension_names[demo->enabled_extension_count++] = VK_KHR_XLIB_SURFACE_EXTENSION_NAME; - } -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - if (!strcmp(VK_KHR_XCB_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName) && - (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_XCB)) { - platformSurfaceExtFound = true; - demo->extension_names[demo->enabled_extension_count++] = VK_KHR_XCB_SURFACE_EXTENSION_NAME; - } -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - if (!strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName) && - (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_WAYLAND)) { - platformSurfaceExtFound = true; - demo->extension_names[demo->enabled_extension_count++] = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME; - } -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - if (!strcmp(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName) && - (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_DIRECTFB)) { - platformSurfaceExtFound = true; - demo->extension_names[demo->enabled_extension_count++] = VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME; - } -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - if (!strcmp(VK_KHR_DISPLAY_EXTENSION_NAME, instance_extensions[i].extensionName) && - (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_DISPLAY)) { - platformSurfaceExtFound = true; - demo->extension_names[demo->enabled_extension_count++] = VK_KHR_DISPLAY_EXTENSION_NAME; - } -#endif -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - if (!strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName) && - (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_ANDROID)) { - platformSurfaceExtFound = true; - demo->extension_names[demo->enabled_extension_count++] = VK_KHR_ANDROID_SURFACE_EXTENSION_NAME; - } -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) - if (!strcmp(VK_EXT_METAL_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName) && - (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_METAL)) { - platformSurfaceExtFound = true; - demo->extension_names[demo->enabled_extension_count++] = VK_EXT_METAL_SURFACE_EXTENSION_NAME; - } -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - if (!strcmp(VK_QNX_SCREEN_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName) && - (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_QNX)) { - platformSurfaceExtFound = true; - demo->extension_names[demo->enabled_extension_count++] = VK_QNX_SCREEN_SURFACE_EXTENSION_NAME; - } -#endif - if (!strcmp(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, instance_extensions[i].extensionName)) { - demo->extension_names[demo->enabled_extension_count++] = VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; - } - if (!strcmp(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, instance_extensions[i].extensionName)) { - if (demo->validate) { - demo->extension_names[demo->enabled_extension_count++] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME; - } - } - // We want cube to be able to enumerate drivers that support the portability_subset extension, so we have to enable - // the portability enumeration extension. - if (!strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, instance_extensions[i].extensionName)) { - portabilityEnumerationActive = true; - demo->extension_names[demo->enabled_extension_count++] = VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME; - } - assert(demo->enabled_extension_count < 64); - } - - free(instance_extensions); - } - - if (!surfaceExtFound) { - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "This indicates that no compatible Vulkan installable client driver (ICD) is present or that the system is not " - "configured to present to the screen. \n", - "vkCreateInstance Failure"); - } - if (!platformSurfaceExtFound) { - switch (demo->wsi_platform) { -#if defined(VK_USE_PLATFORM_WIN32_KHR) - case (WSI_PLATFORM_WIN32): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_WIN32_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform win32 is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) - case (WSI_PLATFORM_METAL): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_EXT_METAL_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform metal is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - case (WSI_PLATFORM_XCB): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_XCB_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform xcb is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - case (WSI_PLATFORM_WAYLAND): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform wayland is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - case (WSI_PLATFORM_DISPLAY): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_DISPLAY_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform display is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - case (WSI_PLATFORM_ANDROID): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_ANDROID_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform android is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - case (WSI_PLATFORM_XLIB): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_XLIB_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform xlib is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - case (WSI_PLATFORM_DIRECTFB): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform directfb is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - case (WSI_PLATFORM_QNX): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_QNX_SCREEN_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform qnx is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif - default: - case (WSI_PLATFORM_AUTO): - // Getting here indicates we are using the WSI extension that is default on this platform - ERR_EXIT( - "vkEnumerateInstanceExtensionProperties failed to find any supported WSI surface instance extensions.\n\n" - "This indicates that no compatible Vulkan installable client driver (ICD) is present or that the system is not " - "configured to present to the screen. \n", - "vkCreateInstance Failure"); - break; - } - } - - bool auto_wsi_platform = demo->wsi_platform == WSI_PLATFORM_AUTO; - - demo_check_and_set_wsi_platform(demo); - - // Print a message to indicate the automatically set WSI platform - if (auto_wsi_platform && demo->wsi_platform != WSI_PLATFORM_AUTO) { - fprintf(stderr, "Selected WSI platform: %s\n", wsi_to_string(demo->wsi_platform)); - } - - const VkApplicationInfo app = { - .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, - .pNext = NULL, - .pApplicationName = APP_SHORT_NAME, - .applicationVersion = 0, - .pEngineName = APP_SHORT_NAME, - .engineVersion = 0, - .apiVersion = VK_API_VERSION_1_0, - }; - VkInstanceCreateInfo inst_info = { - .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, - .pNext = NULL, - .flags = (portabilityEnumerationActive ? VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR : 0), - .pApplicationInfo = &app, - .enabledLayerCount = demo->enabled_layer_count, - .ppEnabledLayerNames = (const char *const *)instance_validation_layers, - .enabledExtensionCount = demo->enabled_extension_count, - .ppEnabledExtensionNames = (const char *const *)demo->extension_names, - }; - - /* - * This is info for a temp callback to use during CreateInstance. - * After the instance is created, we use the instance-based - * function to register the final callback. - */ - VkDebugUtilsMessengerCreateInfoEXT dbg_messenger_create_info; - if (demo->validate) { - // VK_EXT_debug_utils style - dbg_messenger_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; - dbg_messenger_create_info.pNext = NULL; - dbg_messenger_create_info.flags = 0; - dbg_messenger_create_info.messageSeverity = - VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; - dbg_messenger_create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; - dbg_messenger_create_info.pfnUserCallback = debug_messenger_callback; - dbg_messenger_create_info.pUserData = demo; - inst_info.pNext = &dbg_messenger_create_info; - } - - err = vkCreateInstance(&inst_info, NULL, &demo->inst); - if (err == VK_ERROR_INCOMPATIBLE_DRIVER) { - ERR_EXIT( - "Cannot find a compatible Vulkan installable client driver (ICD).\n\n" - "Please look at the Getting Started guide for additional information.\n", - "vkCreateInstance Failure"); - } else if (err == VK_ERROR_EXTENSION_NOT_PRESENT) { - ERR_EXIT( - "Cannot find a specified extension library.\n" - "Make sure your layers path is set appropriately.\n", - "vkCreateInstance Failure"); - } else if (err) { - ERR_EXIT( - "vkCreateInstance failed.\n\n" - "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" - "Please look at the Getting Started guide for additional information.\n", - "vkCreateInstance Failure"); - } - - load_vulkan_instance_functions(demo->inst); -} - -static void demo_select_physical_device(struct demo *demo) { - VkResult err; - /* Make initial call to query gpu_count, then second call for gpu info */ - uint32_t gpu_count = 0; - err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, NULL); - assert(!err); - - if (gpu_count <= 0) { - ERR_EXIT( - "vkEnumeratePhysicalDevices reported zero accessible devices.\n\n" - "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" - "Please look at the Getting Started guide for additional information.\n", - "vkEnumeratePhysicalDevices Failure"); - } - - VkPhysicalDevice *physical_devices = malloc(sizeof(VkPhysicalDevice) * gpu_count); - err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, physical_devices); - assert(!err); - if (demo->invalid_gpu_selection || (demo->gpu_number >= 0 && !((uint32_t)demo->gpu_number < gpu_count))) { - fprintf(stderr, "GPU %d specified is not present, GPU count = %u\n", demo->gpu_number, gpu_count); - ERR_EXIT("Specified GPU number is not present", "User Error"); - } - - if (demo->wsi_platform == WSI_PLATFORM_DISPLAY) { -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - demo->gpu_number = find_display_gpu(demo->gpu_number, gpu_count, physical_devices); - if (demo->gpu_number < 0) { - printf("Cannot find any display!\n"); - fflush(stdout); - exit(1); - } -#else - printf("WSI selection was set to DISPLAY but vkcube was not compiled with support for the DISPLAY platform, exiting \n"); - fflush(stdout); - exit(1); -#endif - } else { - /* Try to auto select most suitable device */ - if (demo->gpu_number == -1) { - VkPhysicalDeviceProperties physicalDeviceProperties; - int prev_priority = 0; - for (uint32_t i = 0; i < gpu_count; i++) { - vkGetPhysicalDeviceProperties(physical_devices[i], &physicalDeviceProperties); - assert(physicalDeviceProperties.deviceType <= VK_PHYSICAL_DEVICE_TYPE_CPU); - - // Continue next gpu if this gpu does not support the surface. - VkBool32 supported = VK_FALSE; - VkResult result = vkGetPhysicalDeviceSurfaceSupportKHR(physical_devices[i], 0, demo->surface, &supported); - if (result != VK_SUCCESS || !supported) continue; - - int priority = 0; - switch (physicalDeviceProperties.deviceType) { - case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: - priority = 5; - break; - case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: - priority = 4; - break; - case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: - priority = 3; - break; - case VK_PHYSICAL_DEVICE_TYPE_CPU: - priority = 2; - break; - case VK_PHYSICAL_DEVICE_TYPE_OTHER: - priority = 1; - break; - default: - priority = -1; - break; - } - - if (priority > prev_priority) { - demo->gpu_number = i; - prev_priority = priority; - } - } - } - } - - assert(demo->gpu_number >= 0); - demo->gpu = physical_devices[demo->gpu_number]; - { - VkPhysicalDeviceProperties physicalDeviceProperties; - vkGetPhysicalDeviceProperties(demo->gpu, &physicalDeviceProperties); - fprintf(stderr, "Selected GPU %d: %s, type: %s\n", demo->gpu_number, physicalDeviceProperties.deviceName, - to_string(physicalDeviceProperties.deviceType)); - } - free(physical_devices); - - /* Look for device extensions */ - uint32_t device_extension_count = 0; - VkBool32 swapchainExtFound = 0; - demo->enabled_extension_count = 0; - memset(demo->extension_names, 0, sizeof(demo->extension_names)); - - err = vkEnumerateDeviceExtensionProperties(demo->gpu, NULL, &device_extension_count, NULL); - assert(!err); - - if (device_extension_count > 0) { - VkExtensionProperties *device_extensions = malloc(sizeof(VkExtensionProperties) * device_extension_count); - err = vkEnumerateDeviceExtensionProperties(demo->gpu, NULL, &device_extension_count, device_extensions); - assert(!err); - - for (uint32_t i = 0; i < device_extension_count; i++) { - if (!strcmp(VK_KHR_SWAPCHAIN_EXTENSION_NAME, device_extensions[i].extensionName)) { - swapchainExtFound = 1; - demo->extension_names[demo->enabled_extension_count++] = VK_KHR_SWAPCHAIN_EXTENSION_NAME; - } - if (!strcmp("VK_KHR_portability_subset", device_extensions[i].extensionName)) { - demo->extension_names[demo->enabled_extension_count++] = "VK_KHR_portability_subset"; - } - assert(demo->enabled_extension_count < 64); - } - - if (demo->VK_KHR_incremental_present_enabled) { - // Even though the user "enabled" the extension via the command - // line, we must make sure that it's enumerated for use with the - // device. Therefore, disable it here, and re-enable it again if - // enumerated. - demo->VK_KHR_incremental_present_enabled = false; - for (uint32_t i = 0; i < device_extension_count; i++) { - if (!strcmp(VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME, device_extensions[i].extensionName)) { - demo->extension_names[demo->enabled_extension_count++] = VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME; - demo->VK_KHR_incremental_present_enabled = true; - DbgMsg("VK_KHR_incremental_present extension enabled\n"); - } - assert(demo->enabled_extension_count < 64); - } - if (!demo->VK_KHR_incremental_present_enabled) { - DbgMsg("VK_KHR_incremental_present extension NOT AVAILABLE\n"); - } - } - - if (demo->VK_GOOGLE_display_timing_enabled) { - // Even though the user "enabled" the extension via the command - // line, we must make sure that it's enumerated for use with the - // device. Therefore, disable it here, and re-enable it again if - // enumerated. - demo->VK_GOOGLE_display_timing_enabled = false; - for (uint32_t i = 0; i < device_extension_count; i++) { - if (!strcmp(VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME, device_extensions[i].extensionName)) { - demo->extension_names[demo->enabled_extension_count++] = VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME; - demo->VK_GOOGLE_display_timing_enabled = true; - DbgMsg("VK_GOOGLE_display_timing extension enabled\n"); - } - assert(demo->enabled_extension_count < 64); - } - if (!demo->VK_GOOGLE_display_timing_enabled) { - DbgMsg("VK_GOOGLE_display_timing extension NOT AVAILABLE\n"); - } - } - - free(device_extensions); - } - - if (!swapchainExtFound) { - ERR_EXIT("vkEnumerateDeviceExtensionProperties failed to find the " VK_KHR_SWAPCHAIN_EXTENSION_NAME - " extension.\n\nDo you have a compatible Vulkan installable client driver (ICD) installed?\n" - "Please look at the Getting Started guide for additional information.\n", - "vkCreateInstance Failure"); - } - - if (demo->validate) { - /* - * This is info for a temp callback to use during CreateInstance. - * After the instance is created, we use the instance-based - * function to register the final callback. - */ - VkDebugUtilsMessengerCreateInfoEXT dbg_messenger_create_info; - // VK_EXT_debug_utils style - dbg_messenger_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; - dbg_messenger_create_info.pNext = NULL; - dbg_messenger_create_info.flags = 0; - dbg_messenger_create_info.messageSeverity = - VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; - dbg_messenger_create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; - dbg_messenger_create_info.pfnUserCallback = debug_messenger_callback; - dbg_messenger_create_info.pUserData = demo; - - err = vkCreateDebugUtilsMessengerEXT(demo->inst, &dbg_messenger_create_info, NULL, &demo->dbg_messenger); - switch (err) { - case VK_SUCCESS: - break; - case VK_ERROR_OUT_OF_HOST_MEMORY: - ERR_EXIT("CreateDebugUtilsMessengerEXT: out of host memory\n", "CreateDebugUtilsMessengerEXT Failure"); - break; - default: - ERR_EXIT("CreateDebugUtilsMessengerEXT: unknown failure\n", "CreateDebugUtilsMessengerEXT Failure"); - break; - } - } - vkGetPhysicalDeviceProperties(demo->gpu, &demo->gpu_props); - - /* Call with NULL data to get count */ - vkGetPhysicalDeviceQueueFamilyProperties(demo->gpu, &demo->queue_family_count, NULL); - assert(demo->queue_family_count >= 1); - - demo->queue_props = (VkQueueFamilyProperties *)malloc(demo->queue_family_count * sizeof(VkQueueFamilyProperties)); - vkGetPhysicalDeviceQueueFamilyProperties(demo->gpu, &demo->queue_family_count, demo->queue_props); - - // Query fine-grained feature support for this device. - // If app has specific feature requirements it should check supported - // features based on this query - VkPhysicalDeviceFeatures physDevFeatures; - vkGetPhysicalDeviceFeatures(demo->gpu, &physDevFeatures); -} - -static void demo_create_device(struct demo *demo) { - VkResult U_ASSERT_ONLY err; - float queue_priorities[1] = {0.0}; - VkDeviceQueueCreateInfo queues[2]; - queues[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queues[0].pNext = NULL; - queues[0].queueFamilyIndex = demo->graphics_queue_family_index; - queues[0].queueCount = 1; - queues[0].pQueuePriorities = queue_priorities; - queues[0].flags = 0; - - VkDeviceCreateInfo device = { - .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - .pNext = NULL, - .queueCreateInfoCount = 1, - .pQueueCreateInfos = queues, - .enabledLayerCount = 0, - .ppEnabledLayerNames = NULL, - .enabledExtensionCount = demo->enabled_extension_count, - .ppEnabledExtensionNames = (const char *const *)demo->extension_names, - .pEnabledFeatures = NULL, // If specific features are required, pass them in here - }; - if (demo->separate_present_queue) { - queues[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queues[1].pNext = NULL; - queues[1].queueFamilyIndex = demo->present_queue_family_index; - queues[1].queueCount = 1; - queues[1].pQueuePriorities = queue_priorities; - queues[1].flags = 0; - device.queueCreateInfoCount = 2; - } - err = vkCreateDevice(demo->gpu, &device, NULL, &demo->device); - assert(!err); - - load_vulkan_device_functions(demo->device); -} - -static void demo_create_surface(struct demo *demo) { - VkResult U_ASSERT_ONLY err = VK_SUCCESS; - -// Create a WSI surface for the window: -#if defined(VK_USE_PLATFORM_WIN32_KHR) - if (demo->wsi_platform == WSI_PLATFORM_WIN32) { - VkWin32SurfaceCreateInfoKHR win32_createInfo; - win32_createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; - win32_createInfo.pNext = NULL; - win32_createInfo.flags = 0; - win32_createInfo.hinstance = demo->connection; - win32_createInfo.hwnd = demo->window; - - err = vkCreateWin32SurfaceKHR(demo->inst, &win32_createInfo, NULL, &demo->surface); - } -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - if (demo->wsi_platform == WSI_PLATFORM_WAYLAND) { - VkWaylandSurfaceCreateInfoKHR wayland_createInfo; - wayland_createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; - wayland_createInfo.pNext = NULL; - wayland_createInfo.flags = 0; - wayland_createInfo.display = demo->wayland_display; - wayland_createInfo.surface = demo->window; - - err = vkCreateWaylandSurfaceKHR(demo->inst, &wayland_createInfo, NULL, &demo->surface); - } -#endif -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - if (demo->wsi_platform == WSI_PLATFORM_ANDROID) { - VkAndroidSurfaceCreateInfoKHR android_createInfo; - android_createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; - android_createInfo.pNext = NULL; - android_createInfo.flags = 0; - android_createInfo.window = (struct ANativeWindow *)(demo->window); - - err = vkCreateAndroidSurfaceKHR(demo->inst, &android_createInfo, NULL, &demo->surface); - } -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - if (demo->wsi_platform == WSI_PLATFORM_XLIB) { - VkXlibSurfaceCreateInfoKHR xlib_createInfo; - xlib_createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; - xlib_createInfo.pNext = NULL; - xlib_createInfo.flags = 0; - xlib_createInfo.dpy = demo->xlib_display; - xlib_createInfo.window = demo->xlib_window; - - err = vkCreateXlibSurfaceKHR(demo->inst, &xlib_createInfo, NULL, &demo->surface); - } -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - if (demo->wsi_platform == WSI_PLATFORM_XCB) { - VkXcbSurfaceCreateInfoKHR xcb_createInfo; - xcb_createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; - xcb_createInfo.pNext = NULL; - xcb_createInfo.flags = 0; - xcb_createInfo.connection = demo->connection; - xcb_createInfo.window = demo->xcb_window; - - err = vkCreateXcbSurfaceKHR(demo->inst, &xcb_createInfo, NULL, &demo->surface); - } -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - if (demo->wsi_platform == WSI_PLATFORM_DIRECTFB) { - VkDirectFBSurfaceCreateInfoEXT directfb_createInfo; - directfb_createInfo.sType = VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT; - directfb_createInfo.pNext = NULL; - directfb_createInfo.flags = 0; - directfb_createInfo.dfb = demo->dfb; - directfb_createInfo.surface = demo->directfb_window; - - err = vkCreateDirectFBSurfaceEXT(demo->inst, &directfb_createInfo, NULL, &demo->surface); - } - -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - if (demo->wsi_platform == WSI_PLATFORM_DISPLAY) { - err = demo_create_display_surface(demo); - } -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) - if (demo->wsi_platform == WSI_PLATFORM_METAL) { - VkMetalSurfaceCreateInfoEXT metal_createInfo; - metal_createInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; - metal_createInfo.pNext = NULL; - metal_createInfo.flags = 0; - metal_createInfo.pLayer = demo->caMetalLayer; - - err = vkCreateMetalSurfaceEXT(demo->inst, &metal_createInfo, NULL, &demo->surface); - } -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - if (demo->wsi_platform == WSI_PLATFORM_QNX) { - VkScreenSurfaceCreateInfoQNX qnx_createInfo; - qnx_createInfo.sType = VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX; - qnx_createInfo.pNext = NULL; - qnx_createInfo.flags = 0; - qnx_createInfo.context = demo->screen_context; - qnx_createInfo.window = demo->screen_window; - - err = vkCreateScreenSurfaceQNX(demo->inst, &qnx_createInfo, NULL, &demo->surface); - } -#endif - assert(!err); -} - -static VkSurfaceFormatKHR pick_surface_format(const VkSurfaceFormatKHR *surfaceFormats, uint32_t count) { - // Prefer non-SRGB formats... - for (uint32_t i = 0; i < count; i++) { - const VkFormat format = surfaceFormats[i].format; - - if (format == VK_FORMAT_R8G8B8A8_UNORM || format == VK_FORMAT_B8G8R8A8_UNORM || - format == VK_FORMAT_A2B10G10R10_UNORM_PACK32 || format == VK_FORMAT_A2R10G10B10_UNORM_PACK32 || - format == VK_FORMAT_A1R5G5B5_UNORM_PACK16 || format == VK_FORMAT_R5G6B5_UNORM_PACK16 || - format == VK_FORMAT_R16G16B16A16_SFLOAT) { - return surfaceFormats[i]; - } - } - - printf("Can't find our preferred formats... Falling back to first exposed format. Rendering may be incorrect.\n"); - - assert(count >= 1); - return surfaceFormats[0]; -} - -static void demo_init_vk_swapchain(struct demo *demo) { - VkResult U_ASSERT_ONLY err; - - // Iterate over each queue to learn whether it supports presenting: - VkBool32 *supportsPresent = (VkBool32 *)malloc(demo->queue_family_count * sizeof(VkBool32)); - for (uint32_t i = 0; i < demo->queue_family_count; i++) { - vkGetPhysicalDeviceSurfaceSupportKHR(demo->gpu, i, demo->surface, &supportsPresent[i]); - } - - // Search for a graphics and a present queue in the array of queue - // families, try to find one that supports both - uint32_t graphicsQueueFamilyIndex = UINT32_MAX; - uint32_t presentQueueFamilyIndex = UINT32_MAX; - for (uint32_t i = 0; i < demo->queue_family_count; i++) { - if ((demo->queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) { - if (graphicsQueueFamilyIndex == UINT32_MAX) { - graphicsQueueFamilyIndex = i; - } - - if (supportsPresent[i] == VK_TRUE) { - graphicsQueueFamilyIndex = i; - presentQueueFamilyIndex = i; - break; - } - } - } - - if (presentQueueFamilyIndex == UINT32_MAX) { - // If didn't find a queue that supports both graphics and present, then - // find a separate present queue. - for (uint32_t i = 0; i < demo->queue_family_count; ++i) { - if (supportsPresent[i] == VK_TRUE) { - presentQueueFamilyIndex = i; - break; - } - } - } - - // Generate error if could not find both a graphics and a present queue - if (graphicsQueueFamilyIndex == UINT32_MAX || presentQueueFamilyIndex == UINT32_MAX) { - ERR_EXIT("Could not find both graphics and present queues\n", "Swapchain Initialization Failure"); - } - - demo->graphics_queue_family_index = graphicsQueueFamilyIndex; - demo->present_queue_family_index = presentQueueFamilyIndex; - demo->separate_present_queue = (demo->graphics_queue_family_index != demo->present_queue_family_index); - free(supportsPresent); - - demo_create_device(demo); - - vkGetDeviceQueue(demo->device, demo->graphics_queue_family_index, 0, &demo->graphics_queue); - - if (!demo->separate_present_queue) { - demo->present_queue = demo->graphics_queue; - } else { - vkGetDeviceQueue(demo->device, demo->present_queue_family_index, 0, &demo->present_queue); - } - - // Get the list of VkFormat's that are supported: - uint32_t formatCount; - err = vkGetPhysicalDeviceSurfaceFormatsKHR(demo->gpu, demo->surface, &formatCount, NULL); - assert(!err); - VkSurfaceFormatKHR *surfFormats = (VkSurfaceFormatKHR *)malloc(formatCount * sizeof(VkSurfaceFormatKHR)); - err = vkGetPhysicalDeviceSurfaceFormatsKHR(demo->gpu, demo->surface, &formatCount, surfFormats); - assert(!err); - VkSurfaceFormatKHR surfaceFormat = pick_surface_format(surfFormats, formatCount); - demo->format = surfaceFormat.format; - demo->color_space = surfaceFormat.colorSpace; - free(surfFormats); - - demo->quit = false; - demo->curFrame = 0; - - demo->first_swapchain_frame = true; - - // Get Memory information and properties - vkGetPhysicalDeviceMemoryProperties(demo->gpu, &demo->memory_properties); -} - -static void demo_init(struct demo *demo, int argc, char **argv) { - vec3 eye = {0.0f, 3.0f, 5.0f}; - vec3 origin = {0, 0, 0}; - vec3 up = {0.0f, 1.0f, 0.0}; - - memset(demo, 0, sizeof(*demo)); - demo->presentMode = VK_PRESENT_MODE_FIFO_KHR; - demo->frameCount = INT32_MAX; - /* Autodetect suitable / best GPU by default */ - demo->gpu_number = -1; - demo->width = 500; - demo->height = 500; - demo->tex_file = "lunarg.ppm"; - - for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "--use_staging") == 0) { - demo->use_staging_buffer = true; - continue; - } - if ((strcmp(argv[i], "--present_mode") == 0) && (i < argc - 1)) { - demo->presentMode = atoi(argv[i + 1]); - i++; - continue; - } - if (strcmp(argv[i], "--break") == 0) { - demo->use_break = true; - continue; - } - if (strcmp(argv[i], "--validate") == 0) { - demo->validate = true; - continue; - } - if (strcmp(argv[i], "--xlib") == 0) { - fprintf(stderr, "--xlib is deprecated and no longer does anything\n"); - continue; - } - if (strcmp(argv[i], "--c") == 0 && demo->frameCount == INT32_MAX && i < argc - 1 && - sscanf(argv[i + 1], "%d", &demo->frameCount) == 1 && demo->frameCount >= 0) { - i++; - continue; - } - if (strcmp(argv[i], "--width") == 0) { - if (i < argc - 1 && sscanf(argv[i + 1], "%d", &demo->width) == 1) { - if (demo->width > 0) { - i++; - continue; - } else { - ERR_EXIT("The --width parameter must be greater than 0", "User Error"); - } - } - ERR_EXIT("The --width parameter must be followed by a number", "User Error"); - } - if (strcmp(argv[i], "--height") == 0) { - if (i < argc - 1 && sscanf(argv[i + 1], "%d", &demo->height) == 1) { - if (demo->height > 0) { - i++; - continue; - } else { - ERR_EXIT("The --height parameter must be greater than 0", "User Error"); - } - } - ERR_EXIT("The --height parameter must be followed by a number", "User Error"); - } - if (strcmp(argv[i], "--suppress_popups") == 0) { - demo->suppress_popups = true; - continue; - } - if (strcmp(argv[i], "--display_timing") == 0) { - demo->VK_GOOGLE_display_timing_enabled = true; - continue; - } - if (strcmp(argv[i], "--incremental_present") == 0) { - demo->VK_KHR_incremental_present_enabled = true; - continue; - } - if ((strcmp(argv[i], "--gpu_number") == 0) && (i < argc - 1)) { - demo->gpu_number = atoi(argv[i + 1]); - if (demo->gpu_number < 0) demo->invalid_gpu_selection = true; - i++; - continue; - } - if (strcmp(argv[i], "--force_errors") == 0) { - demo->force_errors = true; - continue; - } - if ((strcmp(argv[i], "--wsi") == 0) && (i < argc - 1)) { - size_t argc_len = strlen(argv[i + 1]); - for (size_t argc_i = 0; argc_i < argc_len; argc_i++) { - argv[i + 1][argc_i] = tolower(argv[i + 1][argc_i]); - } - WSI_PLATFORM selection = wsi_from_string(argv[i + 1]); - if (selection == WSI_PLATFORM_INVALID) { - printf( - "The --wsi parameter %s is not a supported WSI platform. The list of available platforms is available from " - "--help\n", - (const char *)&(argv[i + 1][0])); - fflush(stdout); - exit(1); - } - demo->wsi_platform = selection; - i++; - continue; - } - if (strcmp(argv[i], "--texture") == 0) { - if (i < argc - 1) { - demo->tex_file = argv[i + 1]; - i++; - continue; - } - ERR_EXIT("The --texture parameter must be followed by a string", "User Error"); - } - -#if defined(ANDROID) - ERR_EXIT("Usage: vkcube [--validate]\n", "Usage"); -#else - - // Making the help for --wsi nice requires a little extra work since the list depends on what is available at - // compile time - size_t max_str_len = 100; - char *available_wsi_platforms = (char *)malloc(max_str_len); - memset(available_wsi_platforms, 0, max_str_len); -#if defined(VK_USE_PLATFORM_XCB_KHR) - strncat(available_wsi_platforms, "xcb", max_str_len); -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - if (strlen(available_wsi_platforms) > 0) { - strncat(available_wsi_platforms, "|", max_str_len); - } - strncat(available_wsi_platforms, "xlib", max_str_len); -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - if (strlen(available_wsi_platforms) > 0) { - strncat(available_wsi_platforms, "|", max_str_len); - } - strncat(available_wsi_platforms, "wayland", max_str_len); -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - if (strlen(available_wsi_platforms) > 0) { - strncat(available_wsi_platforms, "|", max_str_len); - } - strncat(available_wsi_platforms, "directfb", max_str_len); -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - if (strlen(available_wsi_platforms) > 0) { - strncat(available_wsi_platforms, "|", max_str_len); - } - strncat(available_wsi_platforms, "display", max_str_len); -#endif -#if defined(VK_USE_PLATFORM_WIN32_KHR) - if (strlen(available_wsi_platforms) > 0) { - strncat(available_wsi_platforms, "|", max_str_len); - } - strncat(available_wsi_platforms, "win32", max_str_len); -#endif -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - if (strlen(available_wsi_platforms) > 0) { - strncat(available_wsi_platforms, "|", max_str_len); - } - strncat(available_wsi_platforms, "android", max_str_len); -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) - if (strlen(available_wsi_platforms) > 0) { - strncat(available_wsi_platforms, "|", max_str_len); - } - strncat(available_wsi_platforms, "metal", max_str_len); -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - if (strlen(available_wsi_platforms) > 0) { - strncat(available_wsi_platforms, "|", max_str_len); - } - strncat(available_wsi_platforms, "qnx", max_str_len); -#endif - - char *message = - "Usage:\n %s\t[--use_staging] [--validate]\n" - "\t[--break] [--c <framecount>] [--suppress_popups]\n" - "\t[--incremental_present] [--display_timing]\n" - "\t[--gpu_number <index of physical device>]\n" - "\t[--present_mode <present mode enum>]\n" - "\t[--width <width>] [--height <height>]\n" - "\t[--force_errors]\n" - "\t[--texture <filename>]\n" - "\t[--wsi <%s>]\n" - "\t<present_mode_enum>\n" - "\t\tVK_PRESENT_MODE_IMMEDIATE_KHR = %d\n" - "\t\tVK_PRESENT_MODE_MAILBOX_KHR = %d\n" - "\t\tVK_PRESENT_MODE_FIFO_KHR = %d\n" - "\t\tVK_PRESENT_MODE_FIFO_RELAXED_KHR = %d\n"; - int length = snprintf(NULL, 0, message, APP_SHORT_NAME, available_wsi_platforms, VK_PRESENT_MODE_IMMEDIATE_KHR, - VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_FIFO_RELAXED_KHR); - char *usage = (char *)malloc(length + 1); - if (!usage) { - exit(1); - } - snprintf(usage, length + 1, message, APP_SHORT_NAME, available_wsi_platforms, VK_PRESENT_MODE_IMMEDIATE_KHR, - VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_FIFO_RELAXED_KHR); -#if defined(_WIN32) - if (!demo->suppress_popups) MessageBox(NULL, usage, "Usage Error", MB_OK); -#else - fprintf(stderr, "%s", usage); - fflush(stderr); -#endif - free(usage); - exit(1); -#endif - } - - demo->initialized = false; - - demo_init_vk(demo); - - demo->spin_angle = 270.0f; - demo->spin_increment = 60.0f; - demo->pause = false; - - mat4x4_perspective(demo->projection_matrix, (float)degreesToRadians(37.0f), 1.0f, 0.1f, 100.0f); - mat4x4_look_at(demo->view_matrix, eye, origin, up); - mat4x4_identity(demo->model_matrix); - - demo->projection_matrix[1][1] *= -1; // Flip projection matrix from GL to Vulkan orientation. -} - -#if defined(VK_USE_PLATFORM_WIN32_KHR) -// Include header required for parsing the command line options. -#include <shellapi.h> - -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow) { - MSG msg; // message - bool done; // flag saying when app is complete - int argc; - char **argv; - - // Ensure wParam is initialized. - msg.wParam = 0; - - // Use the CommandLine functions to get the command line arguments. - // Unfortunately, Microsoft outputs - // this information as wide characters for Unicode, and we simply want the - // Ascii version to be compatible - // with the non-Windows side. So, we have to convert the information to - // Ascii character strings. - LPWSTR *commandLineArgs = CommandLineToArgvW(GetCommandLineW(), &argc); - if (NULL == commandLineArgs) { - argc = 0; - } - - if (argc > 0) { - argv = (char **)malloc(sizeof(char *) * argc); - if (argv == NULL) { - argc = 0; - } else { - for (int iii = 0; iii < argc; iii++) { - size_t wideCharLen = wcslen(commandLineArgs[iii]); - size_t numConverted = 0; - - argv[iii] = (char *)malloc(sizeof(char) * (wideCharLen + 1)); - if (argv[iii] != NULL) { - wcstombs_s(&numConverted, argv[iii], wideCharLen + 1, commandLineArgs[iii], wideCharLen + 1); - } - } - } - } else { - argv = NULL; - } - - demo_init(&demo, argc, argv); - - // Free up the items we had to allocate for the command line arguments. - if (argc > 0 && argv != NULL) { - for (int iii = 0; iii < argc; iii++) { - if (argv[iii] != NULL) { - free(argv[iii]); - } - } - free(argv); - } - - demo.connection = hInstance; - strncpy(demo.name, "Vulkan Cube", APP_NAME_STR_LEN); - demo_create_window(&demo); - demo_create_surface(&demo); - demo_select_physical_device(&demo); - demo_init_vk_swapchain(&demo); - - demo_prepare(&demo); - - done = false; // initialize loop condition variable - - // main message loop - while (!done) { - if (demo.pause) { - const BOOL succ = WaitMessage(); - - if (!succ) { - struct demo *tmp = &demo; - struct demo *demo = tmp; - ERR_EXIT("WaitMessage() failed on paused demo", "event loop error"); - } - } - PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); - if (msg.message == WM_QUIT) // check for a quit message - { - done = true; // if found, quit app - } else { - /* Translate and dispatch to event queue*/ - TranslateMessage(&msg); - DispatchMessage(&msg); - } - RedrawWindow(demo.window, NULL, NULL, RDW_INTERNALPAINT); - } - - demo_cleanup(&demo); - - return (int)msg.wParam; -} - -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) -static void demo_main(struct demo *demo, void *caMetalLayer, int argc, const char *argv[]) { - demo_init(demo, argc, (char **)argv); - demo->caMetalLayer = caMetalLayer; - demo_create_surface(demo); - demo_select_physical_device(demo); - demo_init_vk_swapchain(demo); - demo_prepare(demo); - demo->spin_angle = 0.4f; -} - -#endif -#if defined(VK_USE_PLATFORM_ANDROID_KHR) -#include <android/log.h> -#include <android_native_app_glue.h> -#include "android_util.h" - -static bool active = false; -struct demo demo; - -static int32_t processInput(struct android_app *app, AInputEvent *event) { return 0; } - -static void processCommand(struct android_app *app, int32_t cmd) { - switch (cmd) { - case APP_CMD_INIT_WINDOW: { - if (app->window) { - // We're getting a new window. If the app is starting up, we - // need to initialize. If the app has already been - // initialized, that means that we lost our previous window, - // which means that we have a lot of work to do. At a minimum, - // we need to destroy the swapchain and surface associated with - // the old window, and create a new surface and swapchain. - // However, since there are a lot of other objects/state that - // is tied to the swapchain, it's easiest to simply cleanup and - // start over (i.e. use a brute-force approach of re-starting - // the app) - if (demo.initialized) { - demo_cleanup(&demo); - } - - // Parse Intents into argc, argv - // Use the following key to send arguments, i.e. - // --es args "--validate" - const char key[] = "args"; - char *appTag = (char *)APP_SHORT_NAME; - int argc = 0; - char **argv = get_args(app, key, appTag, &argc); - - __android_log_print(ANDROID_LOG_INFO, appTag, "argc = %i", argc); - for (int i = 0; i < argc; i++) __android_log_print(ANDROID_LOG_INFO, appTag, "argv[%i] = %s", i, argv[i]); - - demo_init(&demo, argc, argv); - - // Free the argv malloc'd by get_args - for (int i = 0; i < argc; i++) free(argv[i]); - - demo.window = (void *)app->window; - demo_create_surface(&demo); - demo_select_physical_device(&demo); - demo_init_vk_swapchain(&demo); - demo_prepare(&demo); - } - break; - } - case APP_CMD_GAINED_FOCUS: { - active = true; - break; - } - case APP_CMD_LOST_FOCUS: { - active = false; - break; - } - } -} - -void android_main(struct android_app *app) { - demo.initialized = false; - - app->onAppCmd = processCommand; - app->onInputEvent = processInput; - - while (1) { - int events; - struct android_poll_source *source; - while (ALooper_pollOnce(active ? 0 : -1, NULL, &events, (void **)&source) >= 0) { - if (source) { - source->process(app, source); - } - - if (app->destroyRequested != 0) { - demo_cleanup(&demo); - return; - } - } - if (demo.initialized && demo.swapchain_ready && active) { - demo_run(&demo); - } - } -} -#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__QNX__) || defined(__GNU__) -int main(int argc, char **argv) { - struct demo demo; - - demo_init(&demo, argc, argv); - switch (demo.wsi_platform) { - default: - case (WSI_PLATFORM_AUTO): - fprintf(stderr, - "WSI platform should have already been set, indicating a bug. Please set a WSI platform manually with " - "--wsi\n"); - exit(1); - break; -#if defined(VK_USE_PLATFORM_XCB_KHR) - case (WSI_PLATFORM_XCB): - demo_create_xcb_window(&demo); - break; -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - case (WSI_PLATFORM_XLIB): - demo_create_xlib_window(&demo); - break; -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - case (WSI_PLATFORM_WAYLAND): - demo_create_wayland_window(&demo); - break; -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - case (WSI_PLATFORM_DIRECTFB): - demo_create_directfb_window(&demo); - break; -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - case (WSI_PLATFORM_QNX): - demo_create_screen_window(&demo); - break; -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - case (WSI_PLATFORM_DISPLAY): - // select physical device because display surface creation needs a gpu to be selected. - demo_select_physical_device(&demo); - break; -#endif - } - demo_create_surface(&demo); - if (demo.wsi_platform != WSI_PLATFORM_DISPLAY) { - demo_select_physical_device(&demo); - } - - demo_init_vk_swapchain(&demo); - - demo_prepare(&demo); - - switch (demo.wsi_platform) { - default: - case (WSI_PLATFORM_AUTO): - fprintf(stderr, - "WSI platform should have already been set, indicating a bug. Please set a WSI platform manually with " - "--wsi\n"); - exit(1); - break; -#if defined(VK_USE_PLATFORM_XCB_KHR) - case (WSI_PLATFORM_XCB): - demo_run_xcb(&demo); - break; -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - case (WSI_PLATFORM_XLIB): - demo_run_xlib(&demo); - break; -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - case (WSI_PLATFORM_WAYLAND): - demo_run(&demo); - break; -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - case (WSI_PLATFORM_DIRECTFB): - demo_run_directfb(&demo); - break; -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - case (WSI_PLATFORM_DISPLAY): - demo_run_display(&demo); - break; -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - case (WSI_PLATFORM_QNX): - demo_run(&demo); - break; -#endif - } - - demo_cleanup(&demo); - - return validation_error; -} -#endif diff --git a/tools/Vulkan-Tools/cube/cube.cpp b/tools/Vulkan-Tools/cube/cube.cpp deleted file mode 100644 index de411cfa..00000000 --- a/tools/Vulkan-Tools/cube/cube.cpp +++ /dev/null @@ -1,4252 +0,0 @@ -/* - * Copyright (c) 2015-2019 The Khronos Group Inc. - * Copyright (c) 2015-2019 Valve Corporation - * Copyright (c) 2015-2019 LunarG, Inc. - * Copyright (c) 2025 The Fuchsia Authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Author: Jeremy Hayes <jeremy@lunarg.com> - * Author: Charles Giessen <charles@lunarg.com> - */ - -#include <algorithm> -#include <cassert> -#include <cinttypes> -#include <cstdio> -#include <cstdlib> -#include <cstring> -#include <csignal> - -#include <sstream> -#include <iostream> -#include <memory> -#include <map> - -#if defined(VK_USE_PLATFORM_XLIB_KHR) -#include "xlib_loader.h" -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) -#include "xcb_loader.h" -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -#include <linux/input.h> -#include "wayland_loader.h" -#endif -#if defined(VK_USE_PLATFORM_FUCHSIA) -#include <fidl/fuchsia.ui.app/cpp/fidl.h> -#include <lib/async-loop/cpp/loop.h> -#include <lib/component/incoming/cpp/protocol.h> -#include <lib/component/outgoing/cpp/outgoing_directory.h> -#include <lib/zx/result.h> - -#include "fuchsia/flatland_view.h" -#endif - -#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 -#define VULKAN_HPP_NO_EXCEPTIONS -#define VULKAN_HPP_TYPESAFE_CONVERSION 1 - -#include <vulkan/vulkan.hpp> - -VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE - -#include "linmath.h" - -#ifndef NDEBUG -#define VERIFY(x) assert(x) -#else -#define VERIFY(x) ((void)(x)) -#endif - -#define APP_SHORT_NAME "vkcubepp" - -// Allow a maximum of two outstanding presentation operations. -constexpr uint32_t FRAME_LAG = 2; - -#ifdef _WIN32 -#define ERR_EXIT(err_msg, err_class) \ - do { \ - if (!suppress_popups) MessageBox(nullptr, err_msg, err_class, MB_OK); \ - exit(1); \ - } while (0) -#else -#define ERR_EXIT(err_msg, err_class) \ - do { \ - printf("%s\n", err_msg); \ - fflush(stdout); \ - exit(1); \ - } while (0) -#endif - -struct texture_object { - vk::Sampler sampler; - - vk::Image image; - vk::Buffer buffer; - vk::ImageLayout imageLayout{vk::ImageLayout::eUndefined}; - - vk::MemoryAllocateInfo mem_alloc; - vk::DeviceMemory mem; - vk::ImageView view; - - uint32_t tex_width{0}; - uint32_t tex_height{0}; -}; - -static char const *const tex_files[] = {"lunarg.ppm"}; - -static int validation_error = 0; - -struct vktexcube_vs_uniform { - // Must start with MVP - float mvp[4][4]; - float position[12 * 3][4]; - float attr[12 * 3][4]; -}; - -//-------------------------------------------------------------------------------------- -// Mesh and VertexFormat Data -//-------------------------------------------------------------------------------------- -// clang-format off -static const float g_vertex_buffer_data[] = { - -1.0f,-1.0f,-1.0f, // -X side - -1.0f,-1.0f, 1.0f, - -1.0f, 1.0f, 1.0f, - -1.0f, 1.0f, 1.0f, - -1.0f, 1.0f,-1.0f, - -1.0f,-1.0f,-1.0f, - - -1.0f,-1.0f,-1.0f, // -Z side - 1.0f, 1.0f,-1.0f, - 1.0f,-1.0f,-1.0f, - -1.0f,-1.0f,-1.0f, - -1.0f, 1.0f,-1.0f, - 1.0f, 1.0f,-1.0f, - - -1.0f,-1.0f,-1.0f, // -Y side - 1.0f,-1.0f,-1.0f, - 1.0f,-1.0f, 1.0f, - -1.0f,-1.0f,-1.0f, - 1.0f,-1.0f, 1.0f, - -1.0f,-1.0f, 1.0f, - - -1.0f, 1.0f,-1.0f, // +Y side - -1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, - -1.0f, 1.0f,-1.0f, - 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f,-1.0f, - - 1.0f, 1.0f,-1.0f, // +X side - 1.0f, 1.0f, 1.0f, - 1.0f,-1.0f, 1.0f, - 1.0f,-1.0f, 1.0f, - 1.0f,-1.0f,-1.0f, - 1.0f, 1.0f,-1.0f, - - -1.0f, 1.0f, 1.0f, // +Z side - -1.0f,-1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, - -1.0f,-1.0f, 1.0f, - 1.0f,-1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, -}; - -static const float g_uv_buffer_data[] = { - 0.0f, 1.0f, // -X side - 1.0f, 1.0f, - 1.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 0.0f, - 0.0f, 1.0f, - - 1.0f, 1.0f, // -Z side - 0.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, - 1.0f, 0.0f, - 0.0f, 0.0f, - - 1.0f, 0.0f, // -Y side - 1.0f, 1.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 0.0f, 0.0f, - - 1.0f, 0.0f, // +Y side - 0.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, - - 1.0f, 0.0f, // +X side - 0.0f, 0.0f, - 0.0f, 1.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, - 1.0f, 0.0f, - - 0.0f, 0.0f, // +Z side - 0.0f, 1.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, - 1.0f, 0.0f, -}; -// clang-format on -enum class WsiPlatform { - auto_ = 0, - win32, - metal, - android, - qnx, - xcb, - xlib, - wayland, - directfb, - display, - fuchsia_display, - fuchsia_scenic, - invalid, // Sentinel just to indicate invalid user input -}; - -WsiPlatform wsi_from_string(std::string const &str) { - if (str == "auto") return WsiPlatform::auto_; -#if defined(VK_USE_PLATFORM_WIN32_KHR) - if (str == "win32") return WsiPlatform::win32; -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) - if (str == "metal") return WsiPlatform::metal; -#endif -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - if (str == "android") return WsiPlatform::android; -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - if (str == "qnx") return WsiPlatform::qnx; -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - if (str == "xcb") return WsiPlatform::xcb; -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - if (str == "xlib") return WsiPlatform::xlib; -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - if (str == "wayland") return WsiPlatform::wayland; -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - if (str == "directfb") return WsiPlatform::directfb; -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - if (str == "display") return WsiPlatform::display; -#endif -#if defined(VK_USE_PLATFORM_FUCHSIA) - if (str == "fuchsia_display") return WsiPlatform::fuchsia_display; - if (str == "fuchsia_scenic") return WsiPlatform::fuchsia_scenic; -#endif - return WsiPlatform::invalid; -}; - -const char *wsi_to_string(WsiPlatform wsi_platform) { - switch (wsi_platform) { - case (WsiPlatform::auto_): - return "auto"; -#if defined(VK_USE_PLATFORM_WIN32_KHR) - case (WsiPlatform::win32): - return "win32"; -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) - case (WsiPlatform::metal): - return "metal"; -#endif -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - case (WsiPlatform::android): - return "android"; -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - case (WsiPlatform::qnx): - return "qnx"; -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - case (WsiPlatform::xcb): - return "xcb"; -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - case (WsiPlatform::xlib): - return "xlib"; -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - case (WsiPlatform::wayland): - return "wayland"; -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - case (WsiPlatform::directfb): - return "directfb"; -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - case (WsiPlatform::display): - return "display"; -#endif -#if defined(VK_USE_PLATFORM_FUCHSIA) - case (WsiPlatform::fuchsia_display): - return "fuchsia_display"; - case (WsiPlatform::fuchsia_scenic): - return "fuchsia_scenic"; -#endif - default: - return "unknown"; - } -}; - -struct SubmissionResources { - vk::Fence fence; - vk::Semaphore image_acquired_semaphore; - vk::CommandBuffer cmd; - vk::CommandBuffer graphics_to_present_cmd; - vk::Buffer uniform_buffer; - vk::DeviceMemory uniform_memory; - void *uniform_memory_ptr = nullptr; - vk::DescriptorSet descriptor_set; -}; - -struct SwapchainImageResources { - vk::Image image; - vk::ImageView view; - vk::Framebuffer framebuffer; - vk::Semaphore draw_complete_semaphore; - vk::Semaphore image_ownership_semaphore; -}; - -struct Demo { - void build_image_ownership_cmd(const SubmissionResources &submission_resource, - const SwapchainImageResources &swapchain_image_resource); - vk::Bool32 check_layers(const std::vector<const char *> &check_names, const std::vector<vk::LayerProperties> &layers); - void cleanup(); - void create_device(); - void destroy_texture(texture_object &tex_objs); - void draw(); - void draw_build_cmd(const SubmissionResources &submission_resource, const SwapchainImageResources &swapchain_image_resource); - void prepare_init_cmd(); - void flush_init_cmd(); - void init(int argc, char **argv); - void check_and_set_wsi_platform(); - void init_vk(); - void select_physical_device(); - void init_vk_swapchain(); - - void prepare(); - void prepare_cube_data_buffers(); - void prepare_descriptor_layout(); - void prepare_descriptor_pool(); - void prepare_descriptor_set(); - void prepare_submission_sync_objects(); - vk::ShaderModule prepare_shader_module(const uint32_t *code, size_t size); - vk::ShaderModule prepare_vs(); - vk::ShaderModule prepare_fs(); - void prepare_pipeline(); - void prepare_render_pass(); - void prepare_texture_image(const char *filename, texture_object &tex_obj, vk::ImageTiling tiling, vk::ImageUsageFlags usage, - vk::MemoryPropertyFlags required_props); - void prepare_texture_buffer(const char *filename, texture_object &tex_obj); - void prepare_textures(); - - void resize(); - void create_surface(); - void prepare_swapchain(); - void prepare_framebuffers(); - void prepare_depth(); - - void set_image_layout(vk::Image image, vk::ImageAspectFlags aspectMask, vk::ImageLayout oldLayout, vk::ImageLayout newLayout, - vk::AccessFlags srcAccessMask, vk::PipelineStageFlags src_stages, vk::PipelineStageFlags dest_stages); - void update_data_buffer(void *uniform_memory_ptr); - bool loadTexture(const char *filename, uint8_t *rgba_data, vk::SubresourceLayout &layout, uint32_t &width, uint32_t &height); - bool memory_type_from_properties(uint32_t typeBits, vk::MemoryPropertyFlags requirements_mask, uint32_t &typeIndex); - vk::SurfaceFormatKHR pick_surface_format(const std::vector<vk::SurfaceFormatKHR> &surface_formats); - - static VKAPI_ATTR vk::Bool32 VKAPI_CALL debug_messenger_callback(vk::DebugUtilsMessageSeverityFlagBitsEXT messageSeverity, - vk::DebugUtilsMessageTypeFlagsEXT messageType, - const vk::DebugUtilsMessengerCallbackDataEXT *pCallbackData, - void *pUserData); - - template <WsiPlatform WSI_PLATFORM> - void create_window() = delete; - template <WsiPlatform WSI_PLATFORM> - void run() = delete; - template <WsiPlatform WSI_PLATFORM> - void execute(); -#if defined(VK_USE_PLATFORM_XLIB_KHR) - const char *init_xlib_connection(); - void handle_xlib_event(const XEvent *event); -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - const char *init_xcb_connection(); - void handle_xcb_event(const xcb_generic_event_t *event); -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - const char *init_wayland_connection(); -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - void handle_directfb_event(const DFBInputEvent *event); -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - vk::Result create_display_surface(); -#endif -#if defined(VK_USE_PLATFORM_FUCHSIA) - // Returns a layer name of static storage duration. - const char *get_fuchsia_image_pipe_layer() const; -#endif - - std::string name = "vkcubepp"; // Name to put on the window/icon -#if defined(VK_USE_PLATFORM_WIN32_KHR) - HINSTANCE connection = nullptr; // hInstance - Windows Instance - HWND window = nullptr; // hWnd - window handle - POINT minsize = {0, 0}; // minimum window size -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - void *xlib_library; - Window xlib_window = 0; - Atom xlib_wm_delete_window = 0; - Display *xlib_display = nullptr; -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - void *xcb_library; - xcb_window_t xcb_window = 0; - xcb_screen_t *screen = nullptr; - xcb_connection_t *connection = nullptr; - xcb_intern_atom_reply_t *atom_wm_delete_window = nullptr; -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - void *wayland_library = nullptr; - wl_display *wayland_display = nullptr; - wl_registry *registry = nullptr; - wl_compositor *compositor = nullptr; - wl_surface *wayland_window = nullptr; - xdg_wm_base *wm_base = nullptr; - zxdg_decoration_manager_v1 *xdg_decoration_mgr = nullptr; - zxdg_toplevel_decoration_v1 *toplevel_decoration = nullptr; - xdg_surface *window_surface = nullptr; - bool xdg_surface_has_been_configured = false; - xdg_toplevel *window_toplevel = nullptr; - wl_seat *seat = nullptr; - wl_pointer *pointer = nullptr; - wl_keyboard *keyboard = nullptr; - int pending_width = 0, pending_height = 0; -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - IDirectFB *dfb = nullptr; - IDirectFBSurface *directfb_window = nullptr; - IDirectFBEventBuffer *event_buffer = nullptr; -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) - void *caMetalLayer; -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - screen_context_t screen_context = nullptr; - screen_window_t screen_window = nullptr; - screen_event_t screen_event = nullptr; -#endif -#if defined(VK_USE_PLATFORM_FUCHSIA) - fuchsia_ui_views::ViewCreationToken view_creation_token; - async::Loop loop{&kAsyncLoopConfigNeverAttachToThread}; - fidl::ClientEnd<fuchsia_io::Directory> incoming; - std::unique_ptr<component::OutgoingDirectory> outgoing; - std::unique_ptr<FlatlandViewProviderService> view_provider_service; - std::unique_ptr<FlatlandView> flatland_view; -#endif - WsiPlatform wsi_platform = WsiPlatform::auto_; - vk::SurfaceKHR surface; - bool initialized; - bool swapchain_ready; - bool is_minimized; - bool use_staging_buffer = false; - bool separate_present_queue = false; - bool invalid_gpu_selection = false; - int32_t gpu_number = 0; - - // If true, the Demo renders on the protected memory. This requires the - // physical device to support protected memory. - bool protected_output = false; - - vk::Instance inst; - vk::DebugUtilsMessengerEXT debug_messenger; - vk::PhysicalDevice gpu; - vk::Device device; - vk::Queue graphics_queue; - vk::Queue present_queue; - uint32_t graphics_queue_family_index = 0; - uint32_t present_queue_family_index = 0; - vk::PhysicalDeviceProperties gpu_props; - std::vector<vk::QueueFamilyProperties> queue_props; - vk::PhysicalDeviceMemoryProperties memory_properties; - std::array<SubmissionResources, FRAME_LAG> submission_resources; - uint32_t current_submission_index = 0; - - std::vector<const char *> enabled_instance_extensions; - std::vector<const char *> enabled_layers; - std::vector<const char *> enabled_device_extensions; - - uint32_t width = 0; - uint32_t height = 0; - vk::Format format; - vk::ColorSpaceKHR color_space; - - vk::SwapchainKHR swapchain; - std::vector<SwapchainImageResources> swapchain_resources; - vk::PresentModeKHR presentMode = vk::PresentModeKHR::eFifo; - bool first_swapchain_frame; - - vk::CommandPool cmd_pool; - vk::CommandPool present_cmd_pool; - - struct { - vk::Format format; - vk::Image image; - vk::MemoryAllocateInfo mem_alloc; - vk::DeviceMemory mem; - vk::ImageView view; - } depth; - - static int32_t const texture_count = 1; - std::array<texture_object, texture_count> textures; - texture_object staging_texture; - - struct { - vk::Buffer buf; - vk::MemoryAllocateInfo mem_alloc; - vk::DeviceMemory mem; - vk::DescriptorBufferInfo buffer_info; - } uniform_data; - - vk::CommandBuffer cmd; // Buffer for initialization commands - vk::PipelineLayout pipeline_layout; - vk::DescriptorSetLayout desc_layout; - vk::PipelineCache pipelineCache; - vk::RenderPass render_pass; - vk::Pipeline pipeline; - - mat4x4 projection_matrix = {}; - mat4x4 view_matrix = {}; - mat4x4 model_matrix = {}; - - float spin_angle = 0.0f; - float spin_increment = 0.0f; - bool pause = false; - - vk::ShaderModule vert_shader_module; - vk::ShaderModule frag_shader_module; - - vk::DescriptorPool desc_pool; - vk::DescriptorSet desc_set; - - std::vector<vk::Framebuffer> framebuffers; - - bool quit = false; - uint32_t curFrame = 0; - uint32_t frameCount = 0; - bool validate = false; - bool in_callback = false; - bool use_debug_messenger = false; - bool use_break = false; - bool suppress_popups = false; - bool force_errors = false; -}; - -#ifdef _WIN32 -// MS-Windows event handling function: -LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -#endif - -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -static void pointer_handle_enter(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t sx, - wl_fixed_t sy) {} - -static void pointer_handle_leave(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface) {} - -static void pointer_handle_motion(void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy) {} - -static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, - uint32_t state) { - Demo &demo = *static_cast<Demo *>(data); - if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED) { - xdg_toplevel_move(demo.window_toplevel, demo.seat, serial); - } -} - -static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) {} - -static const struct wl_pointer_listener pointer_listener = { - pointer_handle_enter, pointer_handle_leave, pointer_handle_motion, pointer_handle_button, pointer_handle_axis, -}; - -static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size) {} - -static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, - struct wl_array *keys) {} - -static void keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface) {} - -static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, - uint32_t state) { - if (state != WL_KEYBOARD_KEY_STATE_RELEASED) return; - Demo &demo = *static_cast<Demo *>(data); - switch (key) { - case KEY_ESC: // Escape - demo.quit = true; - break; - case KEY_LEFT: // left arrow key - demo.spin_angle -= demo.spin_increment; - break; - case KEY_RIGHT: // right arrow key - demo.spin_angle += demo.spin_increment; - break; - case KEY_SPACE: // space bar - demo.pause = !demo.pause; - break; - } -} - -static void keyboard_handle_modifiers(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, - uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {} - -static const struct wl_keyboard_listener keyboard_listener = { - keyboard_handle_keymap, keyboard_handle_enter, keyboard_handle_leave, keyboard_handle_key, keyboard_handle_modifiers, -}; - -static void seat_handle_capabilities(void *data, wl_seat *seat, uint32_t caps) { - // Subscribe to pointer events - Demo &demo = *static_cast<Demo *>(data); - if ((caps & WL_SEAT_CAPABILITY_POINTER) && !demo.pointer) { - demo.pointer = wl_seat_get_pointer(seat); - wl_pointer_add_listener(demo.pointer, &pointer_listener, &demo); - } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && demo.pointer) { - wl_pointer_destroy(demo.pointer); - demo.pointer = nullptr; - } - // Subscribe to keyboard events - if (caps & WL_SEAT_CAPABILITY_KEYBOARD) { - demo.keyboard = wl_seat_get_keyboard(seat); - wl_keyboard_add_listener(demo.keyboard, &keyboard_listener, &demo); - } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && demo.keyboard) { - wl_keyboard_destroy(demo.keyboard); - demo.keyboard = nullptr; - } -} - -static const wl_seat_listener seat_listener = { - seat_handle_capabilities, -}; - -static void wm_base_ping(void *data, xdg_wm_base *xdg_wm_base, uint32_t serial) { xdg_wm_base_pong(xdg_wm_base, serial); } - -static const struct xdg_wm_base_listener wm_base_listener = {wm_base_ping}; - -static void registry_handle_global(void *data, wl_registry *registry, uint32_t id, const char *interface, uint32_t version) { - Demo &demo = *static_cast<Demo *>(data); - // pickup wayland objects when they appear - if (strcmp(interface, wl_compositor_interface.name) == 0) { - demo.compositor = (wl_compositor *)wl_registry_bind(registry, id, &wl_compositor_interface, 1); - } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) { - demo.wm_base = (xdg_wm_base *)wl_registry_bind(registry, id, &xdg_wm_base_interface, 1); - xdg_wm_base_add_listener(demo.wm_base, &wm_base_listener, nullptr); - } else if (strcmp(interface, wl_seat_interface.name) == 0) { - demo.seat = (wl_seat *)wl_registry_bind(registry, id, &wl_seat_interface, 1); - wl_seat_add_listener(demo.seat, &seat_listener, &demo); - } else if (strcmp(interface, zxdg_decoration_manager_v1_interface.name) == 0) { - demo.xdg_decoration_mgr = - (zxdg_decoration_manager_v1 *)wl_registry_bind(registry, id, &zxdg_decoration_manager_v1_interface, 1); - } -} - -static void registry_handle_global_remove(void *data, wl_registry *registry, uint32_t name) {} - -static const wl_registry_listener registry_listener = {registry_handle_global, registry_handle_global_remove}; -#endif - -void Demo::build_image_ownership_cmd(const SubmissionResources &submission_resource, - const SwapchainImageResources &swapchain_image_resource) { - auto result = submission_resource.graphics_to_present_cmd.reset(); - VERIFY(result == vk::Result::eSuccess); - - result = submission_resource.graphics_to_present_cmd.begin( - vk::CommandBufferBeginInfo().setFlags(vk::CommandBufferUsageFlagBits::eSimultaneousUse)); - VERIFY(result == vk::Result::eSuccess); - - auto const image_ownership_barrier = - vk::ImageMemoryBarrier() - .setSrcAccessMask(vk::AccessFlags()) - .setDstAccessMask(vk::AccessFlags()) - .setOldLayout(vk::ImageLayout::ePresentSrcKHR) - .setNewLayout(vk::ImageLayout::ePresentSrcKHR) - .setSrcQueueFamilyIndex(graphics_queue_family_index) - .setDstQueueFamilyIndex(present_queue_family_index) - .setImage(swapchain_image_resource.image) - .setSubresourceRange(vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1)); - - submission_resource.graphics_to_present_cmd.pipelineBarrier(vk::PipelineStageFlagBits::eBottomOfPipe, - vk::PipelineStageFlagBits::eBottomOfPipe, vk::DependencyFlagBits(), - {}, {}, image_ownership_barrier); - - result = submission_resource.graphics_to_present_cmd.end(); - VERIFY(result == vk::Result::eSuccess); -} - -vk::Bool32 Demo::check_layers(const std::vector<const char *> &check_names, const std::vector<vk::LayerProperties> &layers) { - for (const auto &name : check_names) { - vk::Bool32 found = VK_FALSE; - for (const auto &layer : layers) { - if (!strcmp(name, layer.layerName)) { - found = VK_TRUE; - break; - } - } - if (!found) { - fprintf(stderr, "Cannot find layer: %s\n", name); - return 0; - } - } - return VK_TRUE; -} - -void Demo::cleanup() { - initialized = false; - auto result = device.waitIdle(); - VERIFY(result == vk::Result::eSuccess); - - device.destroyCommandPool(cmd_pool); - if (separate_present_queue) { - device.destroyCommandPool(present_cmd_pool); - } - - device.destroyDescriptorPool(desc_pool); - - device.destroyPipeline(pipeline); - device.destroyPipelineCache(pipelineCache); - device.destroyRenderPass(render_pass); - device.destroyPipelineLayout(pipeline_layout); - device.destroyDescriptorSetLayout(desc_layout); - - for (const auto &tex : textures) { - device.destroyImageView(tex.view); - device.destroyImage(tex.image); - device.freeMemory(tex.mem); - device.destroySampler(tex.sampler); - } - - device.destroyImageView(depth.view); - device.destroyImage(depth.image); - device.freeMemory(depth.mem); - - for (auto &swapchain_resource : swapchain_resources) { - device.destroyFramebuffer(swapchain_resource.framebuffer); - device.destroyImageView(swapchain_resource.view); - device.destroySemaphore(swapchain_resource.draw_complete_semaphore); - if (separate_present_queue) { - device.destroySemaphore(swapchain_resource.image_ownership_semaphore); - } - } - - device.destroySwapchainKHR(swapchain); - - for (const auto &submission_resource : submission_resources) { - device.destroyFence(submission_resource.fence); - device.destroySemaphore(submission_resource.image_acquired_semaphore); - device.destroyBuffer(submission_resource.uniform_buffer); - device.unmapMemory(submission_resource.uniform_memory); - device.freeMemory(submission_resource.uniform_memory); - } - - device.destroy(); - inst.destroySurfaceKHR(surface); - -#if defined(VK_USE_PLATFORM_XLIB_KHR) - if (wsi_platform == WsiPlatform::xlib) { - XDestroyWindow(xlib_display, xlib_window); - XCloseDisplay(xlib_display); - } -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - if (wsi_platform == WsiPlatform::xcb) { - xcb_destroy_window(connection, xcb_window); - xcb_disconnect(connection); - free(atom_wm_delete_window); - } -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - if (wsi_platform == WsiPlatform::wayland) { - if (keyboard) wl_keyboard_destroy(keyboard); - if (pointer) wl_pointer_destroy(pointer); - if (seat) wl_seat_destroy(seat); - xdg_toplevel_destroy(window_toplevel); - xdg_surface_destroy(window_surface); - wl_surface_destroy(wayland_window); - xdg_wm_base_destroy(wm_base); - if (xdg_decoration_mgr) { - zxdg_toplevel_decoration_v1_destroy(toplevel_decoration); - zxdg_decoration_manager_v1_destroy(xdg_decoration_mgr); - } - wl_compositor_destroy(compositor); - wl_registry_destroy(registry); - wl_display_disconnect(wayland_display); - } -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - if (wsi_platform == WsiPlatform::directfb) { - event_buffer->Release(event_buffer); - directfb_window->Release(directfb_window); - dfb->Release(dfb); - } -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - screen_destroy_event(screen_event); - screen_destroy_window(screen_window); - screen_destroy_context(screen_context); -#endif - if (use_debug_messenger) { - inst.destroyDebugUtilsMessengerEXT(debug_messenger); - } - inst.destroy(); -} - -void Demo::create_device() { - float priorities = 0.0; - - std::vector<vk::DeviceQueueCreateInfo> queues; - const vk::DeviceQueueCreateFlags queue_create_flags = - protected_output ? vk::DeviceQueueCreateFlagBits::eProtected : vk::DeviceQueueCreateFlags{}; - queues.push_back(vk::DeviceQueueCreateInfo() - .setQueueFamilyIndex(graphics_queue_family_index) - .setQueuePriorities(priorities) - .setFlags(queue_create_flags)); - - if (separate_present_queue) { - queues.push_back( - vk::DeviceQueueCreateInfo().setQueueFamilyIndex(present_queue_family_index).setQueuePriorities(priorities)); - } - - auto const protected_memory_features = vk::PhysicalDeviceProtectedMemoryFeatures().setProtectedMemory(protected_output); - auto deviceInfo = vk::DeviceCreateInfo() - .setPNext(protected_output ? &protected_memory_features : nullptr) - .setQueueCreateInfos(queues) - .setPEnabledExtensionNames(enabled_device_extensions); - auto device_return = gpu.createDevice(deviceInfo); - VERIFY(device_return.result == vk::Result::eSuccess); - device = device_return.value; - VULKAN_HPP_DEFAULT_DISPATCHER.init(device); -} - -void Demo::destroy_texture(texture_object &tex_objs) { - // clean up staging resources - device.freeMemory(tex_objs.mem); - if (tex_objs.image) device.destroyImage(tex_objs.image); - if (tex_objs.buffer) device.destroyBuffer(tex_objs.buffer); -} - -void Demo::draw() { - // Don't draw if initialization isn't complete, if the swapchain became outdated, or if the window is minimized - if (!initialized || !swapchain_ready || is_minimized) { - return; - } - - auto ¤t_submission = submission_resources[current_submission_index]; - - // Ensure no more than FRAME_LAG renderings are outstanding - const vk::Result wait_result = device.waitForFences(current_submission.fence, VK_TRUE, UINT64_MAX); - VERIFY(wait_result == vk::Result::eSuccess || wait_result == vk::Result::eTimeout); - - vk::Result acquire_result; - uint32_t current_swapchain_image_index = 0; - do { - acquire_result = device.acquireNextImageKHR(swapchain, UINT64_MAX, current_submission.image_acquired_semaphore, vk::Fence(), - ¤t_swapchain_image_index); - if (acquire_result == vk::Result::eErrorOutOfDateKHR) { - // demo.swapchain is out of date (e.g. the window was resized) and - // must be recreated: - resize(); - } else if (acquire_result == vk::Result::eSuboptimalKHR) { - // swapchain is not as optimal as it could be, but the platform's - // presentation engine will still present the image correctly. - break; - } else if (acquire_result == vk::Result::eErrorSurfaceLostKHR) { - inst.destroySurfaceKHR(surface); - create_surface(); - resize(); - } else { - VERIFY(acquire_result == vk::Result::eSuccess); - } - // If we minimized then stop trying to draw - if (!swapchain_ready) { - return; - } - } while (acquire_result != vk::Result::eSuccess); - - auto ¤t_swapchain_resource = swapchain_resources[current_swapchain_image_index]; - - update_data_buffer(submission_resources[current_submission_index].uniform_memory_ptr); - - draw_build_cmd(current_submission, current_swapchain_resource); - - if (separate_present_queue) { - build_image_ownership_cmd(current_submission, current_swapchain_resource); - } - - // Only reset right before submitting so we can't deadlock on an un-signalled fence that has nothing submitted to it - auto reset_result = device.resetFences({current_submission.fence}); - VERIFY(reset_result == vk::Result::eSuccess); - - // Wait for the image acquired semaphore to be signaled to ensure - // that the image won't be rendered to until the presentation - // engine has fully released ownership to the application, and it is - // okay to render to the image. - vk::PipelineStageFlags const pipe_stage_flags = vk::PipelineStageFlagBits::eColorAttachmentOutput; - auto protected_submit_info = vk::ProtectedSubmitInfo().setProtectedSubmit(protected_output); - - auto submit_result = graphics_queue.submit(vk::SubmitInfo() - .setPNext(protected_output ? &protected_submit_info : nullptr) - .setWaitDstStageMask(pipe_stage_flags) - .setWaitSemaphores(current_submission.image_acquired_semaphore) - .setCommandBuffers(current_submission.cmd) - .setSignalSemaphores(current_swapchain_resource.draw_complete_semaphore), - current_submission.fence); - VERIFY(submit_result == vk::Result::eSuccess); - - if (separate_present_queue) { - // If we are using separate queues, change image ownership to the - // present queue before presenting, waiting for the draw complete - // semaphore and signalling the ownership released semaphore when - // finished - auto change_owner_result = - present_queue.submit(vk::SubmitInfo() - .setWaitDstStageMask(pipe_stage_flags) - .setWaitSemaphores(current_swapchain_resource.draw_complete_semaphore) - .setCommandBuffers(current_submission.graphics_to_present_cmd) - .setSignalSemaphores(current_swapchain_resource.image_ownership_semaphore)); - VERIFY(change_owner_result == vk::Result::eSuccess); - } - - const auto presentInfo = vk::PresentInfoKHR() - .setWaitSemaphores(separate_present_queue ? current_swapchain_resource.image_ownership_semaphore - : current_swapchain_resource.draw_complete_semaphore) - .setSwapchains(swapchain) - .setImageIndices(current_swapchain_image_index); - - // If we are using separate queues we have to wait for image ownership, - // otherwise wait for draw complete - auto present_result = present_queue.presentKHR(&presentInfo); - current_submission_index += 1; - current_submission_index %= FRAME_LAG; - first_swapchain_frame = false; - if (present_result == vk::Result::eErrorOutOfDateKHR) { - // swapchain is out of date (e.g. the window was resized) and - // must be recreated: - resize(); - } else if (present_result == vk::Result::eSuboptimalKHR) { - // SUBOPTIMAL could be due to resize - vk::SurfaceCapabilitiesKHR surfCapabilities; - auto caps_result = gpu.getSurfaceCapabilitiesKHR(surface, &surfCapabilities); - VERIFY(caps_result == vk::Result::eSuccess); - if (surfCapabilities.currentExtent.width != width || surfCapabilities.currentExtent.height != height) { - resize(); - } - } else if (present_result == vk::Result::eErrorSurfaceLostKHR) { - inst.destroySurfaceKHR(surface); - create_surface(); - resize(); - } else { - VERIFY(present_result == vk::Result::eSuccess); - } -} - -void Demo::draw_build_cmd(const SubmissionResources &submission_resource, const SwapchainImageResources &swapchain_image_resource) { - const auto commandBuffer = submission_resource.cmd; - vk::ClearValue const clearValues[2] = {vk::ClearColorValue(std::array<float, 4>({{0.2f, 0.2f, 0.2f, 0.2f}})), - vk::ClearDepthStencilValue(1.0f, 0u)}; - auto result = commandBuffer.reset(); - VERIFY(result == vk::Result::eSuccess); - - result = commandBuffer.begin(vk::CommandBufferBeginInfo().setFlags(vk::CommandBufferUsageFlagBits::eSimultaneousUse)); - VERIFY(result == vk::Result::eSuccess); - - commandBuffer.beginRenderPass(vk::RenderPassBeginInfo() - .setRenderPass(render_pass) - .setFramebuffer(swapchain_image_resource.framebuffer) - .setRenderArea(vk::Rect2D(vk::Offset2D{}, vk::Extent2D(width, height))) - .setClearValueCount(2) - .setPClearValues(clearValues), - vk::SubpassContents::eInline); - - commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline); - commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline_layout, 0, submission_resource.descriptor_set, {}); - float viewport_dimension; - float viewport_x = 0.0f; - float viewport_y = 0.0f; - if (width < height) { - viewport_dimension = static_cast<float>(width); - viewport_y = (height - width) / 2.0f; - } else { - viewport_dimension = static_cast<float>(height); - viewport_x = (width - height) / 2.0f; - } - - commandBuffer.setViewport(0, vk::Viewport() - .setX(viewport_x) - .setY(viewport_y) - .setWidth(viewport_dimension) - .setHeight(viewport_dimension) - .setMinDepth(0.0f) - .setMaxDepth(1.0f)); - - commandBuffer.setScissor(0, vk::Rect2D(vk::Offset2D{}, vk::Extent2D(width, height))); - commandBuffer.draw(12 * 3, 1, 0, 0); - // Note that ending the renderpass changes the image's layout from - // COLOR_ATTACHMENT_OPTIMAL to PRESENT_SRC_KHR - commandBuffer.endRenderPass(); - - if (separate_present_queue) { - // We have to transfer ownership from the graphics queue family to - // the - // present queue family to be able to present. Note that we don't - // have - // to transfer from present queue family back to graphics queue - // family at - // the start of the next frame because we don't care about the - // image's - // contents at that point. - commandBuffer.pipelineBarrier( - vk::PipelineStageFlagBits::eBottomOfPipe, vk::PipelineStageFlagBits::eBottomOfPipe, vk::DependencyFlagBits(), {}, {}, - vk::ImageMemoryBarrier() - .setSrcAccessMask(vk::AccessFlags()) - .setDstAccessMask(vk::AccessFlags()) - .setOldLayout(vk::ImageLayout::ePresentSrcKHR) - .setNewLayout(vk::ImageLayout::ePresentSrcKHR) - .setSrcQueueFamilyIndex(graphics_queue_family_index) - .setDstQueueFamilyIndex(present_queue_family_index) - .setImage(swapchain_image_resource.image) - .setSubresourceRange(vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1))); - } - - result = commandBuffer.end(); - VERIFY(result == vk::Result::eSuccess); -} - -void Demo::prepare_init_cmd() { - vk::CommandPoolCreateFlags cmd_pool_create_flags = - protected_output ? vk::CommandPoolCreateFlagBits::eProtected : vk::CommandPoolCreateFlags{}; - cmd_pool_create_flags |= vk::CommandPoolCreateFlagBits::eResetCommandBuffer; - auto cmd_pool_return = device.createCommandPool( - vk::CommandPoolCreateInfo().setQueueFamilyIndex(graphics_queue_family_index).setFlags(cmd_pool_create_flags)); - VERIFY(cmd_pool_return.result == vk::Result::eSuccess); - cmd_pool = cmd_pool_return.value; - - auto cmd_return = device.allocateCommandBuffers(vk::CommandBufferAllocateInfo() - .setCommandPool(cmd_pool) - .setLevel(vk::CommandBufferLevel::ePrimary) - .setCommandBufferCount(1)); - VERIFY(cmd_return.result == vk::Result::eSuccess); - cmd = cmd_return.value[0]; - - auto result = cmd.begin(vk::CommandBufferBeginInfo()); - VERIFY(result == vk::Result::eSuccess); -} - -void Demo::flush_init_cmd() { - auto result = cmd.end(); - VERIFY(result == vk::Result::eSuccess); - - auto fenceInfo = vk::FenceCreateInfo(); - if (force_errors) { - // Remove sType to intentionally force validation layer errors. - fenceInfo.sType = vk::StructureType::eRenderPassBeginInfo; - } - auto fence_return = device.createFence(fenceInfo); - VERIFY(fence_return.result == vk::Result::eSuccess); - auto fence = fence_return.value; - - auto const protected_submit_info = vk::ProtectedSubmitInfo().setProtectedSubmit(protected_output); - result = graphics_queue.submit( - vk::SubmitInfo().setPNext(protected_output ? &protected_submit_info : nullptr).setCommandBuffers(cmd), fence); - VERIFY(result == vk::Result::eSuccess); - - result = device.waitForFences(fence, VK_TRUE, UINT64_MAX); - VERIFY(result == vk::Result::eSuccess); - - device.freeCommandBuffers(cmd_pool, cmd); - device.destroyFence(fence); -} - -void Demo::init(int argc, char **argv) { - vec3 eye = {0.0f, 3.0f, 5.0f}; - vec3 origin = {0, 0, 0}; - vec3 up = {0.0f, 1.0f, 0.0}; - - presentMode = vk::PresentModeKHR::eFifo; - frameCount = UINT32_MAX; - width = 500; - height = 500; - /* Autodetect suitable / best GPU by default */ - gpu_number = -1; - - for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "--use_staging") == 0) { - use_staging_buffer = true; - continue; - } - if ((strcmp(argv[i], "--present_mode") == 0) && (i < argc - 1)) { - presentMode = static_cast<vk::PresentModeKHR>(atoi(argv[i + 1])); - i++; - continue; - } - if (strcmp(argv[i], "--break") == 0) { - use_break = true; - continue; - } - if (strcmp(argv[i], "--validate") == 0) { - validate = true; - continue; - } - if (strcmp(argv[i], "--xlib") == 0) { - fprintf(stderr, "--xlib is deprecated and no longer does anything\n"); - continue; - } - if (strcmp(argv[i], "--c") == 0 && frameCount == UINT32_MAX && i < argc - 1 && - sscanf(argv[i + 1], "%" SCNu32, &frameCount) == 1) { - i++; - continue; - } - if (strcmp(argv[i], "--width") == 0) { - int32_t in_width = 0; - if (i < argc - 1 && sscanf(argv[i + 1], "%d", &in_width) == 1) { - if (in_width > 0) { - width = static_cast<uint32_t>(in_width); - i++; - continue; - } else { - ERR_EXIT("The --width parameter must be greater than 0", "User Error"); - } - } - ERR_EXIT("The --width parameter must be followed by a number", "User Error"); - } - if (strcmp(argv[i], "--height") == 0) { - int32_t in_height = 0; - if (i < argc - 1 && sscanf(argv[i + 1], "%d", &in_height) == 1) { - if (in_height > 0) { - height = static_cast<uint32_t>(in_height); - i++; - continue; - } else { - ERR_EXIT("The --height parameter must be greater than 0", "User Error"); - } - } - ERR_EXIT("The --height parameter must be followed by a number", "User Error"); - } - if (strcmp(argv[i], "--suppress_popups") == 0) { - suppress_popups = true; - continue; - } - if ((strcmp(argv[i], "--gpu_number") == 0) && (i < argc - 1)) { - gpu_number = atoi(argv[i + 1]); - if (gpu_number < 0) invalid_gpu_selection = true; - i++; - continue; - } - if (strcmp(argv[i], "--force_errors") == 0) { - force_errors = true; - continue; - } - if (strcmp(argv[i], "--protected_output") == 0) { - protected_output = true; - continue; - } - if ((strcmp(argv[i], "--wsi") == 0) && (i < argc - 1)) { - std::string selection_input = argv[i + 1]; - for (char &c : selection_input) { - c = static_cast<char>(std::tolower(c)); - } - WsiPlatform selection = wsi_from_string(selection_input); - if (selection == WsiPlatform::invalid) { - printf( - "The --wsi parameter %s is not a supported WSI platform. The list of available platforms is available from " - "--help\n", - (const char *)&(argv[i + 1][0])); - fflush(stdout); - exit(1); - } - wsi_platform = selection; - i++; - continue; - } - - std::string wsi_platforms; -#if defined(VK_USE_PLATFORM_XCB_KHR) - wsi_platforms.append("xcb"); -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - if (!wsi_platforms.empty()) wsi_platforms.append("|"); - wsi_platforms.append("xlib"); -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - if (!wsi_platforms.empty()) wsi_platforms.append("|"); - wsi_platforms.append("wayland"); -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - if (!wsi_platforms.empty()) wsi_platforms.append("|"); - wsi_platforms.append("directfb"); -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - if (!wsi_platforms.empty()) wsi_platforms.append("|"); - wsi_platforms.append("display"); -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) - if (!wsi_platforms.empty()) wsi_platforms.append("|"); - wsi_platforms.append("metal"); -#endif -#if defined(VK_USE_PLATFORM_WIN32_KHR) - if (!wsi_platforms.empty()) wsi_platforms.append("|"); - wsi_platforms.append("win32"); -#endif -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - if (!wsi_platforms.empty()) wsi_platforms.append("|"); - wsi_platforms.append("android"); -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - if (!wsi_platforms.empty()) wsi_platforms.append("|"); - wsi_platforms.append("qnx"); -#endif -#if defined(VK_USE_PLATFORM_FUCHSIA) - if (!wsi_platforms.empty()) wsi_platforms.append("|"); - wsi_platforms.append("fuchsia_display"); - if (!wsi_platforms.empty()) wsi_platforms.append("|"); - wsi_platforms.append("fuchsia_scenic"); -#endif - std::stringstream usage; - usage << "Usage:\n " << APP_SHORT_NAME << "\t[--use_staging] [--validate]\n" - << "\t[--break] [--c <framecount>] [--suppress_popups]\n" - << "\t[--gpu_number <index of physical device>]\n" - << "\t[--present_mode <present mode enum>]\n" - << "\t[--width <width>] [--height <height>]\n" - << "\t[--force_errors]\n" - << "\t[--protected_output]\n" - << "\t[--wsi <" << wsi_platforms << ">]\n" - << "\t<present_mode_enum>\n" - << "\t\tVK_PRESENT_MODE_IMMEDIATE_KHR = " << VK_PRESENT_MODE_IMMEDIATE_KHR << "\n" - << "\t\tVK_PRESENT_MODE_MAILBOX_KHR = " << VK_PRESENT_MODE_MAILBOX_KHR << "\n" - << "\t\tVK_PRESENT_MODE_FIFO_KHR = " << VK_PRESENT_MODE_FIFO_KHR << "\n" - << "\t\tVK_PRESENT_MODE_FIFO_RELAXED_KHR = " << VK_PRESENT_MODE_FIFO_RELAXED_KHR << "\n"; - -#if defined(_WIN32) - if (!suppress_popups) MessageBox(nullptr, usage.str().c_str(), "Usage Error", MB_OK); -#else - std::cerr << usage.str(); - std::cerr.flush(); -#endif - exit(1); - } - - initialized = false; - - init_vk(); - - spin_angle = 4.0f; - spin_increment = 0.2f; - pause = false; - - mat4x4_perspective(projection_matrix, static_cast<float>(degreesToRadians(45.0f)), 1.0f, 0.1f, 100.0f); - mat4x4_look_at(view_matrix, eye, origin, up); - mat4x4_identity(model_matrix); - - projection_matrix[1][1] *= -1; // Flip projection matrix from GL to Vulkan orientation. -} - -#if defined(VK_USE_PLATFORM_XCB_KHR) -const char *Demo::init_xcb_connection() { - xcb_library = initialize_xcb(); - if (NULL == xcb_library) { - return "Cannot load XLIB dynamic library."; - } - const xcb_setup_t *setup; - xcb_screen_iterator_t iter; - int scr; - - const char *display_envar = getenv("DISPLAY"); - if (display_envar == nullptr || display_envar[0] == '\0') { - return "Environment variable DISPLAY requires a valid value."; - } - - connection = xcb_connect(nullptr, &scr); - if (xcb_connection_has_error(connection) > 0) { - return "Cannot connect to XCB."; - } - - setup = xcb_get_setup(connection); - iter = xcb_setup_roots_iterator(setup); - while (scr-- > 0) xcb_screen_next(&iter); - - screen = iter.data; - return NULL; -} -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) -const char *Demo::init_xlib_connection() { - xlib_library = initialize_xlib(); - if (NULL == xlib_library) { - return "Cannot load XLIB dynamic library."; - } - return NULL; -} -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -const char *Demo::init_wayland_connection() { - wayland_library = initialize_wayland(); - if (NULL == wayland_library) { - return "Cannot load wayland dynamic library."; - } - wayland_display = wl_display_connect(nullptr); - - if (wayland_display == nullptr) { - return "Cannot connect to wayland."; - } - - registry = wl_display_get_registry(wayland_display); - wl_registry_add_listener(registry, ®istry_listener, this); - wl_display_dispatch(wayland_display); - return NULL; -} -#endif - -void Demo::check_and_set_wsi_platform() { -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - if (wsi_platform == WsiPlatform::wayland || wsi_platform == WsiPlatform::auto_) { - auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), - [](const char *str) { return 0 == strcmp(str, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); }); - if (found != enabled_instance_extensions.end()) { - const char *error_msg = init_wayland_connection(); - if (error_msg != NULL) { - if (wsi_platform == WsiPlatform::wayland) { - fprintf(stderr, "%s\nExiting ...\n", error_msg); - fflush(stdout); - exit(1); - } - } else { - wsi_platform = WsiPlatform::wayland; - return; - } - } - } -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - if (wsi_platform == WsiPlatform::xcb || wsi_platform == WsiPlatform::auto_) { - auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), - [](const char *str) { return 0 == strcmp(str, VK_KHR_XCB_SURFACE_EXTENSION_NAME); }); - if (found != enabled_instance_extensions.end()) { - const char *error_msg = init_xcb_connection(); - if (error_msg != NULL) { - if (wsi_platform == WsiPlatform::xcb) { - fprintf(stderr, "%s\nExiting ...\n", error_msg); - fflush(stdout); - exit(1); - } - } else { - wsi_platform = WsiPlatform::xcb; - return; - } - } - } -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - if (wsi_platform == WsiPlatform::xlib || wsi_platform == WsiPlatform::auto_) { - auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), - [](const char *str) { return 0 == strcmp(str, VK_KHR_XLIB_SURFACE_EXTENSION_NAME); }); - if (found != enabled_instance_extensions.end()) { - const char *error_msg = init_xlib_connection(); - if (error_msg != NULL) { - if (wsi_platform == WsiPlatform::xlib) { - fprintf(stderr, "%s\nExiting ...\n", error_msg); - fflush(stdout); - exit(1); - } - } else { - wsi_platform = WsiPlatform::xlib; - return; - } - } - } -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - if (wsi_platform == WsiPlatform::directfb || wsi_platform == WsiPlatform::auto_) { - auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), - [](const char *str) { return 0 == strcmp(str, VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME); }); - if (found != enabled_instance_extensions.end()) { - // Because DirectFB is still linked in, we can assume that it works if we got here - wsi_platform = WsiPlatform::directfb; - return; - } - } -#endif -#if defined(VK_USE_PLATFORM_WIN32_KHR) - if (wsi_platform == WsiPlatform::win32 || wsi_platform == WsiPlatform::auto_) { - auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), - [](const char *str) { return 0 == strcmp(str, VK_KHR_WIN32_SURFACE_EXTENSION_NAME); }); - if (found != enabled_instance_extensions.end()) { - wsi_platform = WsiPlatform::win32; - return; - } - } -#endif -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - if (wsi_platform == WsiPlatform::android || wsi_platform == WsiPlatform::auto_) { - auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), - [](const char *str) { return 0 == strcmp(str, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); }); - if (found != enabled_instance_extensions.end()) { - wsi_platform = WsiPlatform::android; - return; - } - } -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) - if (wsi_platform == WsiPlatform::metal || wsi_platform == WsiPlatform::auto_) { - auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), - [](const char *str) { return 0 == strcmp(str, VK_EXT_METAL_SURFACE_EXTENSION_NAME); }); - if (found != enabled_instance_extensions.end()) { - wsi_platform = WsiPlatform::metal; - return; - } - } -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - if (wsi_platform == WsiPlatform::qnx || wsi_platform == WsiPlatform::auto_) { - auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), - [](const char *str) { return 0 == strcmp(str, VK_QNX_SCREEN_SURFACE_EXTENSION_NAME); }); - if (found != enabled_instance_extensions.end()) { - wsi_platform = WsiPlatform::qnx; - return; - } - } -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - if (wsi_platform == WsiPlatform::display || wsi_platform == WsiPlatform::auto_) { - auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), - [](const char *str) { return 0 == strcmp(str, VK_KHR_DISPLAY_EXTENSION_NAME); }); - if (found != enabled_instance_extensions.end()) { - wsi_platform = WsiPlatform::display; - return; - } - } -#endif -#if defined(VK_USE_PLATFORM_FUCHSIA) - if (wsi_platform == WsiPlatform::auto_) { - ERR_EXIT("auto WSI platform is not supported on Fuchsia", "check_and_set_wsi_platform error"); - } -#endif -} -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -int find_display_gpu(int gpu_number, const std::vector<vk::PhysicalDevice> &physical_devices) { - uint32_t display_count = 0; - int gpu_return = gpu_number; - if (gpu_number >= 0) { - auto display_props_return = physical_devices[gpu_number].getDisplayPropertiesKHR(); - VERIFY(display_props_return.result == vk::Result::eSuccess); - display_count = static_cast<uint32_t>(display_props_return.value.size()); - } else { - for (uint32_t i = 0; i < physical_devices.size(); i++) { - auto display_props_return = physical_devices[i].getDisplayPropertiesKHR(); - VERIFY(display_props_return.result == vk::Result::eSuccess); - if (display_props_return.value.size() > 0) { - display_count = static_cast<uint32_t>(display_props_return.value.size()); - gpu_return = i; - break; - } - } - } - if (display_count > 0) - return gpu_return; - else - return -1; -} -#endif -VKAPI_ATTR vk::Bool32 VKAPI_CALL Demo::debug_messenger_callback(vk::DebugUtilsMessageSeverityFlagBitsEXT messageSeverity, - vk::DebugUtilsMessageTypeFlagsEXT messageType, - const vk::DebugUtilsMessengerCallbackDataEXT *pCallbackData, - void *pUserData) { - std::ostringstream message; - Demo &demo = *static_cast<Demo *>(pUserData); - - if (demo.use_break) { -#ifndef WIN32 - raise(SIGTRAP); -#else - DebugBreak(); -#endif - } - message << vk::to_string(vk::DebugUtilsMessageSeverityFlagBitsEXT(messageSeverity)); - message << " : " + vk::to_string(vk::DebugUtilsMessageTypeFlagsEXT(messageType)); - - if (vk::DebugUtilsMessageTypeFlagsEXT(messageType) & vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation) { - validation_error = 1; - } - - message << " - Message Id Number: " << std::to_string(pCallbackData->messageIdNumber); - message << " | Message Id Name: " << (pCallbackData->pMessageIdName == nullptr ? "" : pCallbackData->pMessageIdName) << "\n\t" - << pCallbackData->pMessage << "\n"; - - if (pCallbackData->objectCount > 0) { - message << "\n\tObjects - " << pCallbackData->objectCount << "\n"; - for (uint32_t object = 0; object < pCallbackData->objectCount; ++object) { - message << "\t\tObject[" << object << "] - " - << vk::to_string(vk::ObjectType(pCallbackData->pObjects[object].objectType)) << ", Handle "; - - // Print handle correctly if it is a dispatchable handle - aka a pointer - vk::ObjectType t = pCallbackData->pObjects[object].objectType; - if (t == vk::ObjectType::eInstance || t == vk::ObjectType::ePhysicalDevice || t == vk::ObjectType::eDevice || - t == vk::ObjectType::eCommandBuffer || t == vk::ObjectType::eQueue) { - message << reinterpret_cast<void *>(static_cast<uintptr_t>(pCallbackData->pObjects[object].objectHandle)); - } else { - message << pCallbackData->pObjects[object].objectHandle; - } - if (NULL != pCallbackData->pObjects[object].pObjectName && strlen(pCallbackData->pObjects[object].pObjectName) > 0) { - message << ", Name \"" << pCallbackData->pObjects[object].pObjectName << "\"\n"; - } else { - message << "\n"; - } - } - } - if (pCallbackData->cmdBufLabelCount > 0) { - message << "\n\tCommand Buffer Labels - " << pCallbackData->cmdBufLabelCount << "\n"; - for (uint32_t cmd_buf_label = 0; cmd_buf_label < pCallbackData->cmdBufLabelCount; ++cmd_buf_label) { - message << "\t\tLabel[" << cmd_buf_label << "] - " << pCallbackData->pCmdBufLabels[cmd_buf_label].pLabelName << " { " - << pCallbackData->pCmdBufLabels[cmd_buf_label].color[0] << ", " - << pCallbackData->pCmdBufLabels[cmd_buf_label].color[1] << ", " - << pCallbackData->pCmdBufLabels[cmd_buf_label].color[2] << ", " - << pCallbackData->pCmdBufLabels[cmd_buf_label].color[2] << "}\n"; - } - } - -#ifdef _WIN32 - - if (!demo.suppress_popups) { - demo.in_callback = true; - auto message_string = message.str(); - MessageBox(NULL, message_string.c_str(), "Alert", MB_OK); - demo.in_callback = false; - } - -#elif defined(ANDROID) - - if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) { - __android_log_print(ANDROID_LOG_INFO, APP_SHORT_NAME, "%s", message.str()); - } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) { - __android_log_print(ANDROID_LOG_WARN, APP_SHORT_NAME, "%s", message.str()); - } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { - __android_log_print(ANDROID_LOG_ERROR, APP_SHORT_NAME, "%s", message.str()); - } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) { - __android_log_print(ANDROID_LOG_VERBOSE, APP_SHORT_NAME, "%s", message.str()); - } else { - __android_log_print(ANDROID_LOG_INFO, APP_SHORT_NAME, "%s", message.str()); - } - -#else - std::cout << message.str() << std::endl; // use endl to force a flush -#endif - return false; // Don't bail out, but keep going. -} - -void Demo::init_vk() { - VULKAN_HPP_DEFAULT_DISPATCHER.init(); - - uint32_t apiVersion = 0; - vk::Result enumerate_instance_version_result = vk::enumerateInstanceVersion(&apiVersion); - if (protected_output) { - if (enumerate_instance_version_result != vk::Result::eSuccess) { - ERR_EXIT("Failed to query instance version.", "vkCreateInstance Failure"); - } - if (apiVersion < VK_MAKE_VERSION(1, 1, 0)) { - ERR_EXIT("Need Vulkan 1.1 instance for protected output.", "vkCreateInstance Failure"); - } - } - - std::vector<char const *> instance_validation_layers = {"VK_LAYER_KHRONOS_validation"}; - - // Look for validation layers - vk::Bool32 validation_found = VK_FALSE; - if (validate) { - auto layers = vk::enumerateInstanceLayerProperties(); - VERIFY(layers.result == vk::Result::eSuccess); - - validation_found = check_layers(instance_validation_layers, layers.value); - if (validation_found) { - enabled_layers.push_back("VK_LAYER_KHRONOS_validation"); - } - - else { - ERR_EXIT( - "vkEnumerateInstanceLayerProperties failed to find required validation layer.\n\n" - "Please look at the Getting Started guide for additional information.\n", - "vkCreateInstance Failure"); - } - } - - /* Look for instance extensions */ - vk::Bool32 surfaceExtFound = VK_FALSE; - vk::Bool32 platformSurfaceExtFound = VK_FALSE; - bool portabilityEnumerationActive = false; - - // Some platforms (for example, Fuchsia) may have their WSI instance - // extension in layers and require the client to manually specify the - // instance extension layer. - vk::Optional<const std::string> instance_extension_layer = nullptr; -#if VK_USE_PLATFORM_FUCHSIA - const char *image_pipe_layer_name = get_fuchsia_image_pipe_layer(); - enabled_layers.push_back(image_pipe_layer_name); - - const std::string image_pipe_layer_name_str = image_pipe_layer_name; - instance_extension_layer = image_pipe_layer_name_str; -#endif // VK_USE_PLATFORM_FUCHSIA - - auto instance_extensions_return = vk::enumerateInstanceExtensionProperties(instance_extension_layer); - VERIFY(instance_extensions_return.result == vk::Result::eSuccess); - - for (const auto &extension : instance_extensions_return.value) { - if (!strcmp(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, extension.extensionName)) { - enabled_instance_extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } else if (!strcmp(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, extension.extensionName)) { - use_debug_messenger = true; - enabled_instance_extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); - } else if (!strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, extension.extensionName)) { - // We want cube to be able to enumerate drivers that support the portability_subset extension, so we have to enable the - // portability enumeration extension. - portabilityEnumerationActive = true; - enabled_instance_extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); - } else if (!strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extension.extensionName)) { - surfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); - } -#if defined(VK_USE_PLATFORM_WIN32_KHR) - else if (!strcmp(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, extension.extensionName) && - (wsi_platform == WsiPlatform::auto_ || wsi_platform == WsiPlatform::win32)) { - platformSurfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); - } -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - else if (!strcmp(VK_KHR_XLIB_SURFACE_EXTENSION_NAME, extension.extensionName) && - (wsi_platform == WsiPlatform::auto_ || wsi_platform == WsiPlatform::xlib)) { - platformSurfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - } -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - else if (!strcmp(VK_KHR_XCB_SURFACE_EXTENSION_NAME, extension.extensionName) && - (wsi_platform == WsiPlatform::auto_ || wsi_platform == WsiPlatform::xcb)) { - platformSurfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); - } -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - else if (!strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, extension.extensionName) && - (wsi_platform == WsiPlatform::auto_ || wsi_platform == WsiPlatform::wayland)) { - platformSurfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); - } -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - else if (!strcmp(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME, extension.extensionName) && - (wsi_platform == WsiPlatform::auto_ || wsi_platform == WsiPlatform::directfb)) { - platformSurfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME); - } -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - else if (!strcmp(VK_KHR_DISPLAY_EXTENSION_NAME, extension.extensionName) && - (wsi_platform == WsiPlatform::auto_ || wsi_platform == WsiPlatform::display)) { - platformSurfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_KHR_DISPLAY_EXTENSION_NAME); - } -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) - else if (!strcmp(VK_EXT_METAL_SURFACE_EXTENSION_NAME, extension.extensionName) && - (wsi_platform == WsiPlatform::auto_ || wsi_platform == WsiPlatform::metal)) { - platformSurfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME); - } -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - else if (!strcmp(VK_QNX_SCREEN_SURFACE_EXTENSION_NAME, extension.extensionName) && - (wsi_platform == WsiPlatform::auto_ || wsi_platform == WsiPlatform::qnx)) { - platformSurfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_QNX_SCREEN_SURFACE_EXTENSION_NAME); - } -#endif -#if defined(VK_USE_PLATFORM_FUCHSIA) - else if (!strcmp(VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME, extension.extensionName)) { - platformSurfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME); - } -#endif - } - - if (!surfaceExtFound) { - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "This indicates that no compatible Vulkan installable client driver (ICD) is present or that the system is not " - "configured to present to the screen. \n", - "vkCreateInstance Failure"); - } - - if (!platformSurfaceExtFound) { - switch (wsi_platform) { -#if defined(VK_USE_PLATFORM_WIN32_KHR) - case (WsiPlatform::win32): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_WIN32_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform win32 is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - case (WsiPlatform::xcb): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_XCB_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform xcb is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - case (WsiPlatform::wayland): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform wayland is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - case (WsiPlatform::xlib): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_XLIB_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform xlib is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - case (WsiPlatform::directfb): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform directfb is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - case (WsiPlatform::display): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_DISPLAY_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform display is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) - case (WsiPlatform::metal): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_EXT_METAL_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform metal is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - case (WsiPlatform::qnx): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_QNX_SCREEN_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform qnx is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif -#if defined(VK_USE_PLATFORM_FUCHSIA) - case (WsiPlatform::fuchsia_display): - case (WsiPlatform::fuchsia_scenic): - ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME - " instance extension.\n\n" - "The selected WSI platform fuschia is not available, please choose a different WSI platform\n", - "vkCreateInstance Failure"); - break; -#endif - default: - case (WsiPlatform::auto_): - // Getting here indicates we are using the WSI extension that is default on this platform - ERR_EXIT( - "vkEnumerateInstanceExtensionProperties failed to find any supported WSI surface instance extensions.\n\n" - "This indicates that no compatible Vulkan installable client driver (ICD) is present or that the system is not " - "configured to present to the screen. \n", - "vkCreateInstance Failure"); - } - } - - bool auto_wsi_platform = wsi_platform == WsiPlatform::auto_; - - check_and_set_wsi_platform(); - - // Print a message to indicate the automatically set WSI platform - if (auto_wsi_platform && wsi_platform != WsiPlatform::auto_) { - fprintf(stderr, "Selected WSI platform: %s\n", wsi_to_string(wsi_platform)); - } - - vk::DebugUtilsMessageSeverityFlagsEXT severityFlags(vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | - vk::DebugUtilsMessageSeverityFlagBitsEXT::eError); - vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags(vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral | - vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance | - vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation); - auto debug_utils_create_info = vk::DebugUtilsMessengerCreateInfoEXT({}, severityFlags, messageTypeFlags, - &debug_messenger_callback, static_cast<void *>(this)); - - auto const app = vk::ApplicationInfo() - .setPApplicationName(APP_SHORT_NAME) - .setApplicationVersion(0) - .setPEngineName(APP_SHORT_NAME) - .setEngineVersion(0) - .setApiVersion(VK_API_VERSION_1_0); - auto const inst_info = vk::InstanceCreateInfo() - .setFlags(portabilityEnumerationActive ? vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR - : static_cast<vk::InstanceCreateFlagBits>(0)) - .setPNext((use_debug_messenger && validate) ? &debug_utils_create_info : nullptr) - .setPApplicationInfo(&app) - .setPEnabledLayerNames(enabled_layers) - .setPEnabledExtensionNames(enabled_instance_extensions); - - auto instance_result = vk::createInstance(inst_info); - if (instance_result.result == vk::Result::eErrorIncompatibleDriver) { - ERR_EXIT( - "Cannot find a compatible Vulkan installable client driver (ICD).\n\n" - "Please look at the Getting Started guide for additional information.\n", - "vkCreateInstance Failure"); - } else if (instance_result.result == vk::Result::eErrorExtensionNotPresent) { - ERR_EXIT( - "Cannot find a specified extension library.\n" - "Make sure your layers path is set appropriately.\n", - "vkCreateInstance Failure"); - } else if (instance_result.result != vk::Result::eSuccess) { - ERR_EXIT( - "vkCreateInstance failed.\n\n" - "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" - "Please look at the Getting Started guide for additional information.\n", - "vkCreateInstance Failure"); - } - inst = instance_result.value; - VULKAN_HPP_DEFAULT_DISPATCHER.init(inst); - - if (use_debug_messenger) { - auto create_debug_messenger_return = inst.createDebugUtilsMessengerEXT(debug_utils_create_info); - VERIFY(create_debug_messenger_return.result == vk::Result::eSuccess); - debug_messenger = create_debug_messenger_return.value; - } -} - -void Demo::select_physical_device() { - auto physical_device_return = inst.enumeratePhysicalDevices(); - VERIFY(physical_device_return.result == vk::Result::eSuccess); - auto physical_devices = physical_device_return.value; - - if (physical_devices.size() <= 0) { - ERR_EXIT( - "vkEnumeratePhysicalDevices reported zero accessible devices.\n\n" - "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" - "Please look at the Getting Started guide for additional information.\n", - "vkEnumeratePhysicalDevices Failure"); - } - - if (invalid_gpu_selection || (gpu_number >= 0 && !(static_cast<uint32_t>(gpu_number) < physical_devices.size()))) { - fprintf(stderr, "GPU %d specified is not present, GPU count = %zu\n", gpu_number, physical_devices.size()); - ERR_EXIT("Specified GPU number is not present", "User Error"); - } - - if (wsi_platform == WsiPlatform::display) { -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - gpu_number = find_display_gpu(gpu_number, physical_devices); - if (gpu_number < 0) { - printf("Cannot find any display!\n"); - fflush(stdout); - exit(1); - } -#else - printf( - "WSI selection was set to DISPLAY but vkcubepp was not compiled with support for the DISPLAY platform, exiting " - "\n"); - fflush(stdout); - exit(1); -#endif - } else { - /* Try to auto select most suitable device */ - if (gpu_number == -1) { - int prev_priority = 0; - for (uint32_t i = 0; i < physical_devices.size(); i++) { - const auto physicalDeviceProperties = physical_devices[i].getProperties(); - assert(physicalDeviceProperties.deviceType <= vk::PhysicalDeviceType::eCpu); - - auto support_result = physical_devices[i].getSurfaceSupportKHR(0, surface); - if (support_result.result != vk::Result::eSuccess || support_result.value != vk::True) { - continue; - } - - std::map<vk::PhysicalDeviceType, int> device_type_priorities = { - {vk::PhysicalDeviceType::eDiscreteGpu, 5}, {vk::PhysicalDeviceType::eIntegratedGpu, 4}, - {vk::PhysicalDeviceType::eVirtualGpu, 3}, {vk::PhysicalDeviceType::eCpu, 2}, - {vk::PhysicalDeviceType::eOther, 1}, - }; - int priority = -1; - if (device_type_priorities.find(physicalDeviceProperties.deviceType) != device_type_priorities.end()) { - priority = device_type_priorities[physicalDeviceProperties.deviceType]; - } - - if (priority > prev_priority) { - gpu_number = i; - prev_priority = priority; - } - } - } - } - assert(gpu_number >= 0); - gpu = physical_devices[gpu_number]; - { - auto physicalDeviceProperties = gpu.getProperties(); - fprintf(stderr, "Selected GPU %d: %s, type: %s\n", gpu_number, physicalDeviceProperties.deviceName.data(), - to_string(physicalDeviceProperties.deviceType).c_str()); - } - - /* Look for device extensions */ - vk::Bool32 swapchainExtFound = VK_FALSE; - - // Some platforms (for example, Fuchsia) may have their device swapchain - // extension in layers and require the client to manually specify the - // device swapchain extension layer. - vk::Optional<const std::string> device_extension_layer = nullptr; -#if VK_USE_PLATFORM_FUCHSIA - const std::string image_pipe_layer_name = get_fuchsia_image_pipe_layer(); - device_extension_layer = image_pipe_layer_name; -#endif // VK_USE_PLATFORM_FUCHSIA - - // Currently we assume that the device swapchain extension layer is always - // enabled when the instance is initialized. - assert((!device_extension_layer) || (std::any_of(enabled_layers.begin(), enabled_layers.end(), [&](const char *layer_name) { - return *device_extension_layer == layer_name; - }))); - - auto device_extension_return = gpu.enumerateDeviceExtensionProperties(device_extension_layer); - VERIFY(device_extension_return.result == vk::Result::eSuccess); - - for (const auto &extension : device_extension_return.value) { - if (!strcmp(VK_KHR_SWAPCHAIN_EXTENSION_NAME, extension.extensionName)) { - swapchainExtFound = 1; - enabled_device_extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - } else if (!strcmp("VK_KHR_portability_subset", extension.extensionName)) { - enabled_device_extensions.push_back("VK_KHR_portability_subset"); - } - } - - if (!swapchainExtFound) { - ERR_EXIT("vkEnumerateDeviceExtensionProperties failed to find the " VK_KHR_SWAPCHAIN_EXTENSION_NAME - " extension.\n\n" - "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" - "Please look at the Getting Started guide for additional information.\n", - "vkCreateInstance Failure"); - } - - gpu.getProperties(&gpu_props); - - if (protected_output && gpu_props.apiVersion < VK_MAKE_VERSION(1, 1, 0)) { - ERR_EXIT("Need Vulkan 1.1 physical device for protected output.", "VkPhysicalDevice failure"); - } - - /* Call with nullptr data to get count */ - queue_props = gpu.getQueueFamilyProperties(); - assert(queue_props.size() >= 1); - - // Query fine-grained feature support for this device. - // If app has specific feature requirements it should check supported - // features based on this query - vk::PhysicalDeviceFeatures physDevFeatures; - gpu.getFeatures(&physDevFeatures); -} - -void Demo::create_surface() { -// Create a WSI surface for the window: -#if defined(VK_USE_PLATFORM_WIN32_KHR) - if (wsi_platform == WsiPlatform::win32) { - auto const createInfo = vk::Win32SurfaceCreateInfoKHR().setHinstance(connection).setHwnd(window); - - auto result = inst.createWin32SurfaceKHR(&createInfo, nullptr, &surface); - VERIFY(result == vk::Result::eSuccess); - } -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - - if (wsi_platform == WsiPlatform::wayland) { - auto const createInfo = vk::WaylandSurfaceCreateInfoKHR().setDisplay(wayland_display).setSurface(wayland_window); - - auto result = inst.createWaylandSurfaceKHR(&createInfo, nullptr, &surface); - VERIFY(result == vk::Result::eSuccess); - return; - } -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - if (wsi_platform == WsiPlatform::xlib) { - auto const createInfo = vk::XlibSurfaceCreateInfoKHR().setDpy(xlib_display).setWindow(xlib_window); - - auto result = inst.createXlibSurfaceKHR(&createInfo, nullptr, &surface); - VERIFY(result == vk::Result::eSuccess); - } -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - if (wsi_platform == WsiPlatform::xcb) { - auto const createInfo = vk::XcbSurfaceCreateInfoKHR().setConnection(connection).setWindow(xcb_window); - - auto result = inst.createXcbSurfaceKHR(&createInfo, nullptr, &surface); - VERIFY(result == vk::Result::eSuccess); - } -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - if (wsi_platform == WsiPlatform::directfb) { - auto const createInfo = vk::DirectFBSurfaceCreateInfoEXT().setDfb(dfb).setSurface(directfb_window); - - auto result = inst.createDirectFBSurfaceEXT(&createInfo, nullptr, &surface); - VERIFY(result == vk::Result::eSuccess); - } -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) - { - auto const createInfo = vk::MetalSurfaceCreateInfoEXT().setPLayer(static_cast<CAMetalLayer *>(caMetalLayer)); - - auto result = inst.createMetalSurfaceEXT(&createInfo, nullptr, &surface); - VERIFY(result == vk::Result::eSuccess); - } -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - if (wsi_platform == WsiPlatform::display) { - auto result = create_display_surface(); - VERIFY(result == vk::Result::eSuccess); - } -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - if (wsi_platform == WsiPlatform::qnx) { - auto const createInfo = vk::ScreenSurfaceCreateInfoQNX().setContext(screen_context).setWindow(screen_window); - - auto result = inst.createScreenSurfaceQNX(&createInfo, nullptr, &surface); - VERIFY(result == vk::Result::eSuccess); - } -#endif -#if defined(VK_USE_PLATFORM_FUCHSIA) - if (wsi_platform == WsiPlatform::fuchsia_display) { - auto createInfo = vk::ImagePipeSurfaceCreateInfoFUCHSIA(); - auto result = inst.createImagePipeSurfaceFUCHSIA(&createInfo, nullptr, &surface); - VERIFY(result == vk::Result::eSuccess); - } - if (wsi_platform == WsiPlatform::fuchsia_scenic) { - auto createInfo = vk::ImagePipeSurfaceCreateInfoFUCHSIA(); - // We are using ImagePipeSurface here, but it is being migrated to Flatland and the handle parameter is Flatland's - // ViewCreationToken during this process. - createInfo.setImagePipeHandle(std::move(view_creation_token).value().release()); - auto result = inst.createImagePipeSurfaceFUCHSIA(&createInfo, nullptr, &surface); - VERIFY(result == vk::Result::eSuccess); - } -#endif -} - -void Demo::init_vk_swapchain() { - // Iterate over each queue to learn whether it supports presenting: - std::vector<vk::Bool32> supportsPresent; - for (uint32_t i = 0; i < static_cast<uint32_t>(queue_props.size()); i++) { - auto supports = gpu.getSurfaceSupportKHR(i, surface); - VERIFY(supports.result == vk::Result::eSuccess); - supportsPresent.push_back(supports.value); - } - - uint32_t graphicsQueueFamilyIndex = UINT32_MAX; - uint32_t presentQueueFamilyIndex = UINT32_MAX; - for (uint32_t i = 0; i < static_cast<uint32_t>(queue_props.size()); i++) { - if (queue_props[i].queueFlags & vk::QueueFlagBits::eGraphics) { - if (graphicsQueueFamilyIndex == UINT32_MAX) { - graphicsQueueFamilyIndex = i; - } - - if (supportsPresent[i] == VK_TRUE) { - graphicsQueueFamilyIndex = i; - presentQueueFamilyIndex = i; - break; - } - } - } - - if (presentQueueFamilyIndex == UINT32_MAX) { - // If didn't find a queue that supports both graphics and present, - // then - // find a separate present queue. - for (uint32_t i = 0; i < queue_props.size(); ++i) { - if (supportsPresent[i] == VK_TRUE) { - presentQueueFamilyIndex = i; - break; - } - } - } - - // Generate error if could not find both a graphics and a present queue - if (graphicsQueueFamilyIndex == UINT32_MAX || presentQueueFamilyIndex == UINT32_MAX) { - ERR_EXIT("Could not find both graphics and present queues\n", "Swapchain Initialization Failure"); - } - - graphics_queue_family_index = graphicsQueueFamilyIndex; - present_queue_family_index = presentQueueFamilyIndex; - separate_present_queue = (graphics_queue_family_index != present_queue_family_index); - - create_device(); - - if (protected_output) { - auto const queue_info2 = vk::DeviceQueueInfo2() - .setFlags(vk::DeviceQueueCreateFlagBits::eProtected) - .setQueueFamilyIndex(graphics_queue_family_index) - .setQueueIndex(0); - device.getQueue2(&queue_info2, &graphics_queue); - } else { - graphics_queue = device.getQueue(graphics_queue_family_index, 0); - } - - if (!separate_present_queue) { - present_queue = graphics_queue; - } else { - present_queue = device.getQueue(present_queue_family_index, 0); - } - - // Get the list of VkFormat's that are supported: - auto surface_formats_return = gpu.getSurfaceFormatsKHR(surface); - VERIFY(surface_formats_return.result == vk::Result::eSuccess); - - vk::SurfaceFormatKHR surfaceFormat = pick_surface_format(surface_formats_return.value); - format = surfaceFormat.format; - color_space = surfaceFormat.colorSpace; - - quit = false; - first_swapchain_frame = true; - curFrame = 0; - - // Get Memory information and properties - memory_properties = gpu.getMemoryProperties(); -} - -void Demo::prepare() { - prepare_init_cmd(); - prepare_textures(); - prepare_cube_data_buffers(); - - prepare_descriptor_layout(); - // Only need to know the format of the depth buffer before we create the renderpass - depth.format = vk::Format::eD16Unorm; - prepare_render_pass(); - prepare_pipeline(); - - for (auto &submission_resource : submission_resources) { - auto alloc_return = device.allocateCommandBuffers(vk::CommandBufferAllocateInfo() - .setCommandPool(cmd_pool) - .setLevel(vk::CommandBufferLevel::ePrimary) - .setCommandBufferCount(1)); - VERIFY(alloc_return.result == vk::Result::eSuccess); - submission_resource.cmd = alloc_return.value[0]; - } - - if (separate_present_queue) { - auto present_cmd_pool_return = - device.createCommandPool(vk::CommandPoolCreateInfo().setQueueFamilyIndex(present_queue_family_index)); - VERIFY(present_cmd_pool_return.result == vk::Result::eSuccess); - present_cmd_pool = present_cmd_pool_return.value; - - for (auto &submission_resource : submission_resources) { - auto alloc_cmd_return = device.allocateCommandBuffers(vk::CommandBufferAllocateInfo() - .setCommandPool(present_cmd_pool) - .setLevel(vk::CommandBufferLevel::ePrimary) - .setCommandBufferCount(1)); - VERIFY(alloc_cmd_return.result == vk::Result::eSuccess); - submission_resource.graphics_to_present_cmd = alloc_cmd_return.value[0]; - } - } - - prepare_descriptor_pool(); - prepare_descriptor_set(); - - prepare_framebuffers(); - - prepare_submission_sync_objects(); - - /* - * Prepare functions above may generate pipeline commands - * that need to be flushed before beginning the render loop. - */ - flush_init_cmd(); - if (staging_texture.buffer) { - destroy_texture(staging_texture); - } - - initialized = true; - - prepare_swapchain(); -} - -// Creates the swapchain, swapchain image views, depth buffer, framebuffers, and sempahores. -// This function returns early if it fails to create a swapchain, setting swapchain_ready to false. -void Demo::prepare_swapchain() { - vk::SwapchainKHR oldSwapchain = swapchain; - -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - if (wsi_platform == WsiPlatform::wayland && !xdg_surface_has_been_configured) { - return; - } -#endif - - // Check the surface capabilities and formats - auto surface_capabilities_return = gpu.getSurfaceCapabilitiesKHR(surface); - VERIFY(surface_capabilities_return.result == vk::Result::eSuccess); - auto surfCapabilities = surface_capabilities_return.value; - - auto present_modes_return = gpu.getSurfacePresentModesKHR(surface); - VERIFY(present_modes_return.result == vk::Result::eSuccess); - auto present_modes = present_modes_return.value; - - vk::Extent2D swapchainExtent; - // width and height are either both -1, or both not -1. - if (surfCapabilities.currentExtent.width == static_cast<uint32_t>(-1)) { - // If the surface size is undefined, the size is set to - // the size of the images requested. - swapchainExtent.width = width; - swapchainExtent.height = height; - } else { - // If the surface size is defined, the swap chain size must match - swapchainExtent = surfCapabilities.currentExtent; - width = surfCapabilities.currentExtent.width; - height = surfCapabilities.currentExtent.height; - } - - if (width == 0 || height == 0) { - is_minimized = true; - return; - } else { - is_minimized = false; - } - // The FIFO present mode is guaranteed by the spec to be supported - // and to have no tearing. It's a great default present mode to use. - vk::PresentModeKHR swapchainPresentMode = vk::PresentModeKHR::eFifo; - - // There are times when you may wish to use another present mode. The - // following code shows how to select them, and the comments provide some - // reasons you may wish to use them. - // - // It should be noted that Vulkan 1.0 doesn't provide a method for - // synchronizing rendering with the presentation engine's display. There - // is a method provided for throttling rendering with the display, but - // there are some presentation engines for which this method will not work. - // If an application doesn't throttle its rendering, and if it renders much - // faster than the refresh rate of the display, this can waste power on - // mobile devices. That is because power is being spent rendering images - // that may never be seen. - - // VK_PRESENT_MODE_IMMEDIATE_KHR is for applications that don't care - // about - // tearing, or have some way of synchronizing their rendering with the - // display. - // VK_PRESENT_MODE_MAILBOX_KHR may be useful for applications that - // generally render a new presentable image every refresh cycle, but are - // occasionally early. In this case, the application wants the new - // image - // to be displayed instead of the previously-queued-for-presentation - // image - // that has not yet been displayed. - // VK_PRESENT_MODE_FIFO_RELAXED_KHR is for applications that generally - // render a new presentable image every refresh cycle, but are - // occasionally - // late. In this case (perhaps because of stuttering/latency concerns), - // the application wants the late image to be immediately displayed, - // even - // though that may mean some tearing. - - if (presentMode != swapchainPresentMode) { - for (const auto &mode : present_modes) { - if (mode == presentMode) { - swapchainPresentMode = mode; - break; - } - } - } - - if (swapchainPresentMode != presentMode) { - ERR_EXIT("Present mode specified is not supported\n", "Present mode unsupported"); - } - - // Determine the number of VkImages to use in the swap chain. - // Application desires to acquire 3 images at a time for triple - // buffering - uint32_t desiredNumOfSwapchainImages = 3; - if (desiredNumOfSwapchainImages < surfCapabilities.minImageCount) { - desiredNumOfSwapchainImages = surfCapabilities.minImageCount; - } - - // If maxImageCount is 0, we can ask for as many images as we want, - // otherwise - // we're limited to maxImageCount - if ((surfCapabilities.maxImageCount > 0) && (desiredNumOfSwapchainImages > surfCapabilities.maxImageCount)) { - // Application must settle for fewer images than desired: - desiredNumOfSwapchainImages = surfCapabilities.maxImageCount; - } - - vk::SurfaceTransformFlagBitsKHR preTransform; - if (surfCapabilities.supportedTransforms & vk::SurfaceTransformFlagBitsKHR::eIdentity) { - preTransform = vk::SurfaceTransformFlagBitsKHR::eIdentity; - } else { - preTransform = surfCapabilities.currentTransform; - } - - // Find a supported composite alpha mode - one of these is guaranteed to be set - vk::CompositeAlphaFlagBitsKHR compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque; - std::array<vk::CompositeAlphaFlagBitsKHR, 4> compositeAlphaFlags = { - vk::CompositeAlphaFlagBitsKHR::eOpaque, - vk::CompositeAlphaFlagBitsKHR::ePreMultiplied, - vk::CompositeAlphaFlagBitsKHR::ePostMultiplied, - vk::CompositeAlphaFlagBitsKHR::eInherit, - }; - for (const auto &compositeAlphaFlag : compositeAlphaFlags) { - if (surfCapabilities.supportedCompositeAlpha & compositeAlphaFlag) { - compositeAlpha = compositeAlphaFlag; - break; - } - } - - const vk::SwapchainCreateFlagsKHR swapchain_create_flags = - protected_output ? vk::SwapchainCreateFlagBitsKHR::eProtected : vk::SwapchainCreateFlagsKHR{}; - auto swapchain_return = device.createSwapchainKHR(vk::SwapchainCreateInfoKHR() - .setSurface(surface) - .setMinImageCount(desiredNumOfSwapchainImages) - .setImageFormat(format) - .setImageColorSpace(color_space) - .setImageExtent({swapchainExtent.width, swapchainExtent.height}) - .setImageArrayLayers(1) - .setImageUsage(vk::ImageUsageFlagBits::eColorAttachment) - .setImageSharingMode(vk::SharingMode::eExclusive) - .setPreTransform(preTransform) - .setCompositeAlpha(compositeAlpha) - .setPresentMode(swapchainPresentMode) - .setClipped(true) - .setOldSwapchain(oldSwapchain) - .setFlags(swapchain_create_flags)); - VERIFY(swapchain_return.result == vk::Result::eSuccess); - swapchain = swapchain_return.value; - - // If we just re-created an existing swapchain, we should destroy the - // old - // swapchain at this point. - // Note: destroying the swapchain also cleans up all its associated - // presentable images once the platform is done with them. - if (oldSwapchain) { - device.destroySwapchainKHR(oldSwapchain); - } - - auto swapchain_images_return = device.getSwapchainImagesKHR(swapchain); - VERIFY(swapchain_images_return.result == vk::Result::eSuccess); - swapchain_resources.resize(swapchain_images_return.value.size()); - - for (uint32_t i = 0; i < swapchain_resources.size(); ++i) { - auto color_image_view = vk::ImageViewCreateInfo() - .setViewType(vk::ImageViewType::e2D) - .setFormat(format) - .setSubresourceRange(vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1)); - - swapchain_resources[i].image = swapchain_images_return.value[i]; - - color_image_view.image = swapchain_resources[i].image; - - auto image_view_return = device.createImageView(color_image_view); - VERIFY(image_view_return.result == vk::Result::eSuccess); - swapchain_resources[i].view = image_view_return.value; - } - - // Create semaphores to synchronize acquiring presentable buffers before - // rendering and waiting for drawing to be complete before presenting - auto const semaphoreCreateInfo = vk::SemaphoreCreateInfo(); - - for (auto &swapchain_resource : swapchain_resources) { - auto result = device.createSemaphore(&semaphoreCreateInfo, nullptr, &swapchain_resource.draw_complete_semaphore); - VERIFY(result == vk::Result::eSuccess); - - if (separate_present_queue) { - result = device.createSemaphore(&semaphoreCreateInfo, nullptr, &swapchain_resource.image_ownership_semaphore); - VERIFY(result == vk::Result::eSuccess); - } - } - - prepare_depth(); - prepare_framebuffers(); - swapchain_ready = true; - first_swapchain_frame = true; -} - -void Demo::prepare_cube_data_buffers() { - mat4x4 VP; - mat4x4_mul(VP, projection_matrix, view_matrix); - - mat4x4 MVP; - mat4x4_mul(MVP, VP, model_matrix); - - vktexcube_vs_uniform data; - memcpy(data.mvp, MVP, sizeof(MVP)); - // dumpMatrix("MVP", MVP) - - for (int32_t i = 0; i < 12 * 3; i++) { - data.position[i][0] = g_vertex_buffer_data[i * 3]; - data.position[i][1] = g_vertex_buffer_data[i * 3 + 1]; - data.position[i][2] = g_vertex_buffer_data[i * 3 + 2]; - data.position[i][3] = 1.0f; - data.attr[i][0] = g_uv_buffer_data[2 * i]; - data.attr[i][1] = g_uv_buffer_data[2 * i + 1]; - data.attr[i][2] = 0; - data.attr[i][3] = 0; - } - - auto const buf_info = vk::BufferCreateInfo().setSize(sizeof(data)).setUsage(vk::BufferUsageFlagBits::eUniformBuffer); - - for (auto &submission_resource : submission_resources) { - auto result = device.createBuffer(&buf_info, nullptr, &submission_resource.uniform_buffer); - VERIFY(result == vk::Result::eSuccess); - - vk::MemoryRequirements mem_reqs; - device.getBufferMemoryRequirements(submission_resource.uniform_buffer, &mem_reqs); - - auto mem_alloc = vk::MemoryAllocateInfo().setAllocationSize(mem_reqs.size).setMemoryTypeIndex(0); - - bool const pass = memory_type_from_properties( - mem_reqs.memoryTypeBits, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, - mem_alloc.memoryTypeIndex); - VERIFY(pass); - - result = device.allocateMemory(&mem_alloc, nullptr, &submission_resource.uniform_memory); - VERIFY(result == vk::Result::eSuccess); - - result = device.mapMemory(submission_resource.uniform_memory, 0, VK_WHOLE_SIZE, vk::MemoryMapFlags(), - &submission_resource.uniform_memory_ptr); - VERIFY(result == vk::Result::eSuccess); - - memcpy(submission_resource.uniform_memory_ptr, &data, sizeof data); - - result = device.bindBufferMemory(submission_resource.uniform_buffer, submission_resource.uniform_memory, 0); - VERIFY(result == vk::Result::eSuccess); - } -} - -void Demo::prepare_depth() { - depth.format = vk::Format::eD16Unorm; - - auto const image = vk::ImageCreateInfo() - .setImageType(vk::ImageType::e2D) - .setFormat(depth.format) - .setExtent({width, height, 1}) - .setMipLevels(1) - .setArrayLayers(1) - .setSamples(vk::SampleCountFlagBits::e1) - .setTiling(vk::ImageTiling::eOptimal) - .setUsage(vk::ImageUsageFlagBits::eDepthStencilAttachment) - .setSharingMode(vk::SharingMode::eExclusive) - .setInitialLayout(vk::ImageLayout::eUndefined); - - auto result = device.createImage(&image, nullptr, &depth.image); - VERIFY(result == vk::Result::eSuccess); - - vk::MemoryRequirements mem_reqs; - device.getImageMemoryRequirements(depth.image, &mem_reqs); - - depth.mem_alloc.setAllocationSize(mem_reqs.size); - depth.mem_alloc.setMemoryTypeIndex(0); - - auto const pass = memory_type_from_properties(mem_reqs.memoryTypeBits, vk::MemoryPropertyFlagBits::eDeviceLocal, - depth.mem_alloc.memoryTypeIndex); - VERIFY(pass); - - result = device.allocateMemory(&depth.mem_alloc, nullptr, &depth.mem); - VERIFY(result == vk::Result::eSuccess); - - result = device.bindImageMemory(depth.image, depth.mem, 0); - VERIFY(result == vk::Result::eSuccess); - - auto view = vk::ImageViewCreateInfo() - .setImage(depth.image) - .setViewType(vk::ImageViewType::e2D) - .setFormat(depth.format) - .setSubresourceRange(vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eDepth, 0, 1, 0, 1)); - if (force_errors) { - // Intentionally force a bad pNext value to generate a validation layer error - view.pNext = ℑ - } - result = device.createImageView(&view, nullptr, &depth.view); - VERIFY(result == vk::Result::eSuccess); -} - -void Demo::prepare_descriptor_layout() { - std::array<vk::DescriptorSetLayoutBinding, 2> const layout_bindings = { - vk::DescriptorSetLayoutBinding() - .setBinding(0) - .setDescriptorType(vk::DescriptorType::eUniformBuffer) - .setDescriptorCount(1) - .setStageFlags(vk::ShaderStageFlagBits::eVertex) - .setPImmutableSamplers(nullptr), - vk::DescriptorSetLayoutBinding() - .setBinding(1) - .setDescriptorType(vk::DescriptorType::eCombinedImageSampler) - .setDescriptorCount(texture_count) - .setStageFlags(vk::ShaderStageFlagBits::eFragment) - .setPImmutableSamplers(nullptr)}; - - auto const descriptor_layout = vk::DescriptorSetLayoutCreateInfo().setBindings(layout_bindings); - - auto result = device.createDescriptorSetLayout(&descriptor_layout, nullptr, &desc_layout); - VERIFY(result == vk::Result::eSuccess); - - auto const pPipelineLayoutCreateInfo = vk::PipelineLayoutCreateInfo().setSetLayouts(desc_layout); - - result = device.createPipelineLayout(&pPipelineLayoutCreateInfo, nullptr, &pipeline_layout); - VERIFY(result == vk::Result::eSuccess); -} - -void Demo::prepare_descriptor_pool() { - std::array<vk::DescriptorPoolSize, 2> const poolSizes = { - vk::DescriptorPoolSize() - .setType(vk::DescriptorType::eUniformBuffer) - .setDescriptorCount(static_cast<uint32_t>(submission_resources.size())), - vk::DescriptorPoolSize() - .setType(vk::DescriptorType::eCombinedImageSampler) - .setDescriptorCount(static_cast<uint32_t>(submission_resources.size()) * texture_count)}; - - auto const descriptor_pool = - vk::DescriptorPoolCreateInfo().setMaxSets(static_cast<uint32_t>(submission_resources.size())).setPoolSizes(poolSizes); - - auto result = device.createDescriptorPool(&descriptor_pool, nullptr, &desc_pool); - VERIFY(result == vk::Result::eSuccess); -} - -void Demo::prepare_descriptor_set() { - auto const alloc_info = vk::DescriptorSetAllocateInfo().setDescriptorPool(desc_pool).setSetLayouts(desc_layout); - - auto buffer_info = vk::DescriptorBufferInfo().setOffset(0).setRange(sizeof(vktexcube_vs_uniform)); - - std::array<vk::DescriptorImageInfo, texture_count> tex_descs; - for (uint32_t i = 0; i < texture_count; i++) { - tex_descs[i].setSampler(textures[i].sampler); - tex_descs[i].setImageView(textures[i].view); - tex_descs[i].setImageLayout(vk::ImageLayout::eShaderReadOnlyOptimal); - } - - std::array<vk::WriteDescriptorSet, 2> writes; - writes[0].setDescriptorCount(1).setDescriptorType(vk::DescriptorType::eUniformBuffer).setPBufferInfo(&buffer_info); - writes[1] - .setDstBinding(1) - .setDescriptorCount(texture_count) - .setDescriptorType(vk::DescriptorType::eCombinedImageSampler) - .setImageInfo(tex_descs); - - for (auto &submission_resource : submission_resources) { - auto result = device.allocateDescriptorSets(&alloc_info, &submission_resource.descriptor_set); - VERIFY(result == vk::Result::eSuccess); - - buffer_info.setBuffer(submission_resource.uniform_buffer); - writes[0].setDstSet(submission_resource.descriptor_set); - writes[1].setDstSet(submission_resource.descriptor_set); - device.updateDescriptorSets(writes, {}); - } -} - -void Demo::prepare_framebuffers() { - std::array<vk::ImageView, 2> attachments; - attachments[1] = depth.view; - - for (auto &swapchain_image_resource : swapchain_resources) { - attachments[0] = swapchain_image_resource.view; - auto const framebuffer_return = device.createFramebuffer(vk::FramebufferCreateInfo() - .setRenderPass(render_pass) - .setAttachments(attachments) - .setWidth(width) - .setHeight(height) - .setLayers(1)); - VERIFY(framebuffer_return.result == vk::Result::eSuccess); - swapchain_image_resource.framebuffer = framebuffer_return.value; - } -} - -void Demo::prepare_submission_sync_objects() { - // Create semaphores to synchronize acquiring presentable buffers before - // rendering and waiting for drawing to be complete before presenting - auto const semaphoreCreateInfo = vk::SemaphoreCreateInfo(); - - // Create fences that we can use to throttle if we get too far - // ahead of the image presents - auto const fence_ci = vk::FenceCreateInfo().setFlags(vk::FenceCreateFlagBits::eSignaled); - for (auto &submission_resource : submission_resources) { - vk::Result result = device.createFence(&fence_ci, nullptr, &submission_resource.fence); - VERIFY(result == vk::Result::eSuccess); - - result = device.createSemaphore(&semaphoreCreateInfo, nullptr, &submission_resource.image_acquired_semaphore); - VERIFY(result == vk::Result::eSuccess); - } -} - -vk::ShaderModule Demo::prepare_fs() { - const uint32_t fragShaderCode[] = { -#ifdef CUBE_FRAG_INC -#include CUBE_FRAG_INC -#else -#include "cube.frag.inc" -#endif - }; - - frag_shader_module = prepare_shader_module(fragShaderCode, sizeof(fragShaderCode)); - - return frag_shader_module; -} - -void Demo::prepare_pipeline() { - vk::PipelineCacheCreateInfo const pipelineCacheInfo; - auto result = device.createPipelineCache(&pipelineCacheInfo, nullptr, &pipelineCache); - VERIFY(result == vk::Result::eSuccess); - - std::array<vk::PipelineShaderStageCreateInfo, 2> const shaderStageInfo = { - vk::PipelineShaderStageCreateInfo().setStage(vk::ShaderStageFlagBits::eVertex).setModule(prepare_vs()).setPName("main"), - vk::PipelineShaderStageCreateInfo().setStage(vk::ShaderStageFlagBits::eFragment).setModule(prepare_fs()).setPName("main")}; - - vk::PipelineVertexInputStateCreateInfo const vertexInputInfo; - - auto const inputAssemblyInfo = vk::PipelineInputAssemblyStateCreateInfo().setTopology(vk::PrimitiveTopology::eTriangleList); - - // TODO: Where are pViewports and pScissors set? - auto const viewportInfo = vk::PipelineViewportStateCreateInfo().setViewportCount(1).setScissorCount(1); - - auto const rasterizationInfo = vk::PipelineRasterizationStateCreateInfo() - .setDepthClampEnable(VK_FALSE) - .setRasterizerDiscardEnable(VK_FALSE) - .setPolygonMode(vk::PolygonMode::eFill) - .setCullMode(vk::CullModeFlagBits::eBack) - .setFrontFace(vk::FrontFace::eCounterClockwise) - .setDepthBiasEnable(VK_FALSE) - .setLineWidth(1.0f); - - auto const multisampleInfo = vk::PipelineMultisampleStateCreateInfo(); - - auto const stencilOp = - vk::StencilOpState().setFailOp(vk::StencilOp::eKeep).setPassOp(vk::StencilOp::eKeep).setCompareOp(vk::CompareOp::eAlways); - - auto const depthStencilInfo = vk::PipelineDepthStencilStateCreateInfo() - .setDepthTestEnable(VK_TRUE) - .setDepthWriteEnable(VK_TRUE) - .setDepthCompareOp(vk::CompareOp::eLessOrEqual) - .setDepthBoundsTestEnable(VK_FALSE) - .setStencilTestEnable(VK_FALSE) - .setFront(stencilOp) - .setBack(stencilOp); - - std::array<vk::PipelineColorBlendAttachmentState, 1> const colorBlendAttachments = { - vk::PipelineColorBlendAttachmentState().setColorWriteMask(vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | - vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA)}; - - auto const colorBlendInfo = vk::PipelineColorBlendStateCreateInfo().setAttachments(colorBlendAttachments); - - std::array<vk::DynamicState, 2> const dynamicStates = {vk::DynamicState::eViewport, vk::DynamicState::eScissor}; - - auto const dynamicStateInfo = vk::PipelineDynamicStateCreateInfo().setDynamicStates(dynamicStates); - - auto pipline_return = device.createGraphicsPipelines(pipelineCache, vk::GraphicsPipelineCreateInfo() - .setStages(shaderStageInfo) - .setPVertexInputState(&vertexInputInfo) - .setPInputAssemblyState(&inputAssemblyInfo) - .setPViewportState(&viewportInfo) - .setPRasterizationState(&rasterizationInfo) - .setPMultisampleState(&multisampleInfo) - .setPDepthStencilState(&depthStencilInfo) - .setPColorBlendState(&colorBlendInfo) - .setPDynamicState(&dynamicStateInfo) - .setLayout(pipeline_layout) - .setRenderPass(render_pass)); - VERIFY(pipline_return.result == vk::Result::eSuccess); - pipeline = pipline_return.value.at(0); - - device.destroyShaderModule(frag_shader_module); - device.destroyShaderModule(vert_shader_module); -} - -void Demo::prepare_render_pass() { - // The initial layout for the color and depth attachments will be LAYOUT_UNDEFINED - // because at the start of the renderpass, we don't care about their contents. - // At the start of the subpass, the color attachment's layout will be transitioned - // to LAYOUT_COLOR_ATTACHMENT_OPTIMAL and the depth stencil attachment's layout - // will be transitioned to LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL. At the end of - // the renderpass, the color attachment's layout will be transitioned to - // LAYOUT_PRESENT_SRC_KHR to be ready to present. This is all done as part of - // the renderpass, no barriers are necessary. - std::array<vk::AttachmentDescription, 2> const attachments = { - vk::AttachmentDescription() - .setFormat(format) - .setSamples(vk::SampleCountFlagBits::e1) - .setLoadOp(vk::AttachmentLoadOp::eClear) - .setStoreOp(vk::AttachmentStoreOp::eStore) - .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare) - .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare) - .setInitialLayout(vk::ImageLayout::eUndefined) - .setFinalLayout(vk::ImageLayout::ePresentSrcKHR), - vk::AttachmentDescription() - .setFormat(depth.format) - .setSamples(vk::SampleCountFlagBits::e1) - .setLoadOp(vk::AttachmentLoadOp::eClear) - .setStoreOp(vk::AttachmentStoreOp::eDontCare) - .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare) - .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare) - .setInitialLayout(vk::ImageLayout::eUndefined) - .setFinalLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal)}; - - auto const color_reference = vk::AttachmentReference().setAttachment(0).setLayout(vk::ImageLayout::eColorAttachmentOptimal); - - auto const depth_reference = - vk::AttachmentReference().setAttachment(1).setLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal); - - auto const subpass = vk::SubpassDescription() - .setPipelineBindPoint(vk::PipelineBindPoint::eGraphics) - .setColorAttachments(color_reference) - .setPDepthStencilAttachment(&depth_reference); - - vk::PipelineStageFlags stages = vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests; - std::array<vk::SubpassDependency, 2> const dependencies = { - vk::SubpassDependency() // Depth buffer is shared between swapchain images - .setSrcSubpass(VK_SUBPASS_EXTERNAL) - .setDstSubpass(0) - .setSrcStageMask(stages) - .setDstStageMask(stages) - .setSrcAccessMask(vk::AccessFlagBits::eDepthStencilAttachmentWrite) - .setDstAccessMask(vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite) - .setDependencyFlags(vk::DependencyFlags()), - vk::SubpassDependency() // Image layout transition - .setSrcSubpass(VK_SUBPASS_EXTERNAL) - .setDstSubpass(0) - .setSrcStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput) - .setDstStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput) - .setSrcAccessMask(vk::AccessFlagBits()) - .setDstAccessMask(vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead) - .setDependencyFlags(vk::DependencyFlags()), - }; - - const auto render_pass_result = device.createRenderPass( - vk::RenderPassCreateInfo().setAttachments(attachments).setSubpasses(subpass).setDependencies(dependencies)); - VERIFY(render_pass_result.result == vk::Result::eSuccess); - render_pass = render_pass_result.value; -} - -vk::ShaderModule Demo::prepare_shader_module(const uint32_t *code, size_t size) { - const auto shader_module_return = device.createShaderModule(vk::ShaderModuleCreateInfo().setCodeSize(size).setPCode(code)); - VERIFY(shader_module_return.result == vk::Result::eSuccess); - - return shader_module_return.value; -} - -void Demo::prepare_texture_buffer(const char *filename, texture_object &tex_obj) { - vk::SubresourceLayout tex_layout; - - if (!loadTexture(filename, nullptr, tex_layout, tex_obj.tex_width, tex_obj.tex_height)) { - ERR_EXIT("Failed to load textures", "Load Texture Failure"); - } - - auto const buffer_create_info = vk::BufferCreateInfo() - .setSize(tex_obj.tex_width * tex_obj.tex_height * 4) - .setUsage(vk::BufferUsageFlagBits::eTransferSrc) - .setSharingMode(vk::SharingMode::eExclusive); - - auto result = device.createBuffer(&buffer_create_info, nullptr, &tex_obj.buffer); - VERIFY(result == vk::Result::eSuccess); - - vk::MemoryRequirements mem_reqs; - device.getBufferMemoryRequirements(tex_obj.buffer, &mem_reqs); - - tex_obj.mem_alloc.setAllocationSize(mem_reqs.size); - tex_obj.mem_alloc.setMemoryTypeIndex(0); - - vk::MemoryPropertyFlags requirements = vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent; - auto pass = memory_type_from_properties(mem_reqs.memoryTypeBits, requirements, tex_obj.mem_alloc.memoryTypeIndex); - VERIFY(pass == true); - - result = device.allocateMemory(&tex_obj.mem_alloc, nullptr, &(tex_obj.mem)); - VERIFY(result == vk::Result::eSuccess); - - result = device.bindBufferMemory(tex_obj.buffer, tex_obj.mem, 0); - VERIFY(result == vk::Result::eSuccess); - - vk::SubresourceLayout layout; - layout.rowPitch = tex_obj.tex_width * 4; - auto data = device.mapMemory(tex_obj.mem, 0, tex_obj.mem_alloc.allocationSize); - VERIFY(data.result == vk::Result::eSuccess); - - if (!loadTexture(filename, (uint8_t *)data.value, layout, tex_obj.tex_width, tex_obj.tex_height)) { - fprintf(stderr, "Error loading texture: %s\n", filename); - } - - device.unmapMemory(tex_obj.mem); -} - -void Demo::prepare_texture_image(const char *filename, texture_object &tex_obj, vk::ImageTiling tiling, vk::ImageUsageFlags usage, - vk::MemoryPropertyFlags required_props) { - vk::SubresourceLayout tex_layout; - if (!loadTexture(filename, nullptr, tex_layout, tex_obj.tex_width, tex_obj.tex_height)) { - ERR_EXIT("Failed to load textures", "Load Texture Failure"); - } - - auto const image_create_info = vk::ImageCreateInfo() - .setImageType(vk::ImageType::e2D) - .setFormat(vk::Format::eR8G8B8A8Srgb) - .setExtent({tex_obj.tex_width, tex_obj.tex_height, 1}) - .setMipLevels(1) - .setArrayLayers(1) - .setSamples(vk::SampleCountFlagBits::e1) - .setTiling(tiling) - .setUsage(usage) - .setSharingMode(vk::SharingMode::eExclusive) - .setInitialLayout(vk::ImageLayout::ePreinitialized); - - auto result = device.createImage(&image_create_info, nullptr, &tex_obj.image); - VERIFY(result == vk::Result::eSuccess); - - vk::MemoryRequirements mem_reqs; - device.getImageMemoryRequirements(tex_obj.image, &mem_reqs); - - tex_obj.mem_alloc.setAllocationSize(mem_reqs.size); - tex_obj.mem_alloc.setMemoryTypeIndex(0); - - auto pass = memory_type_from_properties(mem_reqs.memoryTypeBits, required_props, tex_obj.mem_alloc.memoryTypeIndex); - VERIFY(pass == true); - - result = device.allocateMemory(&tex_obj.mem_alloc, nullptr, &tex_obj.mem); - VERIFY(result == vk::Result::eSuccess); - - result = device.bindImageMemory(tex_obj.image, tex_obj.mem, 0); - VERIFY(result == vk::Result::eSuccess); - - if (required_props & vk::MemoryPropertyFlagBits::eHostVisible) { - auto const subres = vk::ImageSubresource().setAspectMask(vk::ImageAspectFlagBits::eColor).setMipLevel(0).setArrayLayer(0); - vk::SubresourceLayout layout; - device.getImageSubresourceLayout(tex_obj.image, &subres, &layout); - - auto data = device.mapMemory(tex_obj.mem, 0, tex_obj.mem_alloc.allocationSize); - VERIFY(data.result == vk::Result::eSuccess); - - if (!loadTexture(filename, (uint8_t *)data.value, layout, tex_obj.tex_width, tex_obj.tex_height)) { - fprintf(stderr, "Error loading texture: %s\n", filename); - } - - device.unmapMemory(tex_obj.mem); - } - - tex_obj.imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal; -} - -void Demo::prepare_textures() { - vk::Format const tex_format = vk::Format::eR8G8B8A8Srgb; - vk::FormatProperties props; - gpu.getFormatProperties(tex_format, &props); - - for (uint32_t i = 0; i < texture_count; i++) { - if ((props.linearTilingFeatures & vk::FormatFeatureFlagBits::eSampledImage) && !use_staging_buffer) { - /* Device can texture using linear textures */ - prepare_texture_image(tex_files[i], textures[i], vk::ImageTiling::eLinear, vk::ImageUsageFlagBits::eSampled, - vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent); - // Nothing in the pipeline needs to be complete to start, and don't allow fragment - // shader to run until layout transition completes - set_image_layout(textures[i].image, vk::ImageAspectFlagBits::eColor, vk::ImageLayout::ePreinitialized, - textures[i].imageLayout, vk::AccessFlagBits(), vk::PipelineStageFlagBits::eTopOfPipe, - vk::PipelineStageFlagBits::eFragmentShader); - staging_texture.image = vk::Image(); - } else if (props.optimalTilingFeatures & vk::FormatFeatureFlagBits::eSampledImage) { - /* Must use staging buffer to copy linear texture to optimized */ - - prepare_texture_buffer(tex_files[i], staging_texture); - - prepare_texture_image(tex_files[i], textures[i], vk::ImageTiling::eOptimal, - vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled, - vk::MemoryPropertyFlagBits::eDeviceLocal); - - set_image_layout(textures[i].image, vk::ImageAspectFlagBits::eColor, vk::ImageLayout::ePreinitialized, - vk::ImageLayout::eTransferDstOptimal, vk::AccessFlagBits(), vk::PipelineStageFlagBits::eTopOfPipe, - vk::PipelineStageFlagBits::eTransfer); - - auto const subresource = vk::ImageSubresourceLayers() - .setAspectMask(vk::ImageAspectFlagBits::eColor) - .setMipLevel(0) - .setBaseArrayLayer(0) - .setLayerCount(1); - - auto const copy_region = vk::BufferImageCopy() - .setBufferOffset(0) - .setBufferRowLength(staging_texture.tex_width) - .setBufferImageHeight(staging_texture.tex_height) - .setImageSubresource(subresource) - .setImageOffset({0, 0, 0}) - .setImageExtent({staging_texture.tex_width, staging_texture.tex_height, 1}); - - cmd.copyBufferToImage(staging_texture.buffer, textures[i].image, vk::ImageLayout::eTransferDstOptimal, 1, ©_region); - - set_image_layout(textures[i].image, vk::ImageAspectFlagBits::eColor, vk::ImageLayout::eTransferDstOptimal, - textures[i].imageLayout, vk::AccessFlagBits::eTransferWrite, vk::PipelineStageFlagBits::eTransfer, - vk::PipelineStageFlagBits::eFragmentShader); - } else { - assert(false && "No support for R8G8B8A8_SRGB as texture image format"); - } - - auto const samplerInfo = vk::SamplerCreateInfo() - .setMagFilter(vk::Filter::eNearest) - .setMinFilter(vk::Filter::eNearest) - .setMipmapMode(vk::SamplerMipmapMode::eNearest) - .setAddressModeU(vk::SamplerAddressMode::eClampToEdge) - .setAddressModeV(vk::SamplerAddressMode::eClampToEdge) - .setAddressModeW(vk::SamplerAddressMode::eClampToEdge) - .setMipLodBias(0.0f) - .setAnisotropyEnable(VK_FALSE) - .setMaxAnisotropy(1) - .setCompareEnable(VK_FALSE) - .setCompareOp(vk::CompareOp::eNever) - .setMinLod(0.0f) - .setMaxLod(0.0f) - .setBorderColor(vk::BorderColor::eFloatOpaqueWhite) - .setUnnormalizedCoordinates(VK_FALSE); - - auto result = device.createSampler(&samplerInfo, nullptr, &textures[i].sampler); - VERIFY(result == vk::Result::eSuccess); - - auto const viewInfo = vk::ImageViewCreateInfo() - .setImage(textures[i].image) - .setViewType(vk::ImageViewType::e2D) - .setFormat(tex_format) - .setSubresourceRange(vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1)); - - result = device.createImageView(&viewInfo, nullptr, &textures[i].view); - VERIFY(result == vk::Result::eSuccess); - } -} - -vk::ShaderModule Demo::prepare_vs() { - const uint32_t vertShaderCode[] = { -#ifdef CUBE_VERT_INC -#include CUBE_VERT_INC -#else -#include "cube.vert.inc" -#endif - }; - - vert_shader_module = prepare_shader_module(vertShaderCode, sizeof(vertShaderCode)); - - return vert_shader_module; -} - -void Demo::resize() { - // Don't react to resize until after first initialization. - if (!initialized) { - return; - } - - // Don't do anything if the surface has zero size, as vulkan disallows creating swapchains with zero area - // We use is_minimized to track this because zero size window usually occurs from minimizing - if (width == 0 || height == 0) { - is_minimized = true; - return; - } else { - is_minimized = false; - } - - // In order to properly resize the window, we must re-create the - // swapchain - // - // First, destroy the old swapchain and its associated resources, setting swapchain_ready to false to prevent draw from - // running - if (swapchain_ready) { - swapchain_ready = false; - auto result = device.waitIdle(); - VERIFY(result == vk::Result::eSuccess); - - device.destroyImageView(depth.view); - device.destroyImage(depth.image); - device.freeMemory(depth.mem); - depth = {}; - - for (auto &swapchain_resource : swapchain_resources) { - device.destroyFramebuffer(swapchain_resource.framebuffer); - device.destroyImageView(swapchain_resource.view); - device.destroySemaphore(swapchain_resource.draw_complete_semaphore); - if (separate_present_queue) { - device.destroySemaphore(swapchain_resource.image_ownership_semaphore); - } - } - swapchain_resources.clear(); - } - // Second, recreate the swapchain, depth buffer, and framebuffers. - prepare_swapchain(); -} - -void Demo::set_image_layout(vk::Image image, vk::ImageAspectFlags aspectMask, vk::ImageLayout oldLayout, vk::ImageLayout newLayout, - vk::AccessFlags srcAccessMask, vk::PipelineStageFlags src_stages, vk::PipelineStageFlags dest_stages) { - assert(cmd); - - auto DstAccessMask = [](vk::ImageLayout const &layout) { - vk::AccessFlags flags; - - switch (layout) { - case vk::ImageLayout::eTransferDstOptimal: - // Make sure anything that was copying from this image has - // completed - flags = vk::AccessFlagBits::eTransferWrite; - break; - case vk::ImageLayout::eColorAttachmentOptimal: - flags = vk::AccessFlagBits::eColorAttachmentWrite; - break; - case vk::ImageLayout::eDepthStencilAttachmentOptimal: - flags = vk::AccessFlagBits::eDepthStencilAttachmentWrite; - break; - case vk::ImageLayout::eShaderReadOnlyOptimal: - // Make sure any Copy or CPU writes to image are flushed - flags = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eInputAttachmentRead; - break; - case vk::ImageLayout::eTransferSrcOptimal: - flags = vk::AccessFlagBits::eTransferRead; - break; - case vk::ImageLayout::ePresentSrcKHR: - flags = vk::AccessFlagBits::eMemoryRead; - break; - default: - break; - } - - return flags; - }; - - cmd.pipelineBarrier(src_stages, dest_stages, vk::DependencyFlagBits(), {}, {}, - vk::ImageMemoryBarrier() - .setSrcAccessMask(srcAccessMask) - .setDstAccessMask(DstAccessMask(newLayout)) - .setOldLayout(oldLayout) - .setNewLayout(newLayout) - .setSrcQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED) - .setDstQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED) - .setImage(image) - .setSubresourceRange(vk::ImageSubresourceRange(aspectMask, 0, 1, 0, 1))); -} - -void Demo::update_data_buffer(void *uniform_memory_ptr) { - mat4x4 VP; - mat4x4_mul(VP, projection_matrix, view_matrix); - - // Rotate around the Y axis - mat4x4 Model; - mat4x4_dup(Model, model_matrix); - mat4x4_rotate_Y(model_matrix, Model, static_cast<float>(degreesToRadians(spin_angle))); - mat4x4_orthonormalize(model_matrix, model_matrix); - - mat4x4 MVP; - mat4x4_mul(MVP, VP, model_matrix); - - memcpy(uniform_memory_ptr, (const void *)&MVP[0][0], sizeof(MVP)); -} - -/* Convert ppm image data from header file into RGBA texture image */ -#ifdef TEXTURE_PPM_H -#include TEXTURE_PPM_H -#else -#include "lunarg.ppm.h" -#endif -bool Demo::loadTexture(const char *filename, uint8_t *rgba_data, vk::SubresourceLayout &layout, uint32_t &width, uint32_t &height) { - (void)filename; - char *cPtr; - cPtr = (char *)lunarg_ppm; - if ((unsigned char *)cPtr >= (lunarg_ppm + lunarg_ppm_len) || strncmp(cPtr, "P6\n", 3)) { - return false; - } - while (strncmp(cPtr++, "\n", 1)); - sscanf(cPtr, "%u %u", &width, &height); - if (rgba_data == nullptr) { - return true; - } - while (strncmp(cPtr++, "\n", 1)); - if ((unsigned char *)cPtr >= (lunarg_ppm + lunarg_ppm_len) || strncmp(cPtr, "255\n", 4)) { - return false; - } - while (strncmp(cPtr++, "\n", 1)); - for (uint32_t y = 0; y < height; y++) { - uint8_t *rowPtr = rgba_data; - for (uint32_t x = 0; x < width; x++) { - memcpy(rowPtr, cPtr, 3); - rowPtr[3] = 255; /* Alpha of 1 */ - rowPtr += 4; - cPtr += 3; - } - rgba_data += layout.rowPitch; - } - return true; -} - -bool Demo::memory_type_from_properties(uint32_t typeBits, vk::MemoryPropertyFlags requirements_mask, uint32_t &typeIndex) { - // Search memtypes to find first index with those properties - for (uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; i++) { - if ((typeBits & 1) == 1) { - // Type is available, does it match user properties? - if ((memory_properties.memoryTypes[i].propertyFlags & requirements_mask) == requirements_mask) { - typeIndex = i; - return true; - } - } - typeBits >>= 1; - } - - // No memory types matched, return failure - return false; -} - -vk::SurfaceFormatKHR Demo::pick_surface_format(const std::vector<vk::SurfaceFormatKHR> &surface_formats) { - // Prefer non-SRGB formats... - for (const auto &surface_format : surface_formats) { - const vk::Format format = surface_format.format; - - if (format == vk::Format::eR8G8B8A8Unorm || format == vk::Format::eB8G8R8A8Unorm || - format == vk::Format::eA2B10G10R10UnormPack32 || format == vk::Format::eA2R10G10B10UnormPack32 || - format == vk::Format::eA1R5G5B5UnormPack16 || format == vk::Format::eR5G6B5UnormPack16 || - format == vk::Format::eR16G16B16A16Sfloat) { - return surface_format; - } - } - - printf("Can't find our preferred formats... Falling back to first exposed format. Rendering may be incorrect.\n"); - - assert(surface_formats.size() >= 1); - return surface_formats[0]; -} - -#if defined(VK_USE_PLATFORM_WIN32_KHR) -template <> -void Demo::run<WsiPlatform::win32>() { - if (!initialized || !swapchain_ready) { - return; - } - - draw(); - if (!is_minimized) { - curFrame++; - } - - if (frameCount != UINT32_MAX && curFrame == frameCount) { - PostQuitMessage(validation_error); - } -} - -template <> -void Demo::create_window<WsiPlatform::win32>() { - WNDCLASSEX win_class; - - // Initialize the window class structure: - win_class.cbSize = sizeof(WNDCLASSEX); - win_class.style = CS_HREDRAW | CS_VREDRAW; - win_class.lpfnWndProc = WndProc; - win_class.cbClsExtra = 0; - win_class.cbWndExtra = 0; - win_class.hInstance = connection; // hInstance - win_class.hIcon = LoadIcon(nullptr, IDI_APPLICATION); - win_class.hCursor = LoadCursor(nullptr, IDC_ARROW); - win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); - win_class.lpszMenuName = nullptr; - win_class.lpszClassName = name.c_str(); - win_class.hIconSm = LoadIcon(nullptr, IDI_WINLOGO); - - // Register window class: - if (!RegisterClassEx(&win_class)) { - // It didn't work, so try to give a useful error: - printf("Unexpected error trying to start the application!\n"); - fflush(stdout); - exit(1); - } - - // Create window with the registered class: - RECT wr = {0, 0, static_cast<LONG>(width), static_cast<LONG>(height)}; - AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); - window = CreateWindowEx(0, - name.c_str(), // class name - name.c_str(), // app name - WS_OVERLAPPEDWINDOW | // window style - WS_VISIBLE | WS_SYSMENU, - 100, 100, // x/y coords - wr.right - wr.left, // width - wr.bottom - wr.top, // height - nullptr, // handle to parent - nullptr, // handle to menu - connection, // hInstance - nullptr); // no extra parameters - - if (!window) { - // It didn't work, so try to give a useful error: - printf("Cannot create a window in which to draw!\n"); - fflush(stdout); - exit(1); - } - - // Window client area size must be at least 1 pixel high, to prevent - // crash. - minsize.x = GetSystemMetrics(SM_CXMINTRACK); - minsize.y = GetSystemMetrics(SM_CYMINTRACK) + 1; -} -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - -template <> -void Demo::create_window<WsiPlatform::xlib>() { - const char *display_envar = getenv("DISPLAY"); - if (display_envar == nullptr || display_envar[0] == '\0') { - printf("Environment variable DISPLAY requires a valid value.\nExiting ...\n"); - fflush(stdout); - exit(1); - } - - XInitThreads(); - xlib_display = XOpenDisplay(nullptr); - long visualMask = VisualScreenMask; - int numberOfVisuals; - XVisualInfo vInfoTemplate = {}; - vInfoTemplate.screen = DefaultScreen(xlib_display); - XVisualInfo *visualInfo = XGetVisualInfo(xlib_display, visualMask, &vInfoTemplate, &numberOfVisuals); - - Colormap colormap = - XCreateColormap(xlib_display, RootWindow(xlib_display, vInfoTemplate.screen), visualInfo->visual, AllocNone); - - XSetWindowAttributes windowAttributes = {}; - windowAttributes.colormap = colormap; - windowAttributes.background_pixel = 0xFFFFFFFF; - windowAttributes.border_pixel = 0; - windowAttributes.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask | ExposureMask; - - xlib_window = - XCreateWindow(xlib_display, RootWindow(xlib_display, vInfoTemplate.screen), 0, 0, width, height, 0, visualInfo->depth, - InputOutput, visualInfo->visual, CWBackPixel | CWBorderPixel | CWEventMask | CWColormap, &windowAttributes); - - XSelectInput(xlib_display, xlib_window, ExposureMask | KeyPressMask); - XMapWindow(xlib_display, xlib_window); - XFlush(xlib_display); - xlib_wm_delete_window = XInternAtom(xlib_display, "WM_DELETE_WINDOW", False); - XSetWMProtocols(xlib_display, xlib_window, &xlib_wm_delete_window, 1); -} - -void Demo::handle_xlib_event(const XEvent *event) { - switch (event->type) { - case ClientMessage: - if ((Atom)event->xclient.data.l[0] == xlib_wm_delete_window) { - quit = true; - } - break; - case KeyPress: - switch (event->xkey.keycode) { - case 0x9: // Escape - quit = true; - break; - case 0x71: // left arrow key - spin_angle -= spin_increment; - break; - case 0x72: // right arrow key - spin_angle += spin_increment; - break; - case 0x41: // space bar - pause = !pause; - break; - } - break; - case ConfigureNotify: - if (((int32_t)width != event->xconfigure.width) || ((int32_t)height != event->xconfigure.height)) { - width = event->xconfigure.width; - height = event->xconfigure.height; - resize(); - } - break; - default: - break; - } -} - -template <> -void Demo::run<WsiPlatform::xlib>() { - while (!quit) { - XEvent event; - - if (pause) { - XNextEvent(xlib_display, &event); - handle_xlib_event(&event); - } - while (XPending(xlib_display) > 0) { - XNextEvent(xlib_display, &event); - handle_xlib_event(&event); - } - if (initialized && swapchain_ready) { - draw(); - if (!is_minimized) { - curFrame++; - } - - if (frameCount != UINT32_MAX && curFrame == frameCount) { - quit = true; - } - } - } -} -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - -void Demo::handle_xcb_event(const xcb_generic_event_t *event) { - uint8_t event_code = event->response_type & 0x7f; - switch (event_code) { - case XCB_EXPOSE: - // TODO: Resize window - break; - case XCB_CLIENT_MESSAGE: - if ((*(xcb_client_message_event_t *)event).data.data32[0] == (*atom_wm_delete_window).atom) { - quit = true; - } - break; - case XCB_KEY_RELEASE: { - const xcb_key_release_event_t *key = (const xcb_key_release_event_t *)event; - - switch (key->detail) { - case 0x9: // Escape - quit = true; - break; - case 0x71: // left arrow key - spin_angle -= spin_increment; - break; - case 0x72: // right arrow key - spin_angle += spin_increment; - break; - case 0x41: // space bar - pause = !pause; - break; - } - } break; - case XCB_CONFIGURE_NOTIFY: { - const xcb_configure_notify_event_t *cfg = (const xcb_configure_notify_event_t *)event; - if ((width != cfg->width) || (height != cfg->height)) { - width = cfg->width; - height = cfg->height; - resize(); - } - } break; - default: - break; - } -} - -template <> -void Demo::run<WsiPlatform::xcb>() { - xcb_flush(connection); - - while (!quit) { - xcb_generic_event_t *event; - - if (pause) { - event = xcb_wait_for_event(connection); - } else { - event = xcb_poll_for_event(connection); - } - while (event) { - handle_xcb_event(event); - free(event); - event = xcb_poll_for_event(connection); - } - if (initialized && swapchain_ready) { - draw(); - if (!is_minimized) { - curFrame++; - } - if (frameCount != UINT32_MAX && curFrame == frameCount) { - quit = true; - } - } - } -} - -template <> -void Demo::create_window<WsiPlatform::xcb>() { - uint32_t value_mask, value_list[32]; - - xcb_window = xcb_generate_id(connection); - - value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; - value_list[0] = screen->black_pixel; - value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY; - - xcb_create_window(connection, XCB_COPY_FROM_PARENT, xcb_window, screen->root, 0, 0, width, height, 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, value_mask, value_list); - - /* Magic code that will send notification when window is destroyed */ - xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connection, 1, 12, "WM_PROTOCOLS"); - xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, cookie, 0); - - xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(connection, 0, 16, "WM_DELETE_WINDOW"); - atom_wm_delete_window = xcb_intern_atom_reply(connection, cookie2, 0); - - xcb_change_property(connection, XCB_PROP_MODE_REPLACE, xcb_window, (*reply).atom, 4, 32, 1, &(*atom_wm_delete_window).atom); - - free(reply); - - xcb_map_window(connection, xcb_window); - - // Force the x/y coordinates to 100,100 results are identical in - // consecutive - // runs - std::array<uint32_t, 2> const coords = {100, 100}; - xcb_configure_window(connection, xcb_window, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, coords.data()); -} -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - -template <> -void Demo::run<WsiPlatform::wayland>() { - while (!quit) { - if (pause) { - wl_display_dispatch(wayland_display); - } else { - wl_display_dispatch_pending(wayland_display); - if (initialized && swapchain_ready) { - draw(); - if (!is_minimized) { - curFrame++; - } - if (frameCount != UINT32_MAX && curFrame == frameCount) { - quit = true; - } - } - } - } -} - -static void handle_surface_configure(void *data, xdg_surface *xdg_surface, uint32_t serial) { - Demo &demo = *static_cast<Demo *>(data); - xdg_surface_ack_configure(xdg_surface, serial); - demo.xdg_surface_has_been_configured = true; - if (demo.pending_width > 0) { - demo.width = demo.pending_width; - } - if (demo.pending_height > 0) { - demo.height = demo.pending_height; - } - demo.resize(); -} - -static const xdg_surface_listener surface_listener = {handle_surface_configure}; - -static void handle_toplevel_configure(void *data, xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, - struct wl_array *states) { - Demo &demo = *static_cast<Demo *>(data); - /* zero values imply the program may choose its own size, so in that case - * stay with the existing value (which on startup is the default) */ - if (width > 0) { - demo.pending_width = static_cast<uint32_t>(width); - } - if (height > 0) { - demo.pending_height = static_cast<uint32_t>(height); - } - // This will be followed by a surface configure -} - -static void handle_toplevel_close(void *data, xdg_toplevel *xdg_toplevel) { - Demo &demo = *static_cast<Demo *>(data); - demo.quit = true; -} - -static const xdg_toplevel_listener toplevel_listener = {handle_toplevel_configure, handle_toplevel_close}; - -template <> -void Demo::create_window<WsiPlatform::wayland>() { - if (!wm_base) { - printf("Compositor did not provide the standard protocol xdg-wm-base\n"); - fflush(stdout); - exit(1); - } - - wayland_window = wl_compositor_create_surface(compositor); - if (!wayland_window) { - printf("Can not create wayland_surface from compositor!\n"); - fflush(stdout); - exit(1); - } - - window_surface = xdg_wm_base_get_xdg_surface(wm_base, wayland_window); - if (!window_surface) { - printf("Can not get xdg_surface from wayland_surface!\n"); - fflush(stdout); - exit(1); - } - window_toplevel = xdg_surface_get_toplevel(window_surface); - if (!window_toplevel) { - printf("Can not allocate xdg_toplevel for xdg_surface!\n"); - fflush(stdout); - exit(1); - } - xdg_surface_add_listener(window_surface, &surface_listener, this); - xdg_toplevel_add_listener(window_toplevel, &toplevel_listener, this); - xdg_toplevel_set_title(window_toplevel, APP_SHORT_NAME); - if (xdg_decoration_mgr) { - // if supported, let the compositor render titlebars for us - toplevel_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(xdg_decoration_mgr, window_toplevel); - zxdg_toplevel_decoration_v1_set_mode(toplevel_decoration, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); - } - - wl_surface_commit(wayland_window); -} -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - -void Demo::handle_directfb_event(const DFBInputEvent *event) { - if (event->type != DIET_KEYPRESS) return; - switch (event->key_symbol) { - case DIKS_ESCAPE: // Escape - quit = true; - break; - case DIKS_CURSOR_LEFT: // left arrow key - spin_angle -= spin_increment; - break; - case DIKS_CURSOR_RIGHT: // right arrow key - spin_angle += spin_increment; - break; - case DIKS_SPACE: // space bar - pause = !pause; - break; - default: - break; - } -} - -template <> -void Demo::run<WsiPlatform::directfb>() { - while (!quit) { - DFBInputEvent event; - - if (pause) { - event_buffer->WaitForEvent(event_buffer); - if (!event_buffer->GetEvent(event_buffer, DFB_EVENT(&event))) handle_directfb_event(&event); - } else { - if (!event_buffer->GetEvent(event_buffer, DFB_EVENT(&event))) handle_directfb_event(&event); - if (initialized && swapchain_ready) { - draw(); - if (!is_minimized) { - curFrame++; - } - if (frameCount != UINT32_MAX && curFrame == frameCount) { - quit = true; - } - } - } - } -} - -template <> -void Demo::create_window<WsiPlatform::directfb>() { - DFBResult ret; - - ret = DirectFBInit(nullptr, nullptr); - if (ret) { - printf("DirectFBInit failed to initialize DirectFB!\n"); - fflush(stdout); - exit(1); - } - - ret = DirectFBCreate(&dfb); - if (ret) { - printf("DirectFBCreate failed to create main interface of DirectFB!\n"); - fflush(stdout); - exit(1); - } - - DFBSurfaceDescription desc; - desc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT); - desc.caps = DSCAPS_PRIMARY; - desc.width = width; - desc.height = height; - ret = dfb->CreateSurface(dfb, &desc, &directfb_window); - if (ret) { - printf("CreateSurface failed to create DirectFB surface interface!\n"); - fflush(stdout); - exit(1); - } - - ret = dfb->CreateInputEventBuffer(dfb, DICAPS_KEYS, DFB_FALSE, &event_buffer); - if (ret) { - printf("CreateInputEventBuffer failed to create DirectFB event buffer interface!\n"); - fflush(stdout); - exit(1); - } -} -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) -template <> -void Demo::run<WsiPlatform::metal>() { - if (!initialized || !swapchain_ready) { - return; - } - draw(); - if (!is_minimized) { - curFrame++; - } - if (frameCount != UINT32_MAX && curFrame == frameCount) { - quit = true; - } -} -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - -vk::Result Demo::create_display_surface() { - auto display_properties_return = gpu.getDisplayPropertiesKHR(); - VERIFY((display_properties_return.result == vk::Result::eSuccess) || - (display_properties_return.result == vk::Result::eIncomplete)); - - auto display = display_properties_return.value.at(0).display; - - auto display_mode_props_return = gpu.getDisplayModePropertiesKHR(display); - VERIFY(display_mode_props_return.result == vk::Result::eSuccess); - - if (display_mode_props_return.value.size() == 0) { - printf("Cannot find any mode for the display!\n"); - fflush(stdout); - exit(1); - } - auto display_mode_prop = display_mode_props_return.value.at(0); - - // Get the list of planes - auto display_plane_props_return = gpu.getDisplayPlanePropertiesKHR(); - VERIFY(display_plane_props_return.result == vk::Result::eSuccess); - - if (display_plane_props_return.value.size() == 0) { - printf("Cannot find any plane!\n"); - fflush(stdout); - exit(1); - } - auto display_plane_props = display_plane_props_return.value; - - vk::Bool32 found_plane = VK_FALSE; - uint32_t plane_found = 0; - // Find a plane compatible with the display - for (uint32_t plane_index = 0; plane_index < display_plane_props.size(); plane_index++) { - // Disqualify planes that are bound to a different display - if (display_plane_props[plane_index].currentDisplay && (display_plane_props[plane_index].currentDisplay != display)) { - continue; - } - - auto display_plane_supported_displays_return = gpu.getDisplayPlaneSupportedDisplaysKHR(plane_index); - VERIFY(display_plane_supported_displays_return.result == vk::Result::eSuccess); - - if (display_plane_supported_displays_return.value.size() == 0) { - continue; - } - - for (const auto &supported_display : display_plane_supported_displays_return.value) { - if (supported_display == display) { - found_plane = VK_TRUE; - plane_found = plane_index; - break; - } - } - - if (found_plane) { - break; - } - } - - if (!found_plane) { - printf("Cannot find a plane compatible with the display!\n"); - fflush(stdout); - exit(1); - } - - vk::DisplayPlaneCapabilitiesKHR planeCaps = - gpu.getDisplayPlaneCapabilitiesKHR(display_mode_prop.displayMode, plane_found).value; - // Find a supported alpha mode - vk::DisplayPlaneAlphaFlagBitsKHR alphaMode = vk::DisplayPlaneAlphaFlagBitsKHR::eOpaque; - std::array<vk::DisplayPlaneAlphaFlagBitsKHR, 4> alphaModes = { - vk::DisplayPlaneAlphaFlagBitsKHR::eOpaque, - vk::DisplayPlaneAlphaFlagBitsKHR::eGlobal, - vk::DisplayPlaneAlphaFlagBitsKHR::ePerPixel, - vk::DisplayPlaneAlphaFlagBitsKHR::ePerPixelPremultiplied, - }; - for (const auto &alpha_mode : alphaModes) { - if (planeCaps.supportedAlpha & alpha_mode) { - alphaMode = alpha_mode; - break; - } - } - - vk::Extent2D image_extent{}; - image_extent.setWidth(display_mode_prop.parameters.visibleRegion.width) - .setHeight(display_mode_prop.parameters.visibleRegion.height); - - auto const createInfo = vk::DisplaySurfaceCreateInfoKHR() - .setDisplayMode(display_mode_prop.displayMode) - .setPlaneIndex(plane_found) - .setPlaneStackIndex(display_plane_props[plane_found].currentStackIndex) - .setGlobalAlpha(1.0f) - .setAlphaMode(alphaMode) - .setImageExtent(image_extent); - - return inst.createDisplayPlaneSurfaceKHR(&createInfo, nullptr, &surface); -} - -template <> -void Demo::run<WsiPlatform::display>() { - while (!quit) { - draw(); - curFrame++; - - if (frameCount != UINT32_MAX && curFrame == frameCount) { - quit = true; - } - } -} - -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) -#include <sys/keycodes.h> - -template <> -void Demo::run<WsiPlatform::qnx>() { - int size[2] = {0, 0}; - screen_window_t win; - int val; - int rc; - - while (!quit) { - while (!screen_get_event(screen_context, screen_event, pause ? ~0 : 0)) { - rc = screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &val); - if (rc) { - printf("Cannot get SCREEN_PROPERTY_TYPE of the event! (%s)\n", strerror(errno)); - fflush(stdout); - quit = true; - break; - } - if (val == SCREEN_EVENT_NONE) { - break; - } - switch (val) { - case SCREEN_EVENT_KEYBOARD: - rc = screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_FLAGS, &val); - if (rc) { - printf("Cannot get SCREEN_PROPERTY_FLAGS of the event! (%s)\n", strerror(errno)); - fflush(stdout); - quit = true; - break; - } - if (val & KEY_DOWN) { - rc = screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_SYM, &val); - if (rc) { - printf("Cannot get SCREEN_PROPERTY_SYM of the event! (%s)\n", strerror(errno)); - fflush(stdout); - quit = true; - break; - } - switch (val) { - case KEYCODE_ESCAPE: - quit = true; - break; - case KEYCODE_SPACE: - pause = !pause; - break; - case KEYCODE_LEFT: - spin_angle -= spin_increment; - break; - case KEYCODE_RIGHT: - spin_angle += spin_increment; - break; - default: - break; - } - } - break; - case SCREEN_EVENT_PROPERTY: - rc = screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_WINDOW, (void **)&win); - if (rc) { - printf("Cannot get SCREEN_PROPERTY_WINDOW of the event! (%s)\n", strerror(errno)); - fflush(stdout); - quit = true; - break; - } - rc = screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_NAME, &val); - if (rc) { - printf("Cannot get SCREEN_PROPERTY_NAME of the event! (%s)\n", strerror(errno)); - fflush(stdout); - quit = true; - break; - } - if (win == screen_window) { - switch (val) { - case SCREEN_PROPERTY_SIZE: - rc = screen_get_window_property_iv(win, SCREEN_PROPERTY_SIZE, size); - if (rc) { - printf("Cannot get SCREEN_PROPERTY_SIZE of the window in the event! (%s)\n", strerror(errno)); - fflush(stdout); - quit = true; - break; - } - width = size[0]; - height = size[1]; - resize(); - break; - default: - /* We are not interested in any other events for now */ - break; - } - } - break; - } - } - - if (pause || !initialized || !swapchain_ready) { - } else { - update_data_buffer(submission_resources[current_submission_index].uniform_memory_ptr); - draw(); - if (!is_minimized) { - curFrame++; - } - if (frameCount != UINT32_MAX && curFrame == frameCount) { - quit = true; - } - } - } -} - -template <> -void Demo::create_window<WsiPlatform::qnx>() { - const char *idstr = APP_SHORT_NAME; - int size[2]; - int usage = SCREEN_USAGE_VULKAN; - int rc; - - rc = screen_create_context(&screen_context, 0); - if (rc) { - printf("Cannot create QNX Screen context!\n"); - fflush(stdout); - exit(EXIT_FAILURE); - } - rc = screen_create_window(&screen_window, screen_context); - if (rc) { - printf("Cannot create QNX Screen window!\n"); - fflush(stdout); - exit(EXIT_FAILURE); - } - rc = screen_create_event(&screen_event); - if (rc) { - printf("Cannot create QNX Screen event!\n"); - fflush(stdout); - exit(EXIT_FAILURE); - } - - /* Set window caption */ - screen_set_window_property_cv(screen_window, SCREEN_PROPERTY_ID_STRING, strlen(idstr), idstr); - - /* Setup VULKAN usage flags */ - rc = screen_set_window_property_iv(screen_window, SCREEN_PROPERTY_USAGE, &usage); - if (rc) { - printf("Cannot set SCREEN_USAGE_VULKAN flag!\n"); - fflush(stdout); - exit(EXIT_FAILURE); - } - - /* Setup window size */ - if ((width == 0) || (height == 0)) { - rc = screen_get_window_property_iv(screen_window, SCREEN_PROPERTY_SIZE, size); - if (rc) { - printf("Cannot obtain current window size!\n"); - fflush(stdout); - exit(EXIT_FAILURE); - } - width = size[0]; - height = size[1]; - } else { - size[0] = width; - size[1] = height; - rc = screen_set_window_property_iv(screen_window, SCREEN_PROPERTY_SIZE, size); - if (rc) { - printf("Cannot set window size!\n"); - fflush(stdout); - exit(EXIT_FAILURE); - } - } -} -#endif -#if defined(VK_USE_PLATFORM_FUCHSIA) - -const char *Demo::get_fuchsia_image_pipe_layer() const { - switch (wsi_platform) { - case (WsiPlatform::fuchsia_display): - return "VK_LAYER_FUCHSIA_imagepipe_swapchain_fb"; - case (WsiPlatform::fuchsia_scenic): - return "VK_LAYER_FUCHSIA_imagepipe_swapchain"; - case (WsiPlatform::auto_): - ERR_EXIT("auto WSI platform is not supported on Fuchsia", "get_fuchsia_image_pipe_layer failure"); - default: - ERR_EXIT("Invalid WSI platform", "get_fuchsia_image_pipe_layer failure"); - } -} - -void Demo::create_window<WsiPlatform::fuchsia_display>() { - // Nothing to do -} - -void Demo::create_window<WsiPlatform::fuchsia_scenic>() { - if (flatland_view) return; - - zx::result<fidl::ClientEnd<fuchsia_io::Directory> > incoming_result = component::OpenServiceRoot(); - if (incoming_result.is_error()) { - printf("Failed to open incoming directory: %s\n", incoming_result.status_string()); - ERR_EXIT("Failed to open incoming directory", "create_window<WsiPlatform::fuchsia_scenic> failure"); - } - incoming = std::move(incoming_result).value(); - - outgoing = std::make_unique<component::OutgoingDirectory>(loop.dispatcher()); - - FlatlandViewProviderService::CreateView2Callback create_view_callback = [this](fuchsia_ui_app::CreateView2Args args) { - auto resize_callback = [this](uint32_t width, uint32_t height) { - this->width = width; - this->height = height; - if (initialized) { - resize(); - } - }; - - flatland_view = - FlatlandView::Create(incoming.borrow(), std::move(*args.view_creation_token()), resize_callback, loop.dispatcher()); - if (!flatland_view) ERR_EXIT("Failed to created FlatlandView", "create_window<WsiPlatform::fuchsia_scenic> failure"); - - view_creation_token = flatland_view->TakeChildViewCreationToken(); - }; - - view_provider_service = std::make_unique<FlatlandViewProviderService>(std::move(create_view_callback), loop.dispatcher()); - - zx::result<> add_protocol_result = outgoing->AddUnmanagedProtocol<fuchsia_ui_app::ViewProvider>( - [view_provider_service = view_provider_service.get()](fidl::ServerEnd<fuchsia_ui_app::ViewProvider> server_end) { - view_provider_service->HandleViewProviderRequest(std::move(server_end)); - }); - if (add_protocol_result.is_error()) { - printf("Failed to add protocol to outgoing directory: %s\n", add_protocol_result.status_string()); - ERR_EXIT("Failed to add protocol to outgoing directory", "create_window<WsiPlatform::fuchsia_scenic> failure"); - } - - zx::result<> serve_result = outgoing->ServeFromStartupInfo(); - if (serve_result.is_error()) { - printf("Failed to serve outgoing directory: %s\n", serve_result.status_string()); - ERR_EXIT("Failed to serve outgoing directory", "create_window<WsiPlatform::fuchsia_scenic> failure"); - } - - zx_status_t loop_status = ZX_OK; - - // Run message loop until view has been created. - while (!quit && !flatland_view && loop_status == ZX_OK) { - loop_status = loop.RunUntilIdle(); - } -} -template <> -void Demo::run<WsiPlatform::fuchsia_display>() { - uint32_t num_frames = 60; - uint32_t elapsed_frames = 0; - static const float kMsPerSec = 1000; - - double total_ms = 0; - auto t0 = std::chrono::high_resolution_clock::now(); - - while (!quit) { - if (wsi_platform == WsiPlatform::fuchsia_scenic) { - if (loop.RunUntilIdle() != ZX_OK) { - break; - } - } - auto t1 = std::chrono::high_resolution_clock::now(); - std::chrono::duration<double, std::milli> elapsed = t1 - t0; - total_ms += elapsed.count(); - t0 = t1; - - if (elapsed_frames && (elapsed_frames % num_frames) == 0) { - float fps = static_cast<float>(num_frames / (total_ms / kMsPerSec)); - printf("Framerate average for last %u frames: %f frames per second\n", num_frames, fps); - fflush(stdout); - total_ms = 0; - // attempt to log once per second - num_frames = static_cast<uint32_t>(fps); - elapsed_frames = 0; - } - if (initialized && swapchain_ready) { - draw(); - - if (!is_minimized) { - curFrame++; - } - elapsed_frames++; - - if (frameCount != UINT32_MAX && curFrame == frameCount) { - quit = true; - } - } - } -} - -template <> -void Demo::run<WsiPlatform::fuchsia_scenic>() { - // Uses the same run function,as fuchsia_display - run<WsiPlatform::fuschia_display>(); -} - -#endif - -#if _WIN32 -// Include header required for parsing the command line options. -#include <shellapi.h> - -Demo demo; - -// MS-Windows event handling function: -LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - switch (uMsg) { - case WM_CLOSE: - PostQuitMessage(validation_error); - break; - case WM_PAINT: - if (!demo.in_callback) { - demo.run<WsiPlatform::win32>(); - } - break; - case WM_GETMINMAXINFO: // set window's minimum size - ((MINMAXINFO *)lParam)->ptMinTrackSize = demo.minsize; - return 0; - case WM_ERASEBKGND: - return 1; - case WM_SIZE: - // Resize the application to the new window size, except when - // it was minimized. Vulkan doesn't support images or swapchains - // with width=0 and height=0. - if (wParam != SIZE_MINIMIZED) { - demo.width = lParam & 0xffff; - demo.height = (lParam & 0xffff0000) >> 16; - demo.resize(); - } - break; - case WM_KEYDOWN: - switch (wParam) { - case VK_ESCAPE: - PostQuitMessage(validation_error); - break; - case VK_LEFT: - demo.spin_angle -= demo.spin_increment; - break; - case VK_RIGHT: - demo.spin_angle += demo.spin_increment; - break; - case VK_SPACE: - demo.pause = !demo.pause; - break; - } - return 0; - default: - break; - } - - return (DefWindowProc(hWnd, uMsg, wParam, lParam)); -} - -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow) { - // TODO: Gah.. refactor. This isn't 1989. - MSG msg; // message - bool done; // flag saying when app is complete - int argc; - char **argv; - - // Ensure wParam is initialized. - msg.wParam = 0; - - // Use the CommandLine functions to get the command line arguments. - // Unfortunately, Microsoft outputs - // this information as wide characters for Unicode, and we simply want the - // Ascii version to be compatible - // with the non-Windows side. So, we have to convert the information to - // Ascii character strings. - LPWSTR *commandLineArgs = CommandLineToArgvW(GetCommandLineW(), &argc); - if (nullptr == commandLineArgs) { - argc = 0; - } - - if (argc > 0) { - argv = (char **)malloc(sizeof(char *) * argc); - if (argv == nullptr) { - argc = 0; - } else { - for (int iii = 0; iii < argc; iii++) { - size_t wideCharLen = wcslen(commandLineArgs[iii]); - size_t numConverted = 0; - - argv[iii] = (char *)malloc(sizeof(char) * (wideCharLen + 1)); - if (argv[iii] != nullptr) { - wcstombs_s(&numConverted, argv[iii], wideCharLen + 1, commandLineArgs[iii], wideCharLen + 1); - } - } - } - } else { - argv = nullptr; - } - - demo.init(argc, argv); - - // Free up the items we had to allocate for the command line arguments. - if (argc > 0 && argv != nullptr) { - for (int iii = 0; iii < argc; iii++) { - if (argv[iii] != nullptr) { - free(argv[iii]); - } - } - free(argv); - } - - demo.connection = hInstance; - demo.name = "Vulkan Cube"; - demo.create_window<WsiPlatform::win32>(); - demo.create_surface(); - demo.select_physical_device(); - demo.init_vk_swapchain(); - - demo.prepare(); - - done = false; // initialize loop condition variable - - // main message loop - while (!done) { - if (demo.pause) { - const BOOL succ = WaitMessage(); - - if (!succ) { - const auto &suppress_popups = demo.suppress_popups; - ERR_EXIT("WaitMessage() failed on paused demo", "event loop error"); - } - } - - PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE); - if (msg.message == WM_QUIT) // check for a quit message - { - done = true; // if found, quit app - } else { - /* Translate and dispatch to event queue*/ - TranslateMessage(&msg); - DispatchMessage(&msg); - } - RedrawWindow(demo.window, nullptr, nullptr, RDW_INTERNALPAINT); - } - - demo.cleanup(); - - return static_cast<int>(msg.wParam); -} - -#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__QNX__) || defined(__GNU__) || \ - defined(__Fuchsia__) - -template <WsiPlatform WSI_PLATFORM> -void Demo::execute() { - create_window<WSI_PLATFORM>(); - - create_surface(); - - select_physical_device(); - - init_vk_swapchain(); - - prepare(); - - run<WSI_PLATFORM>(); -} - -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -template <> -void Demo::execute<WsiPlatform::display>() { - select_physical_device(); - - create_surface(); - - init_vk_swapchain(); - - prepare(); - - run<WsiPlatform::display>(); -} -#endif - -int main(int argc, char **argv) { - Demo demo; - - demo.init(argc, argv); - - switch (demo.wsi_platform) { - default: - case (WsiPlatform::auto_): - fprintf(stderr, - "WSI platform should have already been set, indicating a bug. Please set a WSI platform manually with " - "--wsi\n"); - exit(1); - break; -#if defined(VK_USE_PLATFORM_XCB_KHR) - case (WsiPlatform::xcb): - demo.execute<WsiPlatform::xcb>(); - break; -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - case (WsiPlatform::xlib): - demo.execute<WsiPlatform::xlib>(); - break; -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - case (WsiPlatform::wayland): - demo.execute<WsiPlatform::wayland>(); - break; -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - case (WsiPlatform::directfb): - demo.execute<WsiPlatform::directfb>(); - break; -#endif -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - case (WsiPlatform::display): - demo.execute<WsiPlatform::display>(); - break; -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - case (WsiPlatform::qnx): - demo.execute<WsiPlatform::qnx>(); - break; -#endif -#if defined(VK_USE_PLATFORM_FUCHSIA) - case (WsiPlatform::fuchsia_display): - demo.execute<WsiPlatform::fuchsia_display>(); - break; - case (WsiPlatform::fuchsia_scenic): - demo.execute<WsiPlatform::fuchsia_scenic>(); - break; -#endif - } - - demo.cleanup(); - - return validation_error; -} - -#elif defined(VK_USE_PLATFORM_METAL_EXT) - -// Global function invoked from NS or UI views and controllers to create demo -static void demo_main(Demo &demo, void *caMetalLayer, int argc, const char *argv[]) { - demo.init(argc, (char **)argv); - demo.caMetalLayer = caMetalLayer; - demo.create_surface(); - demo.select_physical_device(); - demo.init_vk_swapchain(); - demo.prepare(); - demo.spin_angle = 0.4f; -} - -#else -#error "Platform not supported" -#endif diff --git a/tools/Vulkan-Tools/cube/cube.frag b/tools/Vulkan-Tools/cube/cube.frag deleted file mode 100644 index c68b9854..00000000 --- a/tools/Vulkan-Tools/cube/cube.frag +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2015-2016 The Khronos Group Inc. - * Copyright (c) 2015-2016 Valve Corporation - * Copyright (c) 2015-2016 LunarG, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Fragment shader for cube demo - */ -#version 400 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_ARB_shading_language_420pack : enable -layout (binding = 1) uniform sampler2D tex; - -layout (location = 0) in vec4 texcoord; -layout (location = 1) in vec3 frag_pos; -layout (location = 0) out vec4 uFragColor; - -const vec3 lightDir= vec3(0.424, 0.566, 0.707); - -float linearToSrgb(float linear) { - if (linear <= 0.0031308) { - return linear * 12.92; - } else { - return (1.055 * pow(linear, 1.0/2.4)) - 0.055; - } -} - -vec3 linearToSrgb(vec3 linear) { - return vec3(linearToSrgb(linear.r), linearToSrgb(linear.g), linearToSrgb(linear.b)); -} - -vec4 linearToSrgb(vec4 linear) { - return vec4(linearToSrgb(linear.rgb), linear.a); -} - -void main() { - vec3 dX = dFdx(frag_pos); - vec3 dY = dFdy(frag_pos); - vec3 normal = normalize(cross(dX,dY)); - float light = max(0.0, dot(lightDir, normal)); - uFragColor = linearToSrgb(light * texture(tex, texcoord.xy)); -} diff --git a/tools/Vulkan-Tools/cube/cube.frag.inc b/tools/Vulkan-Tools/cube/cube.frag.inc deleted file mode 100644 index 539636e5..00000000 --- a/tools/Vulkan-Tools/cube/cube.frag.inc +++ /dev/null @@ -1,84 +0,0 @@ - // 1115.1.0 - 0x07230203,0x00010000,0x0008000b,0x00000073,0x00000000,0x00020011,0x00000001,0x0006000b, - 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, - 0x0008000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x0000004e,0x00000063,0x0000006b, - 0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x00000190,0x00090004,0x415f4c47, - 0x735f4252,0x72617065,0x5f657461,0x64616873,0x6f5f7265,0x63656a62,0x00007374,0x00090004, - 0x415f4c47,0x735f4252,0x69646168,0x6c5f676e,0x75676e61,0x5f656761,0x70303234,0x006b6361, - 0x00040005,0x00000004,0x6e69616d,0x00000000,0x00070005,0x0000000a,0x656e696c,0x6f547261, - 0x62677253,0x3b316628,0x00000000,0x00040005,0x00000009,0x656e696c,0x00007261,0x00070005, - 0x00000010,0x656e696c,0x6f547261,0x62677253,0x33667628,0x0000003b,0x00040005,0x0000000f, - 0x656e696c,0x00007261,0x00070005,0x00000016,0x656e696c,0x6f547261,0x62677253,0x34667628, - 0x0000003b,0x00040005,0x00000015,0x656e696c,0x00007261,0x00040005,0x0000002c,0x61726170, - 0x0000006d,0x00040005,0x00000032,0x61726170,0x0000006d,0x00040005,0x00000037,0x61726170, - 0x0000006d,0x00040005,0x0000003f,0x61726170,0x0000006d,0x00030005,0x0000004c,0x00005864, - 0x00050005,0x0000004e,0x67617266,0x736f705f,0x00000000,0x00030005,0x00000051,0x00005964, - 0x00040005,0x00000054,0x6d726f6e,0x00006c61,0x00040005,0x00000059,0x6867696c,0x00000074, - 0x00050005,0x00000063,0x61724675,0x6c6f4367,0x0000726f,0x00030005,0x00000068,0x00786574, - 0x00050005,0x0000006b,0x63786574,0x64726f6f,0x00000000,0x00040005,0x00000071,0x61726170, - 0x0000006d,0x00040047,0x0000004e,0x0000001e,0x00000001,0x00040047,0x00000063,0x0000001e, - 0x00000000,0x00040047,0x00000068,0x00000021,0x00000001,0x00040047,0x00000068,0x00000022, - 0x00000000,0x00040047,0x0000006b,0x0000001e,0x00000000,0x00020013,0x00000002,0x00030021, - 0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040020,0x00000007,0x00000007, - 0x00000006,0x00040021,0x00000008,0x00000006,0x00000007,0x00040017,0x0000000c,0x00000006, - 0x00000003,0x00040020,0x0000000d,0x00000007,0x0000000c,0x00040021,0x0000000e,0x0000000c, - 0x0000000d,0x00040017,0x00000012,0x00000006,0x00000004,0x00040020,0x00000013,0x00000007, - 0x00000012,0x00040021,0x00000014,0x00000012,0x00000013,0x0004002b,0x00000006,0x00000019, - 0x3b4d2e1c,0x00020014,0x0000001a,0x0004002b,0x00000006,0x0000001f,0x414eb852,0x0004002b, - 0x00000006,0x00000023,0x3f870a3d,0x0004002b,0x00000006,0x00000025,0x3ed55555,0x0004002b, - 0x00000006,0x00000028,0x3d6147ae,0x00040015,0x0000002d,0x00000020,0x00000000,0x0004002b, - 0x0000002d,0x0000002e,0x00000000,0x0004002b,0x0000002d,0x00000033,0x00000001,0x0004002b, - 0x0000002d,0x00000038,0x00000002,0x0004002b,0x0000002d,0x00000043,0x00000003,0x00040020, - 0x0000004d,0x00000001,0x0000000c,0x0004003b,0x0000004d,0x0000004e,0x00000001,0x0004002b, - 0x00000006,0x0000005a,0x00000000,0x0004002b,0x00000006,0x0000005b,0x3ed91687,0x0004002b, - 0x00000006,0x0000005c,0x3f10e560,0x0004002b,0x00000006,0x0000005d,0x3f34fdf4,0x0006002c, - 0x0000000c,0x0000005e,0x0000005b,0x0000005c,0x0000005d,0x00040020,0x00000062,0x00000003, - 0x00000012,0x0004003b,0x00000062,0x00000063,0x00000003,0x00090019,0x00000065,0x00000006, - 0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x0003001b,0x00000066, - 0x00000065,0x00040020,0x00000067,0x00000000,0x00000066,0x0004003b,0x00000067,0x00000068, - 0x00000000,0x00040020,0x0000006a,0x00000001,0x00000012,0x0004003b,0x0000006a,0x0000006b, - 0x00000001,0x00040017,0x0000006c,0x00000006,0x00000002,0x00050036,0x00000002,0x00000004, - 0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,0x0000000d,0x0000004c,0x00000007, - 0x0004003b,0x0000000d,0x00000051,0x00000007,0x0004003b,0x0000000d,0x00000054,0x00000007, - 0x0004003b,0x00000007,0x00000059,0x00000007,0x0004003b,0x00000013,0x00000071,0x00000007, - 0x0004003d,0x0000000c,0x0000004f,0x0000004e,0x000400cf,0x0000000c,0x00000050,0x0000004f, - 0x0003003e,0x0000004c,0x00000050,0x0004003d,0x0000000c,0x00000052,0x0000004e,0x000400d0, - 0x0000000c,0x00000053,0x00000052,0x0003003e,0x00000051,0x00000053,0x0004003d,0x0000000c, - 0x00000055,0x0000004c,0x0004003d,0x0000000c,0x00000056,0x00000051,0x0007000c,0x0000000c, - 0x00000057,0x00000001,0x00000044,0x00000055,0x00000056,0x0006000c,0x0000000c,0x00000058, - 0x00000001,0x00000045,0x00000057,0x0003003e,0x00000054,0x00000058,0x0004003d,0x0000000c, - 0x0000005f,0x00000054,0x00050094,0x00000006,0x00000060,0x0000005e,0x0000005f,0x0007000c, - 0x00000006,0x00000061,0x00000001,0x00000028,0x0000005a,0x00000060,0x0003003e,0x00000059, - 0x00000061,0x0004003d,0x00000006,0x00000064,0x00000059,0x0004003d,0x00000066,0x00000069, - 0x00000068,0x0004003d,0x00000012,0x0000006d,0x0000006b,0x0007004f,0x0000006c,0x0000006e, - 0x0000006d,0x0000006d,0x00000000,0x00000001,0x00050057,0x00000012,0x0000006f,0x00000069, - 0x0000006e,0x0005008e,0x00000012,0x00000070,0x0000006f,0x00000064,0x0003003e,0x00000071, - 0x00000070,0x00050039,0x00000012,0x00000072,0x00000016,0x00000071,0x0003003e,0x00000063, - 0x00000072,0x000100fd,0x00010038,0x00050036,0x00000006,0x0000000a,0x00000000,0x00000008, - 0x00030037,0x00000007,0x00000009,0x000200f8,0x0000000b,0x0004003d,0x00000006,0x00000018, - 0x00000009,0x000500bc,0x0000001a,0x0000001b,0x00000018,0x00000019,0x000300f7,0x0000001d, - 0x00000000,0x000400fa,0x0000001b,0x0000001c,0x00000022,0x000200f8,0x0000001c,0x0004003d, - 0x00000006,0x0000001e,0x00000009,0x00050085,0x00000006,0x00000020,0x0000001e,0x0000001f, - 0x000200fe,0x00000020,0x000200f8,0x00000022,0x0004003d,0x00000006,0x00000024,0x00000009, - 0x0007000c,0x00000006,0x00000026,0x00000001,0x0000001a,0x00000024,0x00000025,0x00050085, - 0x00000006,0x00000027,0x00000023,0x00000026,0x00050083,0x00000006,0x00000029,0x00000027, - 0x00000028,0x000200fe,0x00000029,0x000200f8,0x0000001d,0x000100ff,0x00010038,0x00050036, - 0x0000000c,0x00000010,0x00000000,0x0000000e,0x00030037,0x0000000d,0x0000000f,0x000200f8, - 0x00000011,0x0004003b,0x00000007,0x0000002c,0x00000007,0x0004003b,0x00000007,0x00000032, - 0x00000007,0x0004003b,0x00000007,0x00000037,0x00000007,0x00050041,0x00000007,0x0000002f, - 0x0000000f,0x0000002e,0x0004003d,0x00000006,0x00000030,0x0000002f,0x0003003e,0x0000002c, - 0x00000030,0x00050039,0x00000006,0x00000031,0x0000000a,0x0000002c,0x00050041,0x00000007, - 0x00000034,0x0000000f,0x00000033,0x0004003d,0x00000006,0x00000035,0x00000034,0x0003003e, - 0x00000032,0x00000035,0x00050039,0x00000006,0x00000036,0x0000000a,0x00000032,0x00050041, - 0x00000007,0x00000039,0x0000000f,0x00000038,0x0004003d,0x00000006,0x0000003a,0x00000039, - 0x0003003e,0x00000037,0x0000003a,0x00050039,0x00000006,0x0000003b,0x0000000a,0x00000037, - 0x00060050,0x0000000c,0x0000003c,0x00000031,0x00000036,0x0000003b,0x000200fe,0x0000003c, - 0x00010038,0x00050036,0x00000012,0x00000016,0x00000000,0x00000014,0x00030037,0x00000013, - 0x00000015,0x000200f8,0x00000017,0x0004003b,0x0000000d,0x0000003f,0x00000007,0x0004003d, - 0x00000012,0x00000040,0x00000015,0x0008004f,0x0000000c,0x00000041,0x00000040,0x00000040, - 0x00000000,0x00000001,0x00000002,0x0003003e,0x0000003f,0x00000041,0x00050039,0x0000000c, - 0x00000042,0x00000010,0x0000003f,0x00050041,0x00000007,0x00000044,0x00000015,0x00000043, - 0x0004003d,0x00000006,0x00000045,0x00000044,0x00050051,0x00000006,0x00000046,0x00000042, - 0x00000000,0x00050051,0x00000006,0x00000047,0x00000042,0x00000001,0x00050051,0x00000006, - 0x00000048,0x00000042,0x00000002,0x00070050,0x00000012,0x00000049,0x00000046,0x00000047, - 0x00000048,0x00000045,0x000200fe,0x00000049,0x00010038 diff --git a/tools/Vulkan-Tools/cube/cube.vert b/tools/Vulkan-Tools/cube/cube.vert deleted file mode 100644 index 63380326..00000000 --- a/tools/Vulkan-Tools/cube/cube.vert +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2015-2016 The Khronos Group Inc. - * Copyright (c) 2015-2016 Valve Corporation - * Copyright (c) 2015-2016 LunarG, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Vertex shader used by Cube demo. - */ -#version 400 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_ARB_shading_language_420pack : enable -layout(std140, binding = 0) uniform buf { - mat4 MVP; - vec4 position[12*3]; - vec4 attr[12*3]; -} ubuf; - -layout (location = 0) out vec4 texcoord; -layout (location = 1) out vec3 frag_pos; - -void main() -{ - texcoord = ubuf.attr[gl_VertexIndex]; - gl_Position = ubuf.MVP * ubuf.position[gl_VertexIndex]; - frag_pos = gl_Position.xyz; -} diff --git a/tools/Vulkan-Tools/cube/cube.vert.inc b/tools/Vulkan-Tools/cube/cube.vert.inc deleted file mode 100644 index f5c3fef0..00000000 --- a/tools/Vulkan-Tools/cube/cube.vert.inc +++ /dev/null @@ -1,50 +0,0 @@ - // 1115.1.0 - 0x07230203,0x00010000,0x0008000b,0x0000002f,0x00000000,0x00020011,0x00000001,0x0006000b, - 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, - 0x0009000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x00000009,0x00000015,0x0000001e, - 0x0000002b,0x00030003,0x00000002,0x00000190,0x00090004,0x415f4c47,0x735f4252,0x72617065, - 0x5f657461,0x64616873,0x6f5f7265,0x63656a62,0x00007374,0x00090004,0x415f4c47,0x735f4252, - 0x69646168,0x6c5f676e,0x75676e61,0x5f656761,0x70303234,0x006b6361,0x00040005,0x00000004, - 0x6e69616d,0x00000000,0x00050005,0x00000009,0x63786574,0x64726f6f,0x00000000,0x00030005, - 0x0000000f,0x00667562,0x00040006,0x0000000f,0x00000000,0x0050564d,0x00060006,0x0000000f, - 0x00000001,0x69736f70,0x6e6f6974,0x00000000,0x00050006,0x0000000f,0x00000002,0x72747461, - 0x00000000,0x00040005,0x00000011,0x66756275,0x00000000,0x00060005,0x00000015,0x565f6c67, - 0x65747265,0x646e4978,0x00007865,0x00060005,0x0000001c,0x505f6c67,0x65567265,0x78657472, - 0x00000000,0x00060006,0x0000001c,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006, - 0x0000001c,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x0000001c, - 0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00030005,0x0000001e,0x00000000, - 0x00050005,0x0000002b,0x67617266,0x736f705f,0x00000000,0x00040047,0x00000009,0x0000001e, - 0x00000000,0x00040047,0x0000000d,0x00000006,0x00000010,0x00040047,0x0000000e,0x00000006, - 0x00000010,0x00030047,0x0000000f,0x00000002,0x00040048,0x0000000f,0x00000000,0x00000005, - 0x00050048,0x0000000f,0x00000000,0x00000007,0x00000010,0x00050048,0x0000000f,0x00000000, - 0x00000023,0x00000000,0x00050048,0x0000000f,0x00000001,0x00000023,0x00000040,0x00050048, - 0x0000000f,0x00000002,0x00000023,0x00000280,0x00040047,0x00000011,0x00000021,0x00000000, - 0x00040047,0x00000011,0x00000022,0x00000000,0x00040047,0x00000015,0x0000000b,0x0000002a, - 0x00030047,0x0000001c,0x00000002,0x00050048,0x0000001c,0x00000000,0x0000000b,0x00000000, - 0x00050048,0x0000001c,0x00000001,0x0000000b,0x00000001,0x00050048,0x0000001c,0x00000002, - 0x0000000b,0x00000003,0x00040047,0x0000002b,0x0000001e,0x00000001,0x00020013,0x00000002, - 0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007, - 0x00000006,0x00000004,0x00040020,0x00000008,0x00000003,0x00000007,0x0004003b,0x00000008, - 0x00000009,0x00000003,0x00040018,0x0000000a,0x00000007,0x00000004,0x00040015,0x0000000b, - 0x00000020,0x00000000,0x0004002b,0x0000000b,0x0000000c,0x00000024,0x0004001c,0x0000000d, - 0x00000007,0x0000000c,0x0004001c,0x0000000e,0x00000007,0x0000000c,0x0005001e,0x0000000f, - 0x0000000a,0x0000000d,0x0000000e,0x00040020,0x00000010,0x00000002,0x0000000f,0x0004003b, - 0x00000010,0x00000011,0x00000002,0x00040015,0x00000012,0x00000020,0x00000001,0x0004002b, - 0x00000012,0x00000013,0x00000002,0x00040020,0x00000014,0x00000001,0x00000012,0x0004003b, - 0x00000014,0x00000015,0x00000001,0x00040020,0x00000017,0x00000002,0x00000007,0x0004002b, - 0x0000000b,0x0000001a,0x00000001,0x0004001c,0x0000001b,0x00000006,0x0000001a,0x0005001e, - 0x0000001c,0x00000007,0x00000006,0x0000001b,0x00040020,0x0000001d,0x00000003,0x0000001c, - 0x0004003b,0x0000001d,0x0000001e,0x00000003,0x0004002b,0x00000012,0x0000001f,0x00000000, - 0x00040020,0x00000020,0x00000002,0x0000000a,0x0004002b,0x00000012,0x00000023,0x00000001, - 0x00040017,0x00000029,0x00000006,0x00000003,0x00040020,0x0000002a,0x00000003,0x00000029, - 0x0004003b,0x0000002a,0x0000002b,0x00000003,0x00050036,0x00000002,0x00000004,0x00000000, - 0x00000003,0x000200f8,0x00000005,0x0004003d,0x00000012,0x00000016,0x00000015,0x00060041, - 0x00000017,0x00000018,0x00000011,0x00000013,0x00000016,0x0004003d,0x00000007,0x00000019, - 0x00000018,0x0003003e,0x00000009,0x00000019,0x00050041,0x00000020,0x00000021,0x00000011, - 0x0000001f,0x0004003d,0x0000000a,0x00000022,0x00000021,0x0004003d,0x00000012,0x00000024, - 0x00000015,0x00060041,0x00000017,0x00000025,0x00000011,0x00000023,0x00000024,0x0004003d, - 0x00000007,0x00000026,0x00000025,0x00050091,0x00000007,0x00000027,0x00000022,0x00000026, - 0x00050041,0x00000008,0x00000028,0x0000001e,0x0000001f,0x0003003e,0x00000028,0x00000027, - 0x00050041,0x00000008,0x0000002c,0x0000001e,0x0000001f,0x0004003d,0x00000007,0x0000002d, - 0x0000002c,0x0008004f,0x00000029,0x0000002e,0x0000002d,0x0000002d,0x00000000,0x00000001, - 0x00000002,0x0003003e,0x0000002b,0x0000002e,0x000100fd,0x00010038 diff --git a/tools/Vulkan-Tools/cube/cube_functions.h b/tools/Vulkan-Tools/cube/cube_functions.h deleted file mode 100644 index 975f65f6..00000000 --- a/tools/Vulkan-Tools/cube/cube_functions.h +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (c) 2025 The Khronos Group Inc. - * Copyright (c) 2025 Valve Corporation - * Copyright (c) 2025 LunarG, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Author: Charles Giessen <charles@lunarg.com> - * - */ -#pragma once - -// Need to include relevant system headers to open the dynamic library -#if defined(_WIN32) -#include <windows.h> -#elif defined(__APPLE__) -#include <stdlib.h> -#include <dlfcn.h> -#else -#include <dlfcn.h> -#endif - -// We are providing storage for all functions, make sure the vulkan headers doesn't conflate with ours. -#if !defined(VK_NO_PROTOTYPES) -#define VK_NO_PROTOTYPES -#endif - -#include <vulkan/vulkan.h> - -void* vulkan_library; - -// Global Functions -PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; -PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties; -PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties; -PFN_vkCreateInstance vkCreateInstance; - -// Per-platform Instance functions -#if defined(VK_USE_PLATFORM_WIN32_KHR) -PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR; -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR; -#endif -#if defined(VK_USE_PLATFORM_ANDROID_KHR) -PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR; -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) -PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR; -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) -PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR; -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) -PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT; -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -PFN_vkCreateDirectFBSurfaceEXT vkCreateDirectFBSurfaceEXT; -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) -PFN_vkCreateScreenSurfaceQNX vkCreateScreenSurfaceQNX; -#endif - -// Instance functions -PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT; -PFN_vkCreateDevice vkCreateDevice; -PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT; -PFN_vkDestroyInstance vkDestroyInstance; -PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR; -PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties; -PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices; -PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR; -PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR; -PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR; -PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR; -PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR; -PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures; -PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties; -PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties; -PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties; -PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties; -PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR; -PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR; -PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR; -PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR; -PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR; - -// While technically a device function, it needs to be loaded with get instance proc addr -PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr; - -// Device functions -PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR; -PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers; -PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets; -PFN_vkAllocateMemory vkAllocateMemory; -PFN_vkBeginCommandBuffer vkBeginCommandBuffer; -PFN_vkBindBufferMemory vkBindBufferMemory; -PFN_vkBindImageMemory vkBindImageMemory; -PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT; -PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass; -PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets; -PFN_vkCmdBindPipeline vkCmdBindPipeline; -PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage; -PFN_vkCmdDraw vkCmdDraw; -PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT; -PFN_vkCmdEndRenderPass vkCmdEndRenderPass; -PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier; -PFN_vkCmdSetScissor vkCmdSetScissor; -PFN_vkCmdSetViewport vkCmdSetViewport; -PFN_vkCreateBuffer vkCreateBuffer; -PFN_vkCreateCommandPool vkCreateCommandPool; -PFN_vkCreateDescriptorPool vkCreateDescriptorPool; -PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout; -PFN_vkCreateFence vkCreateFence; -PFN_vkCreateFramebuffer vkCreateFramebuffer; -PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines; -PFN_vkCreateImage vkCreateImage; -PFN_vkCreateImageView vkCreateImageView; -PFN_vkCreatePipelineCache vkCreatePipelineCache; -PFN_vkCreatePipelineLayout vkCreatePipelineLayout; -PFN_vkCreateRenderPass vkCreateRenderPass; -PFN_vkCreateSampler vkCreateSampler; -PFN_vkCreateSemaphore vkCreateSemaphore; -PFN_vkCreateShaderModule vkCreateShaderModule; -PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR; -PFN_vkDestroyBuffer vkDestroyBuffer; -PFN_vkDestroyCommandPool vkDestroyCommandPool; -PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool; -PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout; -PFN_vkDestroyDevice vkDestroyDevice; -PFN_vkDestroyFence vkDestroyFence; -PFN_vkDestroyFramebuffer vkDestroyFramebuffer; -PFN_vkDestroyImage vkDestroyImage; -PFN_vkDestroyImageView vkDestroyImageView; -PFN_vkDestroyPipeline vkDestroyPipeline; -PFN_vkDestroyPipelineCache vkDestroyPipelineCache; -PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout; -PFN_vkDestroyRenderPass vkDestroyRenderPass; -PFN_vkDestroySampler vkDestroySampler; -PFN_vkDestroySemaphore vkDestroySemaphore; -PFN_vkDestroyShaderModule vkDestroyShaderModule; -PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR; -PFN_vkDeviceWaitIdle vkDeviceWaitIdle; -PFN_vkEndCommandBuffer vkEndCommandBuffer; -PFN_vkFreeCommandBuffers vkFreeCommandBuffers; -PFN_vkFreeMemory vkFreeMemory; -PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements; -PFN_vkGetDeviceQueue vkGetDeviceQueue; -PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements; -PFN_vkGetImageSubresourceLayout vkGetImageSubresourceLayout; -PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE; -PFN_vkGetRefreshCycleDurationGOOGLE vkGetRefreshCycleDurationGOOGLE; -PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR; -PFN_vkMapMemory vkMapMemory; -PFN_vkQueuePresentKHR vkQueuePresentKHR; -PFN_vkQueueSubmit vkQueueSubmit; -PFN_vkResetCommandBuffer vkResetCommandBuffer; -PFN_vkResetFences vkResetFences; -PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT; -PFN_vkUnmapMemory vkUnmapMemory; -PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets; -PFN_vkWaitForFences vkWaitForFences; - -#define LOAD_INSTANCE_FUNCTION(instance, function) function = (PFN_##function)vkGetInstanceProcAddr(instance, #function) -#define LOAD_DEVICE_FUNCTION(device, function) function = (PFN_##function)vkGetDeviceProcAddr(device, #function) - -static VkResult load_vulkan_library() { - vulkan_library = NULL; -#if defined(WIN32) - HMODULE library = LoadLibraryA("vulkan-1.dll"); - if (library == NULL) return VK_ERROR_INITIALIZATION_FAILED; - - vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)(void (*)(void))GetProcAddress(library, "vkGetInstanceProcAddr"); -#elif defined(__APPLE__) - void* library = dlopen("libvulkan.dylib", RTLD_NOW | RTLD_LOCAL); - if (library == NULL) { - library = dlopen("libvulkan.1.dylib", RTLD_NOW | RTLD_LOCAL); - } - if (library == NULL && getenv("DYLD_FALLBACK_LIBRARY_PATH") == NULL) { - library = dlopen("/usr/local/lib/libvulkan.dylib", RTLD_NOW | RTLD_LOCAL); - if (library == NULL) { - library = dlopen("/usr/local/lib/libvulkan.1.dylib", RTLD_NOW | RTLD_LOCAL); - } - } - if (library == NULL) { - return VK_ERROR_INITIALIZATION_FAILED; - } - - vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)dlsym(library, "vkGetInstanceProcAddr"); -#else // Assume everything else supports dlopen - void* library = dlopen("libvulkan.so.1", RTLD_NOW | RTLD_LOCAL); - if (library == NULL) library = dlopen("libvulkan.so", RTLD_NOW | RTLD_LOCAL); - if (library == NULL) { - return VK_ERROR_INITIALIZATION_FAILED; - } - vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)dlsym(library, "vkGetInstanceProcAddr"); -#endif - if (vkGetInstanceProcAddr == NULL) { - return VK_ERROR_INITIALIZATION_FAILED; - } - vulkan_library = library; - LOAD_INSTANCE_FUNCTION(NULL, vkEnumerateInstanceExtensionProperties); - LOAD_INSTANCE_FUNCTION(NULL, vkEnumerateInstanceLayerProperties); - LOAD_INSTANCE_FUNCTION(NULL, vkCreateInstance); - - return VK_SUCCESS; -} - -static void unload_vulkan_library() { - if (vulkan_library != NULL) { -#if defined(WIN32) - FreeLibrary((HMODULE)vulkan_library); -#else - dlclose(vulkan_library); -#endif - vulkan_library = NULL; - } -} - -static void load_vulkan_instance_functions(VkInstance instance) { -#if defined(VK_USE_PLATFORM_WIN32_KHR) - LOAD_INSTANCE_FUNCTION(instance, vkCreateWin32SurfaceKHR); -#endif -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - LOAD_INSTANCE_FUNCTION(instance, vkCreateWaylandSurfaceKHR); -#endif -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - LOAD_INSTANCE_FUNCTION(instance, vkCreateAndroidSurfaceKHR); -#endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - LOAD_INSTANCE_FUNCTION(instance, vkCreateXlibSurfaceKHR); -#endif -#if defined(VK_USE_PLATFORM_XCB_KHR) - LOAD_INSTANCE_FUNCTION(instance, vkCreateXcbSurfaceKHR); -#endif -#if defined(VK_USE_PLATFORM_METAL_EXT) - LOAD_INSTANCE_FUNCTION(instance, vkCreateMetalSurfaceEXT); -#endif -#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - LOAD_INSTANCE_FUNCTION(instance, vkCreateDirectFBSurfaceEXT); -#endif -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - LOAD_INSTANCE_FUNCTION(instance, vkCreateScreenSurfaceQNX); -#endif - LOAD_INSTANCE_FUNCTION(instance, vkCreateDebugUtilsMessengerEXT); - LOAD_INSTANCE_FUNCTION(instance, vkCreateDevice); - LOAD_INSTANCE_FUNCTION(instance, vkDestroyDebugUtilsMessengerEXT); - LOAD_INSTANCE_FUNCTION(instance, vkDestroyInstance); - LOAD_INSTANCE_FUNCTION(instance, vkDestroySurfaceKHR); - LOAD_INSTANCE_FUNCTION(instance, vkEnumerateDeviceExtensionProperties); - LOAD_INSTANCE_FUNCTION(instance, vkEnumeratePhysicalDevices); - LOAD_INSTANCE_FUNCTION(instance, vkGetDisplayModePropertiesKHR); - LOAD_INSTANCE_FUNCTION(instance, vkGetDisplayPlaneCapabilitiesKHR); - LOAD_INSTANCE_FUNCTION(instance, vkGetDisplayPlaneSupportedDisplaysKHR); - LOAD_INSTANCE_FUNCTION(instance, vkGetPhysicalDeviceDisplayPlanePropertiesKHR); - LOAD_INSTANCE_FUNCTION(instance, vkGetPhysicalDeviceDisplayPropertiesKHR); - LOAD_INSTANCE_FUNCTION(instance, vkGetPhysicalDeviceFeatures); - LOAD_INSTANCE_FUNCTION(instance, vkGetPhysicalDeviceFormatProperties); - LOAD_INSTANCE_FUNCTION(instance, vkGetPhysicalDeviceMemoryProperties); - LOAD_INSTANCE_FUNCTION(instance, vkGetPhysicalDeviceProperties); - LOAD_INSTANCE_FUNCTION(instance, vkGetPhysicalDeviceQueueFamilyProperties); - LOAD_INSTANCE_FUNCTION(instance, vkGetPhysicalDeviceSurfaceCapabilitiesKHR); - LOAD_INSTANCE_FUNCTION(instance, vkGetPhysicalDeviceSurfaceFormatsKHR); - LOAD_INSTANCE_FUNCTION(instance, vkGetPhysicalDeviceSurfacePresentModesKHR); - LOAD_INSTANCE_FUNCTION(instance, vkGetPhysicalDeviceSurfaceSupportKHR); - LOAD_INSTANCE_FUNCTION(instance, vkGetDeviceProcAddr); - LOAD_INSTANCE_FUNCTION(instance, vkCreateDisplayPlaneSurfaceKHR); -} -static void load_vulkan_device_functions(VkDevice device) { - LOAD_DEVICE_FUNCTION(device, vkAcquireNextImageKHR); - LOAD_DEVICE_FUNCTION(device, vkAllocateCommandBuffers); - LOAD_DEVICE_FUNCTION(device, vkAllocateDescriptorSets); - LOAD_DEVICE_FUNCTION(device, vkAllocateMemory); - LOAD_DEVICE_FUNCTION(device, vkBeginCommandBuffer); - LOAD_DEVICE_FUNCTION(device, vkBindBufferMemory); - LOAD_DEVICE_FUNCTION(device, vkBindImageMemory); - LOAD_DEVICE_FUNCTION(device, vkCmdBeginDebugUtilsLabelEXT); - LOAD_DEVICE_FUNCTION(device, vkCmdBeginRenderPass); - LOAD_DEVICE_FUNCTION(device, vkCmdBindDescriptorSets); - LOAD_DEVICE_FUNCTION(device, vkCmdBindPipeline); - LOAD_DEVICE_FUNCTION(device, vkCmdCopyBufferToImage); - LOAD_DEVICE_FUNCTION(device, vkCmdDraw); - LOAD_DEVICE_FUNCTION(device, vkCmdEndDebugUtilsLabelEXT); - LOAD_DEVICE_FUNCTION(device, vkCmdEndRenderPass); - LOAD_DEVICE_FUNCTION(device, vkCmdPipelineBarrier); - LOAD_DEVICE_FUNCTION(device, vkCmdSetScissor); - LOAD_DEVICE_FUNCTION(device, vkCmdSetViewport); - LOAD_DEVICE_FUNCTION(device, vkCreateBuffer); - LOAD_DEVICE_FUNCTION(device, vkCreateCommandPool); - LOAD_DEVICE_FUNCTION(device, vkCreateDescriptorPool); - LOAD_DEVICE_FUNCTION(device, vkCreateDescriptorSetLayout); - LOAD_DEVICE_FUNCTION(device, vkCreateFence); - LOAD_DEVICE_FUNCTION(device, vkCreateFramebuffer); - LOAD_DEVICE_FUNCTION(device, vkCreateGraphicsPipelines); - LOAD_DEVICE_FUNCTION(device, vkCreateImage); - LOAD_DEVICE_FUNCTION(device, vkCreateImageView); - LOAD_DEVICE_FUNCTION(device, vkCreatePipelineCache); - LOAD_DEVICE_FUNCTION(device, vkCreatePipelineLayout); - LOAD_DEVICE_FUNCTION(device, vkCreateRenderPass); - LOAD_DEVICE_FUNCTION(device, vkCreateSampler); - LOAD_DEVICE_FUNCTION(device, vkCreateSemaphore); - LOAD_DEVICE_FUNCTION(device, vkCreateShaderModule); - LOAD_DEVICE_FUNCTION(device, vkCreateSwapchainKHR); - LOAD_DEVICE_FUNCTION(device, vkDestroyBuffer); - LOAD_DEVICE_FUNCTION(device, vkDestroyCommandPool); - LOAD_DEVICE_FUNCTION(device, vkDestroyDescriptorPool); - LOAD_DEVICE_FUNCTION(device, vkDestroyDescriptorSetLayout); - LOAD_DEVICE_FUNCTION(device, vkDestroyDevice); - LOAD_DEVICE_FUNCTION(device, vkDestroyFence); - LOAD_DEVICE_FUNCTION(device, vkDestroyFramebuffer); - LOAD_DEVICE_FUNCTION(device, vkDestroyImage); - LOAD_DEVICE_FUNCTION(device, vkDestroyImageView); - LOAD_DEVICE_FUNCTION(device, vkDestroyPipeline); - LOAD_DEVICE_FUNCTION(device, vkDestroyPipelineCache); - LOAD_DEVICE_FUNCTION(device, vkDestroyPipelineLayout); - LOAD_DEVICE_FUNCTION(device, vkDestroyRenderPass); - LOAD_DEVICE_FUNCTION(device, vkDestroySampler); - LOAD_DEVICE_FUNCTION(device, vkDestroySemaphore); - LOAD_DEVICE_FUNCTION(device, vkDestroyShaderModule); - LOAD_DEVICE_FUNCTION(device, vkDestroySwapchainKHR); - LOAD_DEVICE_FUNCTION(device, vkDeviceWaitIdle); - LOAD_DEVICE_FUNCTION(device, vkEndCommandBuffer); - LOAD_DEVICE_FUNCTION(device, vkFreeCommandBuffers); - LOAD_DEVICE_FUNCTION(device, vkFreeMemory); - LOAD_DEVICE_FUNCTION(device, vkGetBufferMemoryRequirements); - LOAD_DEVICE_FUNCTION(device, vkGetDeviceProcAddr); - LOAD_DEVICE_FUNCTION(device, vkGetDeviceQueue); - LOAD_DEVICE_FUNCTION(device, vkGetImageMemoryRequirements); - LOAD_DEVICE_FUNCTION(device, vkGetImageSubresourceLayout); - LOAD_DEVICE_FUNCTION(device, vkGetPastPresentationTimingGOOGLE); - LOAD_DEVICE_FUNCTION(device, vkGetRefreshCycleDurationGOOGLE); - LOAD_DEVICE_FUNCTION(device, vkGetSwapchainImagesKHR); - LOAD_DEVICE_FUNCTION(device, vkMapMemory); - LOAD_DEVICE_FUNCTION(device, vkQueuePresentKHR); - LOAD_DEVICE_FUNCTION(device, vkQueueSubmit); - LOAD_DEVICE_FUNCTION(device, vkResetCommandBuffer); - LOAD_DEVICE_FUNCTION(device, vkResetFences); - LOAD_DEVICE_FUNCTION(device, vkSetDebugUtilsObjectNameEXT); - LOAD_DEVICE_FUNCTION(device, vkUnmapMemory); - LOAD_DEVICE_FUNCTION(device, vkUpdateDescriptorSets); - LOAD_DEVICE_FUNCTION(device, vkWaitForFences); -} - -#undef LOAD_INSTANCE_FUNCTION -#undef LOAD_DEVICE_FUNCTION diff --git a/tools/Vulkan-Tools/cube/fuchsia/flatland_view.cpp b/tools/Vulkan-Tools/cube/fuchsia/flatland_view.cpp deleted file mode 100644 index 029c07d3..00000000 --- a/tools/Vulkan-Tools/cube/fuchsia/flatland_view.cpp +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright (c) 2025 The Fuchsia Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "flatland_view.h" - -#include <fidl/fuchsia.ui.app/cpp/fidl.h> -#include <fidl/fuchsia.ui.composition/cpp/fidl.h> -#include <fidl/fuchsia.ui.views/cpp/fidl.h> -#include <lib/component/incoming/cpp/protocol.h> -#include <lib/component/outgoing/cpp/outgoing_directory.h> -#include <lib/syslog/cpp/macros.h> -#include <lib/syslog/global.h> -#include <lib/ui/scenic/cpp/view_creation_tokens.h> -#include <lib/ui/scenic/cpp/view_identity.h> - -#include <cinttypes> - -namespace { - -const char* const kTag = "FlatlandView"; - -const fuchsia_ui_composition::TransformId kRootTransform = {1}; -const fuchsia_ui_composition::ContentId kViewport = {1}; - -} // namespace - -// static -std::unique_ptr<FlatlandView> FlatlandView::Create(fidl::UnownedClientEnd<fuchsia_io::Directory> service_directory, - fuchsia_ui_views::ViewCreationToken view_creation_token, - ResizeCallback resize_callback, async_dispatcher_t* dispatcher) { - ZX_DEBUG_ASSERT(dispatcher != nullptr); - auto view = std::make_unique<FlatlandView>(std::move(resize_callback), dispatcher); - if (!view) return nullptr; - if (!view->Init(service_directory, std::move(view_creation_token))) return nullptr; - return view; -} - -FlatlandView::FlatlandView(ResizeCallback resize_callback, async_dispatcher_t* dispatcher) - : resize_callback_(std::move(resize_callback)), dispatcher_(dispatcher) { - ZX_DEBUG_ASSERT(dispatcher != nullptr); -} - -bool FlatlandView::Init(fidl::UnownedClientEnd<fuchsia_io::Directory> service_directory, - fuchsia_ui_views::ViewCreationToken view_creation_token) { - zx::result<fidl::ClientEnd<fuchsia_ui_composition::Flatland>> connect_result = - component::ConnectAt<fuchsia_ui_composition::Flatland>(service_directory); - if (connect_result.is_error()) { - FX_LOGS(ERROR) << "Failed to connect to Flatland: " << connect_result.status_string(); - return false; - } - fidl::ClientEnd<fuchsia_ui_composition::Flatland> flatland_client = std::move(connect_result).value(); - flatland_.Bind(std::move(flatland_client), dispatcher_, /*event_handler=*/this); - fit::result<fidl::OneWayError> set_debug_name_result = flatland_->SetDebugName({{.name = kTag}}); - if (set_debug_name_result.is_error()) { - FX_LOGS(ERROR) << "Failed to set debug name: " << set_debug_name_result.error_value().FormatDescription(); - } - - fit::result<fidl::OneWayError> create_transform_result = flatland_->CreateTransform(kRootTransform); - if (create_transform_result.is_error()) { - FX_LOGS(ERROR) << "Failed to call CreateTransform: " << create_transform_result.error_value().FormatDescription(); - return false; - } - - fit::result<fidl::OneWayError> set_root_transform_result = flatland_->SetRootTransform(kRootTransform); - if (set_root_transform_result.is_error()) { - FX_LOGS(ERROR) << "Failed to call SetRootTransform: " << set_root_transform_result.error_value().FormatDescription(); - return false; - } - - auto [parent_viewport_watcher_client, parent_viewport_watcher_server] = - fidl::Endpoints<fuchsia_ui_composition::ParentViewportWatcher>::Create(); - fit::result<fidl::OneWayError> create_view2_result = flatland_->CreateView2({{ - .token = std::move(view_creation_token), - .view_identity = scenic::cpp::NewViewIdentityOnCreation(), - .protocols = {}, - .parent_viewport_watcher = std::move(parent_viewport_watcher_server), - }}); - if (create_view2_result.is_error()) { - FX_LOGS(ERROR) << "Failed to call CreateView2: " << set_root_transform_result.error_value().FormatDescription(); - return false; - } - - parent_viewport_watcher_.Bind(std::move(parent_viewport_watcher_client), dispatcher_); - parent_viewport_watcher_->GetLayout().Then( - [this](fidl::Result<fuchsia_ui_composition::ParentViewportWatcher::GetLayout>& result) { - if (result.is_error()) { - FX_LOGS(ERROR) << "GetLayout() failed: " << result.error_value().FormatDescription(); - return; - } - OnGetLayout(std::move(result.value().info())); - }); - - zx::channel::create(0, &viewport_creation_token_.value(), &child_view_creation_token_.value()); - - return true; -} - -void FlatlandView::OnGetLayout(fuchsia_ui_composition::LayoutInfo info) { - ZX_DEBUG_ASSERT(info.logical_size().has_value()); - const fuchsia_math::SizeU& logical_size = info.logical_size().value(); - resize_callback_(logical_size.width(), logical_size.height()); - - fuchsia_ui_composition::ViewportProperties properties = {{.logical_size = logical_size}}; - if (viewport_creation_token_.value().is_valid()) { - // The first time that we receive layout information, create a viewport using the token that was stashed during Init(). - // External code will attach a view to this viewport via the token obtained from TakeChildViewCreationToken(). - auto [child_view_watcher_client, child_view_watcher_server] = - fidl::Endpoints<fuchsia_ui_composition::ChildViewWatcher>::Create(); - fit::result<fidl::OneWayError> create_viewport_result = flatland_->CreateViewport({{ - .viewport_id = kViewport, - .token = std::move(viewport_creation_token_), - .properties = std::move(properties), - .child_view_watcher = std::move(child_view_watcher_server), - }}); - if (create_viewport_result.is_error()) { - FX_LOGS(ERROR) << "Failed to call CreateViewport(): " << create_viewport_result.error_value().FormatDescription(); - return; - } - - fit::result<fidl::OneWayError> set_content_result = flatland_->SetContent({{ - .transform_id = kRootTransform, - .content_id = kViewport, - }}); - if (set_content_result.is_error()) { - FX_LOGS(ERROR) << "Failed to call SetContent(): " << set_content_result.error_value().FormatDescription(); - return; - } - } else { - auto set_viewport_properties_result = flatland_->SetViewportProperties({{ - .viewport_id = kViewport, - .properties = std::move(properties), - }}); - if (set_viewport_properties_result.is_error()) { - FX_LOGS(ERROR) << "Failed to call SetViewportProperties(): " - << set_viewport_properties_result.error_value().FormatDescription(); - return; - } - } - - Present(); - parent_viewport_watcher_->GetLayout().Then( - [this](fidl::Result<fuchsia_ui_composition::ParentViewportWatcher::GetLayout>& result) { - if (result.is_error()) { - FX_LOGS(ERROR) << "GetLayout() failed: " << result.error_value().FormatDescription(); - return; - } - OnGetLayout(std::move(result.value().info())); - }); -} - -void FlatlandView::OnError(fidl::Event<fuchsia_ui_composition::Flatland::OnError>& event) { - FX_LOGF(ERROR, kTag, "OnFlatlandError: %" PRIu32, static_cast<uint32_t>(event.error())); -} - -void FlatlandView::Present() { - if (present_credits_ == 0) { - pending_present_ = true; - return; - } - --present_credits_; - fuchsia_ui_composition::PresentArgs present_args = {{ - .requested_presentation_time = 0, - .acquire_fences = {}, - .release_fences = {}, - .unsquashable = false, - }}; - fit::result<fidl::OneWayError> present_result = flatland_->Present(std::move(present_args)); - if (present_result.is_error()) { - FX_LOGS(ERROR) << "Failed to call Present(): " << present_result.error_value().FormatDescription(); - } -} - -void FlatlandView::OnFramePresented(fidl::Event<fuchsia_ui_composition::Flatland::OnFramePresented>& event) {} - -void FlatlandView::OnNextFrameBegin(fidl::Event<fuchsia_ui_composition::Flatland::OnNextFrameBegin>& event) { - present_credits_ += event.values().additional_present_credits().value_or(0); - if (present_credits_ > 0 && pending_present_) { - Present(); - pending_present_ = false; - } -} - -FlatlandViewProviderService::FlatlandViewProviderService(CreateView2Callback create_view_callback, async_dispatcher_t* dispatcher) - : create_view_callback_(std::move(create_view_callback)), dispatcher_(dispatcher) { - ZX_DEBUG_ASSERT(dispatcher != nullptr); -} - -void FlatlandViewProviderService::CreateViewWithViewRef(CreateViewWithViewRefRequest& request, - CreateViewWithViewRefCompleter::Sync& completer) { - FX_NOTIMPLEMENTED() << "Only Flatland is supported. This is a Gfx ViewProvider method."; -} - -void FlatlandViewProviderService::CreateView2(CreateView2Request& request, CreateView2Completer::Sync& completer) { - create_view_callback_(std::move(request.args())); -} - -void FlatlandViewProviderService::HandleViewProviderRequest(fidl::ServerEnd<fuchsia_ui_app::ViewProvider> server_end) { - bindings_.AddBinding(dispatcher_, std::move(server_end), this, fidl::kIgnoreBindingClosure); -} diff --git a/tools/Vulkan-Tools/cube/fuchsia/flatland_view.h b/tools/Vulkan-Tools/cube/fuchsia/flatland_view.h deleted file mode 100644 index 01a8c6f9..00000000 --- a/tools/Vulkan-Tools/cube/fuchsia/flatland_view.h +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) 2025 The Fuchsia Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef FUCHSIA_FLATLAND_VIEW_H_ -#define FUCHSIA_FLATLAND_VIEW_H_ - -#include <fidl/fuchsia.io/cpp/fidl.h> -#include <fidl/fuchsia.ui.app/cpp/fidl.h> -#include <fidl/fuchsia.ui.composition/cpp/fidl.h> -#include <fidl/fuchsia.ui.views/cpp/fidl.h> -#include <lib/fit/function.h> -#include <lib/async/dispatcher.h> -#include <lib/syslog/cpp/macros.h> - -#include <cstdint> -#include <utility> - -#include <memory> - -// This class provides a convenient wrapper around the scenic fidl apis needed to get a Flatland -// View. Only SDK available constructs should be used so that this code may be leveraged by Vulkan -// applications built with the SDK. -class FlatlandView : public fidl::AsyncEventHandler<fuchsia_ui_composition::Flatland> { - public: - using ResizeCallback = fit::function<void(uint32_t width, uint32_t height)>; - - // Creates and initializes a `FlatlandView` instance. - // - // `dispatcher` must be non-null. - static std::unique_ptr<FlatlandView> Create(fidl::UnownedClientEnd<fuchsia_io::Directory> service_directory, - fuchsia_ui_views::ViewCreationToken view_creation_token, - ResizeCallback resize_callback, async_dispatcher_t* dispatcher); - - // Production code must use the `Create()` factory method. - // - // `dispatcher` must be non-null. - explicit FlatlandView(ResizeCallback resize_callback, async_dispatcher_t* dispatcher); - - fuchsia_ui_views::ViewCreationToken TakeChildViewCreationToken() { - FX_DCHECK(child_view_creation_token_.value().is_valid()); - return std::move(child_view_creation_token_); - } - - bool Init(fidl::UnownedClientEnd<fuchsia_io::Directory> service_directory, - fuchsia_ui_views::ViewCreationToken view_creation_token); - - private: - void OnNextFrameBegin(fidl::Event<fuchsia_ui_composition::Flatland::OnNextFrameBegin>& event) override; - void OnFramePresented(fidl::Event<fuchsia_ui_composition::Flatland::OnFramePresented>& event) override; - void OnError(fidl::Event<fuchsia_ui_composition::Flatland::OnError>& event) override; - - void OnGetLayout(fuchsia_ui_composition::LayoutInfo info); - void OnFlatlandError(fuchsia_ui_composition::FlatlandError error); - void Present(); - - fidl::SharedClient<fuchsia_ui_composition::Flatland> flatland_; - fidl::SharedClient<fuchsia_ui_composition::ParentViewportWatcher> parent_viewport_watcher_; - - fuchsia_ui_views::ViewportCreationToken viewport_creation_token_; - fuchsia_ui_views::ViewCreationToken child_view_creation_token_; - ResizeCallback resize_callback_; - - int64_t present_credits_ = 1; - bool pending_present_ = false; - - async_dispatcher_t* const dispatcher_; - - friend class FlatlandViewTest; -}; - -class FlatlandViewProviderService : public fidl::Server<fuchsia_ui_app::ViewProvider> { - public: - using CreateView2Callback = fit::function<void(fuchsia_ui_app::CreateView2Args args)>; - - // `dispatcher` must be non-null. - explicit FlatlandViewProviderService(CreateView2Callback create_view_callback, async_dispatcher_t* dispatcher); - - // fuchsia::ui::app::ViewProvider methods. - void CreateViewWithViewRef(CreateViewWithViewRefRequest& request, CreateViewWithViewRefCompleter::Sync& completer) override; - void CreateView2(CreateView2Request& request, CreateView2Completer::Sync& completer) override; - - void HandleViewProviderRequest(fidl::ServerEnd<fuchsia_ui_app::ViewProvider> server_end); - - private: - CreateView2Callback create_view_callback_; - fidl::ServerBindingGroup<fuchsia_ui_app::ViewProvider> bindings_; - - async_dispatcher_t* const dispatcher_; -}; - -#endif // FUCHSIA_FLATLAND_VIEW_H_ diff --git a/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-fb-protected.cml b/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-fb-protected.cml deleted file mode 100644 index 43d51a6e..00000000 --- a/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-fb-protected.cml +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2025 The Fuchsia Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -{ - include: [ - "//src/lib/vulkan/swapchain/VkLayer_image_pipe_swapchain_fb.shard.cml", - "sys/testing/elf_test_runner.shard.cml", - ], - program: { - binary: "bin/vkcube", - args: [ - "--protected_output", - "--wsi", - "fuchsia_display", - ], - }, -} diff --git a/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-fb.cml b/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-fb.cml deleted file mode 100644 index eaa78aae..00000000 --- a/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-fb.cml +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2025 The Fuchsia Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -{ - include: [ - "//src/lib/vulkan/swapchain/VkLayer_image_pipe_swapchain_fb.shard.cml", - "sys/testing/elf_test_runner.shard.cml", - ], - program: { - binary: "bin/vkcube", - args: [ - "--wsi", - "fuchsia_display", - ], - }, -} diff --git a/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-scenic-protected.cml b/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-scenic-protected.cml deleted file mode 100644 index 3138b605..00000000 --- a/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-scenic-protected.cml +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2025 The Fuchsia Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -{ - include: [ "//src/lib/vulkan/swapchain/VkLayer_image_pipe_swapchain.shard.cml" ], - program: { - runner: "elf", - binary: "bin/vkcube", - args: [ - "--protected_output", - "--wsi", - "fuchsia_scenic", - ], - }, - capabilities: [ - { - protocol: [ "fuchsia.ui.app.ViewProvider" ], - }, - ], - use: [ - { - protocol: [ - "fuchsia.ui.composition.Allocator", - "fuchsia.ui.composition.Flatland", - ], - }, - ], - expose: [ - { - protocol: [ "fuchsia.ui.app.ViewProvider" ], - from: "self", - to: "parent", - }, - ], -} diff --git a/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-scenic.cml b/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-scenic.cml deleted file mode 100644 index cf940b5b..00000000 --- a/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-scenic.cml +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2025 The Fuchsia Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -{ - include: [ "//src/lib/vulkan/swapchain/VkLayer_image_pipe_swapchain.shard.cml" ], - program: { - runner: "elf", - binary: "bin/vkcube", - args: [ - "--wsi", - "fuchsia_scenic", - ], - }, - capabilities: [ - { - protocol: [ "fuchsia.ui.app.ViewProvider" ], - }, - ], - expose: [ - { - protocol: [ "fuchsia.ui.app.ViewProvider" ], - from: "self", - to: "parent", - }, - ], -} diff --git a/tools/Vulkan-Tools/cube/gettime.h b/tools/Vulkan-Tools/cube/gettime.h deleted file mode 100644 index 0a697b42..00000000 --- a/tools/Vulkan-Tools/cube/gettime.h +++ /dev/null @@ -1,68 +0,0 @@ -/************************************************************************** - * - * Copyright 2014, 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Ported from drawElements Utility Library (Google, Inc.) - * Port done by: Ian Elliott <ianelliott@google.com> - **************************************************************************/ - -#include <time.h> -#include <assert.h> -#include <vulkan/vk_platform.h> - -#if defined(_WIN32) - -#include <windows.h> - -#elif defined(__unix__) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__ANDROID__) || defined(__EPOC32__) || defined(__QNX__) || defined(__APPLE__) - -#include <time.h> - -#endif - -uint64_t getTimeInNanoseconds(void) { - const long long ns_in_us = 1000; - const long long ns_in_ms = 1000 * ns_in_us; - const long long ns_in_s = 1000 * ns_in_ms; -#if defined(_WIN32) - LARGE_INTEGER freq; - LARGE_INTEGER count; - QueryPerformanceCounter(&count); - QueryPerformanceFrequency(&freq); - assert(freq.LowPart != 0 || freq.HighPart != 0); - - if (count.QuadPart < MAXLONGLONG / ns_in_s) { - assert(freq.QuadPart != 0); - return count.QuadPart * ns_in_s / freq.QuadPart; - } else { - assert(freq.QuadPart >= ns_in_s); - return count.QuadPart / (freq.QuadPart / ns_in_s); - } - -#elif defined(__unix__) || defined(__linux) || defined(__linux__) || defined(__ANDROID__) || defined(__QNX__) || defined(__APPLE__) - struct timespec currTime; - clock_gettime(CLOCK_MONOTONIC, &currTime); - return (uint64_t)currTime.tv_sec * ns_in_s + (uint64_t)currTime.tv_nsec; - -#elif defined(__EPOC32__) - struct timespec currTime; - /* Symbian supports only realtime clock for clock_gettime. */ - clock_gettime(CLOCK_REALTIME, &currTime); - return (uint64_t)currTime.tv_sec * ns_in_s + (uint64_t)currTime.tv_nsec; - -#else -#error getTimeInNanoseconds Not implemented for target OS -#endif -} diff --git a/tools/Vulkan-Tools/cube/linmath.h b/tools/Vulkan-Tools/cube/linmath.h deleted file mode 100644 index 6df1d7ee..00000000 --- a/tools/Vulkan-Tools/cube/linmath.h +++ /dev/null @@ -1,608 +0,0 @@ -#ifndef LINMATH_H -#define LINMATH_H - -#include <string.h> -#include <math.h> -#include <string.h> - -#ifdef LINMATH_NO_INLINE -#define LINMATH_H_FUNC static -#else -#define LINMATH_H_FUNC static inline -#endif - -#define degreesToRadians(angleDegrees) (angleDegrees * M_PI / 180.0) - -#define LINMATH_H_DEFINE_VEC(n) \ -typedef float vec##n[n]; \ -LINMATH_H_FUNC void vec##n##_add(vec##n r, vec##n const a, vec##n const b) \ -{ \ - int i; \ - for(i=0; i<n; ++i) \ - r[i] = a[i] + b[i]; \ -} \ -LINMATH_H_FUNC void vec##n##_sub(vec##n r, vec##n const a, vec##n const b) \ -{ \ - int i; \ - for(i=0; i<n; ++i) \ - r[i] = a[i] - b[i]; \ -} \ -LINMATH_H_FUNC void vec##n##_scale(vec##n r, vec##n const v, float const s) \ -{ \ - int i; \ - for(i=0; i<n; ++i) \ - r[i] = v[i] * s; \ -} \ -LINMATH_H_FUNC float vec##n##_mul_inner(vec##n const a, vec##n const b) \ -{ \ - float p = 0.f; \ - int i; \ - for(i=0; i<n; ++i) \ - p += b[i]*a[i]; \ - return p; \ -} \ -LINMATH_H_FUNC float vec##n##_len(vec##n const v) \ -{ \ - return sqrtf(vec##n##_mul_inner(v,v)); \ -} \ -LINMATH_H_FUNC void vec##n##_norm(vec##n r, vec##n const v) \ -{ \ - float k = 1.f / vec##n##_len(v); \ - vec##n##_scale(r, v, k); \ -} \ -LINMATH_H_FUNC void vec##n##_min(vec##n r, vec##n const a, vec##n const b) \ -{ \ - int i; \ - for(i=0; i<n; ++i) \ - r[i] = a[i]<b[i] ? a[i] : b[i]; \ -} \ -LINMATH_H_FUNC void vec##n##_max(vec##n r, vec##n const a, vec##n const b) \ -{ \ - int i; \ - for(i=0; i<n; ++i) \ - r[i] = a[i]>b[i] ? a[i] : b[i]; \ -} \ -LINMATH_H_FUNC void vec##n##_dup(vec##n r, vec##n const src) \ -{ \ - int i; \ - for(i=0; i<n; ++i) \ - r[i] = src[i]; \ -} - -LINMATH_H_DEFINE_VEC(2) -LINMATH_H_DEFINE_VEC(3) -LINMATH_H_DEFINE_VEC(4) - -LINMATH_H_FUNC void vec3_mul_cross(vec3 r, vec3 const a, vec3 const b) -{ - r[0] = a[1]*b[2] - a[2]*b[1]; - r[1] = a[2]*b[0] - a[0]*b[2]; - r[2] = a[0]*b[1] - a[1]*b[0]; -} - -LINMATH_H_FUNC void vec3_reflect(vec3 r, vec3 const v, vec3 const n) -{ - float p = 2.f * vec3_mul_inner(v, n); - int i; - for(i=0;i<3;++i) - r[i] = v[i] - p*n[i]; -} - -LINMATH_H_FUNC void vec4_mul_cross(vec4 r, vec4 const a, vec4 const b) -{ - r[0] = a[1]*b[2] - a[2]*b[1]; - r[1] = a[2]*b[0] - a[0]*b[2]; - r[2] = a[0]*b[1] - a[1]*b[0]; - r[3] = 1.f; -} - -LINMATH_H_FUNC void vec4_reflect(vec4 r, vec4 const v, vec4 const n) -{ - float p = 2.f*vec4_mul_inner(v, n); - int i; - for(i=0;i<4;++i) - r[i] = v[i] - p*n[i]; -} - -typedef vec4 mat4x4[4]; -LINMATH_H_FUNC void mat4x4_identity(mat4x4 M) -{ - int i, j; - for(i=0; i<4; ++i) - for(j=0; j<4; ++j) - M[i][j] = i==j ? 1.f : 0.f; -} -LINMATH_H_FUNC void mat4x4_dup(mat4x4 M, mat4x4 const N) -{ - int i; - for(i=0; i<4; ++i) - vec4_dup(M[i], N[i]); -} -LINMATH_H_FUNC void mat4x4_row(vec4 r, mat4x4 const M, int i) -{ - int k; - for(k=0; k<4; ++k) - r[k] = M[k][i]; -} -LINMATH_H_FUNC void mat4x4_col(vec4 r, mat4x4 const M, int i) -{ - int k; - for(k=0; k<4; ++k) - r[k] = M[i][k]; -} -LINMATH_H_FUNC void mat4x4_transpose(mat4x4 M, mat4x4 const N) -{ - // Note: if M and N are the same, the user has to - // explicitly make a copy of M and set it to N. - int i, j; - for(j=0; j<4; ++j) - for(i=0; i<4; ++i) - M[i][j] = N[j][i]; -} -LINMATH_H_FUNC void mat4x4_add(mat4x4 M, mat4x4 const a, mat4x4 const b) -{ - int i; - for(i=0; i<4; ++i) - vec4_add(M[i], a[i], b[i]); -} -LINMATH_H_FUNC void mat4x4_sub(mat4x4 M, mat4x4 const a, mat4x4 const b) -{ - int i; - for(i=0; i<4; ++i) - vec4_sub(M[i], a[i], b[i]); -} -LINMATH_H_FUNC void mat4x4_scale(mat4x4 M, mat4x4 const a, float k) -{ - int i; - for(i=0; i<4; ++i) - vec4_scale(M[i], a[i], k); -} -LINMATH_H_FUNC void mat4x4_scale_aniso(mat4x4 M, mat4x4 const a, float x, float y, float z) -{ - vec4_scale(M[0], a[0], x); - vec4_scale(M[1], a[1], y); - vec4_scale(M[2], a[2], z); - vec4_dup(M[3], a[3]); -} -LINMATH_H_FUNC void mat4x4_mul(mat4x4 M, mat4x4 const a, mat4x4 const b) -{ - mat4x4 temp; - int k, r, c; - for(c=0; c<4; ++c) for(r=0; r<4; ++r) { - temp[c][r] = 0.f; - for(k=0; k<4; ++k) - temp[c][r] += a[k][r] * b[c][k]; - } - mat4x4_dup(M, temp); -} -LINMATH_H_FUNC void mat4x4_mul_vec4(vec4 r, mat4x4 const M, vec4 const v) -{ - int i, j; - for(j=0; j<4; ++j) { - r[j] = 0.f; - for(i=0; i<4; ++i) - r[j] += M[i][j] * v[i]; - } -} -LINMATH_H_FUNC void mat4x4_translate(mat4x4 T, float x, float y, float z) -{ - mat4x4_identity(T); - T[3][0] = x; - T[3][1] = y; - T[3][2] = z; -} -LINMATH_H_FUNC void mat4x4_translate_in_place(mat4x4 M, float x, float y, float z) -{ - vec4 t = {x, y, z, 0}; - vec4 r; - int i; - for (i = 0; i < 4; ++i) { - mat4x4_row(r, M, i); - M[3][i] += vec4_mul_inner(r, t); - } -} -LINMATH_H_FUNC void mat4x4_from_vec3_mul_outer(mat4x4 M, vec3 const a, vec3 const b) -{ - int i, j; - for(i=0; i<4; ++i) for(j=0; j<4; ++j) - M[i][j] = i<3 && j<3 ? a[i] * b[j] : 0.f; -} -LINMATH_H_FUNC void mat4x4_rotate(mat4x4 R, mat4x4 const M, float x, float y, float z, float angle) -{ - float s = sinf(angle); - float c = cosf(angle); - vec3 u = {x, y, z}; - - if(vec3_len(u) > 1e-4) { - vec3_norm(u, u); - mat4x4 T; - mat4x4_from_vec3_mul_outer(T, u, u); - - mat4x4 S = { - { 0, u[2], -u[1], 0}, - {-u[2], 0, u[0], 0}, - { u[1], -u[0], 0, 0}, - { 0, 0, 0, 0} - }; - mat4x4_scale(S, S, s); - - mat4x4 C; - mat4x4_identity(C); - mat4x4_sub(C, C, T); - - mat4x4_scale(C, C, c); - - mat4x4_add(T, T, C); - mat4x4_add(T, T, S); - - T[3][3] = 1.f; - mat4x4_mul(R, M, T); - } else { - mat4x4_dup(R, M); - } -} -LINMATH_H_FUNC void mat4x4_rotate_X(mat4x4 Q, mat4x4 const M, float angle) -{ - float s = sinf(angle); - float c = cosf(angle); - mat4x4 R = { - {1.f, 0.f, 0.f, 0.f}, - {0.f, c, s, 0.f}, - {0.f, -s, c, 0.f}, - {0.f, 0.f, 0.f, 1.f} - }; - mat4x4_mul(Q, M, R); -} -LINMATH_H_FUNC void mat4x4_rotate_Y(mat4x4 Q, mat4x4 const M, float angle) -{ - float s = sinf(angle); - float c = cosf(angle); - mat4x4 R = { - { c, 0.f, -s, 0.f}, - { 0.f, 1.f, 0.f, 0.f}, - { s, 0.f, c, 0.f}, - { 0.f, 0.f, 0.f, 1.f} - }; - mat4x4_mul(Q, M, R); -} -LINMATH_H_FUNC void mat4x4_rotate_Z(mat4x4 Q, mat4x4 const M, float angle) -{ - float s = sinf(angle); - float c = cosf(angle); - mat4x4 R = { - { c, s, 0.f, 0.f}, - { -s, c, 0.f, 0.f}, - { 0.f, 0.f, 1.f, 0.f}, - { 0.f, 0.f, 0.f, 1.f} - }; - mat4x4_mul(Q, M, R); -} -LINMATH_H_FUNC void mat4x4_invert(mat4x4 T, mat4x4 const M) -{ - float s[6]; - float c[6]; - s[0] = M[0][0]*M[1][1] - M[1][0]*M[0][1]; - s[1] = M[0][0]*M[1][2] - M[1][0]*M[0][2]; - s[2] = M[0][0]*M[1][3] - M[1][0]*M[0][3]; - s[3] = M[0][1]*M[1][2] - M[1][1]*M[0][2]; - s[4] = M[0][1]*M[1][3] - M[1][1]*M[0][3]; - s[5] = M[0][2]*M[1][3] - M[1][2]*M[0][3]; - - c[0] = M[2][0]*M[3][1] - M[3][0]*M[2][1]; - c[1] = M[2][0]*M[3][2] - M[3][0]*M[2][2]; - c[2] = M[2][0]*M[3][3] - M[3][0]*M[2][3]; - c[3] = M[2][1]*M[3][2] - M[3][1]*M[2][2]; - c[4] = M[2][1]*M[3][3] - M[3][1]*M[2][3]; - c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3]; - - /* Assumes it is invertible */ - float idet = 1.0f/( s[0]*c[5]-s[1]*c[4]+s[2]*c[3]+s[3]*c[2]-s[4]*c[1]+s[5]*c[0] ); - - T[0][0] = ( M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet; - T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet; - T[0][2] = ( M[3][1] * s[5] - M[3][2] * s[4] + M[3][3] * s[3]) * idet; - T[0][3] = (-M[2][1] * s[5] + M[2][2] * s[4] - M[2][3] * s[3]) * idet; - - T[1][0] = (-M[1][0] * c[5] + M[1][2] * c[2] - M[1][3] * c[1]) * idet; - T[1][1] = ( M[0][0] * c[5] - M[0][2] * c[2] + M[0][3] * c[1]) * idet; - T[1][2] = (-M[3][0] * s[5] + M[3][2] * s[2] - M[3][3] * s[1]) * idet; - T[1][3] = ( M[2][0] * s[5] - M[2][2] * s[2] + M[2][3] * s[1]) * idet; - - T[2][0] = ( M[1][0] * c[4] - M[1][1] * c[2] + M[1][3] * c[0]) * idet; - T[2][1] = (-M[0][0] * c[4] + M[0][1] * c[2] - M[0][3] * c[0]) * idet; - T[2][2] = ( M[3][0] * s[4] - M[3][1] * s[2] + M[3][3] * s[0]) * idet; - T[2][3] = (-M[2][0] * s[4] + M[2][1] * s[2] - M[2][3] * s[0]) * idet; - - T[3][0] = (-M[1][0] * c[3] + M[1][1] * c[1] - M[1][2] * c[0]) * idet; - T[3][1] = ( M[0][0] * c[3] - M[0][1] * c[1] + M[0][2] * c[0]) * idet; - T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet; - T[3][3] = ( M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet; -} -LINMATH_H_FUNC void mat4x4_orthonormalize(mat4x4 R, mat4x4 const M) -{ - mat4x4_dup(R, M); - float s = 1.f; - vec3 h; - - vec3_norm(R[2], R[2]); - - s = vec3_mul_inner(R[1], R[2]); - vec3_scale(h, R[2], s); - vec3_sub(R[1], R[1], h); - vec3_norm(R[1], R[1]); - - s = vec3_mul_inner(R[0], R[2]); - vec3_scale(h, R[2], s); - vec3_sub(R[0], R[0], h); - - s = vec3_mul_inner(R[0], R[1]); - vec3_scale(h, R[1], s); - vec3_sub(R[0], R[0], h); - vec3_norm(R[0], R[0]); -} - -LINMATH_H_FUNC void mat4x4_frustum(mat4x4 M, float l, float r, float b, float t, float n, float f) -{ - M[0][0] = 2.f*n/(r-l); - M[0][1] = M[0][2] = M[0][3] = 0.f; - - M[1][1] = 2.f*n/(t-b); - M[1][0] = M[1][2] = M[1][3] = 0.f; - - M[2][0] = (r+l)/(r-l); - M[2][1] = (t+b)/(t-b); - M[2][2] = -(f+n)/(f-n); - M[2][3] = -1.f; - - M[3][2] = -2.f*(f*n)/(f-n); - M[3][0] = M[3][1] = M[3][3] = 0.f; -} -LINMATH_H_FUNC void mat4x4_ortho(mat4x4 M, float l, float r, float b, float t, float n, float f) -{ - M[0][0] = 2.f/(r-l); - M[0][1] = M[0][2] = M[0][3] = 0.f; - - M[1][1] = 2.f/(t-b); - M[1][0] = M[1][2] = M[1][3] = 0.f; - - M[2][2] = -2.f/(f-n); - M[2][0] = M[2][1] = M[2][3] = 0.f; - - M[3][0] = -(r+l)/(r-l); - M[3][1] = -(t+b)/(t-b); - M[3][2] = -(f+n)/(f-n); - M[3][3] = 1.f; -} -LINMATH_H_FUNC void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, float n, float f) -{ - /* NOTE: Degrees are an unhandy unit to work with. - * linmath.h uses radians for everything! */ - float const a = 1.f / tanf(y_fov / 2.f); - - m[0][0] = a / aspect; - m[0][1] = 0.f; - m[0][2] = 0.f; - m[0][3] = 0.f; - - m[1][0] = 0.f; - m[1][1] = a; - m[1][2] = 0.f; - m[1][3] = 0.f; - - m[2][0] = 0.f; - m[2][1] = 0.f; - m[2][2] = -((f + n) / (f - n)); - m[2][3] = -1.f; - - m[3][0] = 0.f; - m[3][1] = 0.f; - m[3][2] = -((2.f * f * n) / (f - n)); - m[3][3] = 0.f; -} -LINMATH_H_FUNC void mat4x4_look_at(mat4x4 m, vec3 const eye, vec3 const center, vec3 const up) -{ - /* Adapted from Android's OpenGL Matrix.java. */ - /* See the OpenGL GLUT documentation for gluLookAt for a description */ - /* of the algorithm. We implement it in a straightforward way: */ - - /* TODO: The negation of of can be spared by swapping the order of - * operands in the following cross products in the right way. */ - vec3 f; - vec3_sub(f, center, eye); - vec3_norm(f, f); - - vec3 s; - vec3_mul_cross(s, f, up); - vec3_norm(s, s); - - vec3 t; - vec3_mul_cross(t, s, f); - - m[0][0] = s[0]; - m[0][1] = t[0]; - m[0][2] = -f[0]; - m[0][3] = 0.f; - - m[1][0] = s[1]; - m[1][1] = t[1]; - m[1][2] = -f[1]; - m[1][3] = 0.f; - - m[2][0] = s[2]; - m[2][1] = t[2]; - m[2][2] = -f[2]; - m[2][3] = 0.f; - - m[3][0] = 0.f; - m[3][1] = 0.f; - m[3][2] = 0.f; - m[3][3] = 1.f; - - mat4x4_translate_in_place(m, -eye[0], -eye[1], -eye[2]); -} - -typedef float quat[4]; -#define quat_add vec4_add -#define quat_sub vec4_sub -#define quat_norm vec4_norm -#define quat_scale vec4_scale -#define quat_mul_inner vec4_mul_inner - -LINMATH_H_FUNC void quat_identity(quat q) -{ - q[0] = q[1] = q[2] = 0.f; - q[3] = 1.f; -} -LINMATH_H_FUNC void quat_mul(quat r, quat const p, quat const q) -{ - vec3 w, tmp; - - vec3_mul_cross(tmp, p, q); - vec3_scale(w, p, q[3]); - vec3_add(tmp, tmp, w); - vec3_scale(w, q, p[3]); - vec3_add(tmp, tmp, w); - - vec3_dup(r, tmp); - r[3] = p[3]*q[3] - vec3_mul_inner(p, q); -} -LINMATH_H_FUNC void quat_conj(quat r, quat const q) -{ - int i; - for(i=0; i<3; ++i) - r[i] = -q[i]; - r[3] = q[3]; -} -LINMATH_H_FUNC void quat_rotate(quat r, float angle, vec3 const axis) { - vec3 axis_norm; - vec3_norm(axis_norm, axis); - float s = sinf(angle / 2); - float c = cosf(angle / 2); - vec3_scale(r, axis_norm, s); - r[3] = c; -} -LINMATH_H_FUNC void quat_mul_vec3(vec3 r, quat const q, vec3 const v) -{ -/* - * Method by Fabian 'ryg' Giessen (of Farbrausch) -t = 2 * cross(q.xyz, v) -v' = v + q.w * t + cross(q.xyz, t) - */ - vec3 t; - vec3 q_xyz = {q[0], q[1], q[2]}; - vec3 u = {q[0], q[1], q[2]}; - - vec3_mul_cross(t, q_xyz, v); - vec3_scale(t, t, 2); - - vec3_mul_cross(u, q_xyz, t); - vec3_scale(t, t, q[3]); - - vec3_add(r, v, t); - vec3_add(r, r, u); -} -LINMATH_H_FUNC void mat4x4_from_quat(mat4x4 M, quat const q) -{ - float a = q[3]; - float b = q[0]; - float c = q[1]; - float d = q[2]; - float a2 = a*a; - float b2 = b*b; - float c2 = c*c; - float d2 = d*d; - - M[0][0] = a2 + b2 - c2 - d2; - M[0][1] = 2.f*(b*c + a*d); - M[0][2] = 2.f*(b*d - a*c); - M[0][3] = 0.f; - - M[1][0] = 2*(b*c - a*d); - M[1][1] = a2 - b2 + c2 - d2; - M[1][2] = 2.f*(c*d + a*b); - M[1][3] = 0.f; - - M[2][0] = 2.f*(b*d + a*c); - M[2][1] = 2.f*(c*d - a*b); - M[2][2] = a2 - b2 - c2 + d2; - M[2][3] = 0.f; - - M[3][0] = M[3][1] = M[3][2] = 0.f; - M[3][3] = 1.f; -} - -LINMATH_H_FUNC void mat4x4o_mul_quat(mat4x4 R, mat4x4 const M, quat const q) -{ -/* XXX: The way this is written only works for orthogonal matrices. */ -/* TODO: Take care of non-orthogonal case. */ - quat_mul_vec3(R[0], q, M[0]); - quat_mul_vec3(R[1], q, M[1]); - quat_mul_vec3(R[2], q, M[2]); - - R[3][0] = R[3][1] = R[3][2] = 0.f; - R[0][3] = M[0][3]; - R[1][3] = M[1][3]; - R[2][3] = M[2][3]; - R[3][3] = M[3][3]; // typically 1.0, but here we make it general -} -LINMATH_H_FUNC void quat_from_mat4x4(quat q, mat4x4 const M) -{ - float r=0.f; - int i; - - int perm[] = { 0, 1, 2, 0, 1 }; - int *p = perm; - - for(i = 0; i<3; i++) { - float m = M[i][i]; - if( m < r ) - continue; - m = r; - p = &perm[i]; - } - - r = sqrtf(1.f + M[p[0]][p[0]] - M[p[1]][p[1]] - M[p[2]][p[2]] ); - - if(r < 1e-6) { - q[0] = 1.f; - q[1] = q[2] = q[3] = 0.f; - return; - } - - q[0] = r/2.f; - q[1] = (M[p[0]][p[1]] - M[p[1]][p[0]])/(2.f*r); - q[2] = (M[p[2]][p[0]] - M[p[0]][p[2]])/(2.f*r); - q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]])/(2.f*r); -} - -LINMATH_H_FUNC void mat4x4_arcball(mat4x4 R, mat4x4 const M, vec2 const _a, vec2 const _b, float s) -{ - vec2 a; memcpy(a, _a, sizeof(a)); - vec2 b; memcpy(b, _b, sizeof(b)); - - float z_a = 0.; - float z_b = 0.; - - if(vec2_len(a) < 1.) { - z_a = sqrtf(1.f - vec2_mul_inner(a, a)); - } else { - vec2_norm(a, a); - } - - if(vec2_len(b) < 1.) { - z_b = sqrtf(1.f - vec2_mul_inner(b, b)); - } else { - vec2_norm(b, b); - } - - vec3 a_ = {a[0], a[1], z_a}; - vec3 b_ = {b[0], b[1], z_b}; - - vec3 c_; - vec3_mul_cross(c_, a_, b_); - - float const angle = acosf(vec3_mul_inner(a_, b_)) * s; - mat4x4_rotate(R, M, c_[0], c_[1], c_[2], angle); -} - -#endif diff --git a/tools/Vulkan-Tools/cube/macOS/cube/AppDelegate.h b/tools/Vulkan-Tools/cube/macOS/cube/AppDelegate.h deleted file mode 100644 index 0b1dfe49..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cube/AppDelegate.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * AppDelegate.h - * - * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Cocoa/Cocoa.h> - -@interface AppDelegate : NSObject<NSApplicationDelegate> - -@end diff --git a/tools/Vulkan-Tools/cube/macOS/cube/AppDelegate.m b/tools/Vulkan-Tools/cube/macOS/cube/AppDelegate.m deleted file mode 100644 index c1ee96b4..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cube/AppDelegate.m +++ /dev/null @@ -1,48 +0,0 @@ -/* - * AppDelegate.m - * - * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "AppDelegate.h" -#import "DemoViewController.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - // Insert code here to initialize your application -} - -- (void)applicationWillTerminate:(NSNotification *)aNotification { - NSApplication *app = aNotification.object; - NSArray<NSWindow *> *windows = app.windows; - for (NSUInteger i = 0; i < windows.count; ++i) { - NSViewController *viewController = windows[i].contentViewController; - if ([viewController isKindOfClass:[DemoViewController class]]) { - [(DemoViewController *)viewController quit]; - break; - } - } -} - -- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender { - return YES; -} - -@end diff --git a/tools/Vulkan-Tools/cube/macOS/cube/CMakeLists.txt b/tools/Vulkan-Tools/cube/macOS/cube/CMakeLists.txt deleted file mode 100644 index d0721a89..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cube/CMakeLists.txt +++ /dev/null @@ -1,93 +0,0 @@ -# ~~~ -# Copyright (c) 2018-2024 Valve Corporation -# Copyright (c) 2018-2024 LunarG, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ~~~ - -# VkCube Application Bundle - -set(cube_RESOURCES ${CMAKE_CURRENT_LIST_DIR}/Resources/VulkanIcon.icns) -if(NOT APPLE_USE_SYSTEM_ICD) - list(APPEND cube_RESOURCES ${PROJECT_BINARY_DIR}/staging-json/MoltenVK_icd.json) -endif() - -# Have Xcode handle the Storyboard -if(XCODE) - set(cube_RESOURCES ${cube_RESOURCES} ${CMAKE_CURRENT_LIST_DIR}/Resources/Main.storyboard) -endif() - -add_executable(vkcube MACOSX_BUNDLE) - -target_sources(vkcube PRIVATE - main.m - AppDelegate.m - AppDelegate.h - DemoViewController.m - DemoViewController.h - ${cube_RESOURCES} - ../../cube.vert.inc - ../../cube.frag.inc -) - -# Handle the Storyboard ourselves -if(NOT XCODE) - # Compile the storyboard file with the ibtool. - add_custom_command(TARGET vkcube POST_BUILD - COMMAND ${IBTOOL} - --errors - --warnings - --notices - --output-format human-readable-text - --compile ${CMAKE_CURRENT_BINARY_DIR}/vkcube.app/Contents/Resources/Main.storyboardc - ${CMAKE_CURRENT_LIST_DIR}/Resources/Main.storyboard - COMMENT "Compiling storyboard") -endif() - -if(NOT APPLE_USE_SYSTEM_ICD) - add_dependencies(vkcube MoltenVK_icd-staging-json) -endif() - -# Include demo source code dir because the MacOS cube's Objective-C source includes the "original" cube application C source code. -target_include_directories(vkcube PRIVATE ${CMAKE_CURRENT_LIST_DIR}) - -# We do this so vkcube is linked to an individual library and NOT a framework. -target_link_libraries(vkcube Vulkan::Loader "-framework Cocoa -framework QuartzCore") - -# Disable warnings about sprintf -target_compile_options(vkcube PRIVATE -Wno-deprecated-declarations) - -set_target_properties(vkcube PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_LIST_DIR}/Info.plist) - -# The RESOURCE target property cannot be used in conjunction with the MACOSX_PACKAGE_LOCATION property. We need fine-grained -# control over the Resource directory, so we have to specify the destination of all the resource files on a per-destination- -# directory basis. If all the files went into the top-level Resource directory, then we could simply set the RESOURCE property to a -# list of all the resource files. -set_source_files_properties(${cube_RESOURCES} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") -if(NOT APPLE_USE_SYSTEM_ICD) - set_source_files_properties("${PROJECT_BINARY_DIR}/staging-json/MoltenVK_icd.json" - PROPERTIES - MACOSX_PACKAGE_LOCATION - "Resources/vulkan/icd.d") - - # Copy the MoltenVK lib into the bundle. - if(XCODE) - add_custom_command(TARGET vkcube POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy "${MOLTENVK_DIR}/Package/Release/MoltenVK/dynamic/dylib/macOS/libMoltenVK.dylib" - ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/vkcube.app/Contents/Frameworks/libMoltenVK.dylib) - else() - add_custom_command(TARGET vkcube POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy "${MOLTENVK_DIR}/Package/Release/MoltenVK/dynamic/dylib/macOS/libMoltenVK.dylib" - ${CMAKE_CURRENT_BINARY_DIR}/vkcube.app/Contents/Frameworks/libMoltenVK.dylib) - endif() -endif() diff --git a/tools/Vulkan-Tools/cube/macOS/cube/DemoViewController.h b/tools/Vulkan-Tools/cube/macOS/cube/DemoViewController.h deleted file mode 100644 index 6d7ca215..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cube/DemoViewController.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * DemoViewController.h - * - * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <AppKit/AppKit.h> - -#pragma mark - -#pragma mark DemoViewController - -/** The main view controller for the demo storyboard. */ -@interface DemoViewController : NSViewController - -- (void)quit; - -@end - -#pragma mark - -#pragma mark DemoView - -/** The Metal-compatibile view for the demo Storyboard. */ -@interface DemoView : NSView -@end diff --git a/tools/Vulkan-Tools/cube/macOS/cube/DemoViewController.m b/tools/Vulkan-Tools/cube/macOS/cube/DemoViewController.m deleted file mode 100644 index d2158521..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cube/DemoViewController.m +++ /dev/null @@ -1,119 +0,0 @@ -/* - * DemoViewController.m - * - * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "DemoViewController.h" -#import <QuartzCore/CAMetalLayer.h> - -#include "cube.c" - -#pragma mark - -#pragma mark DemoViewController - -@implementation DemoViewController { - CVDisplayLinkRef _displayLink; - struct demo demo; - NSTimer* _timer; -} - -- (void)dealloc { - [self quit]; - [super dealloc]; -} - -- (void)quit { - CVDisplayLinkRelease(_displayLink); - demo_cleanup(&demo); -} - -/** Since this is a single-view app, initialize Vulkan during view loading. */ -- (void)viewDidLoad { - [super viewDidLoad]; - - self.view.wantsLayer = YES; // Back the view with a layer created by the makeBackingLayer method. - - // Convert incoming args to "C" argc/argv strings - NSArray *args = [[NSProcessInfo processInfo] arguments]; - const char** argv = (const char**) alloca(sizeof(char*) * args.count); - for(unsigned int i = 0; i < args.count; i++) { - NSString *s = args[i]; - argv[i] = s.UTF8String; - } - - demo_main(&demo, self.view.layer, args.count, argv); - - // Monitor the rendering loop for a quit condition - _timer = [NSTimer scheduledTimerWithTimeInterval: 0.2 - target: self - selector: @selector(onTick:) - userInfo: self - repeats: YES]; - - // Start the rendering loop - CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink); - CVDisplayLinkSetOutputCallback(_displayLink, &DisplayLinkCallback, &demo); - CVDisplayLinkStart(_displayLink); - -} - -// Close the window if the demo is in a Quit state --(void)onTick:(NSTimer*)timer { - if (demo.quit) { - [[[self view] window] close]; - } -} - -#pragma mark Display loop callback function - -/** Rendering loop callback function for use with a CVDisplayLink. */ -static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, - const CVTimeStamp* outputTime, - CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* target) { - struct demo* demo = (struct demo*)target; - demo_run(demo); - if (demo->quit) { - CVDisplayLinkStop(displayLink); - } - return kCVReturnSuccess; -} - -@end - -#pragma mark - -#pragma mark DemoView - -@implementation DemoView - -/** Indicates that the view wants to draw using the backing layer instead of using drawRect:. */ -- (BOOL)wantsUpdateLayer { - return YES; -} - -/** Returns a Metal-compatible layer. */ -+ (Class)layerClass { - return [CAMetalLayer class]; -} - -/** If the wantsLayer property is set to YES, this method will be invoked to return a layer instance. */ -- (CALayer*)makeBackingLayer { - CALayer* layer = [self.class.layerClass layer]; - CGSize viewScale = [self convertSizeToBacking:CGSizeMake(1.0, 1.0)]; - layer.contentsScale = MIN(viewScale.width, viewScale.height); - return layer; -} - -@end diff --git a/tools/Vulkan-Tools/cube/macOS/cube/Info.plist b/tools/Vulkan-Tools/cube/macOS/cube/Info.plist deleted file mode 100644 index 55145d32..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cube/Info.plist +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>English</string> - <key>CFBundleExecutable</key> - <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> - <key>CFBundleGetInfoString</key> - <string>VkCube</string> - <key>CFBundleIconFile</key> - <string>VulkanIcon.icns</string> - <key>CFBundleIdentifier</key> - <string>com.lunarg.vkcube</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleLongVersionString</key> - <string>1.0</string> - <key>CFBundleName</key> - <string>VkCube</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>CFBundleShortVersionString</key> - <string>1.0</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1.0</string> - <key>CSResourcesFileMapped</key> - <true/> - <key>NSHumanReadableCopyright</key> - <string>Copyright (c) 2018 The Khronos Group Inc. LunarG Inc. All rights reserved.</string> - <key>NSMainStoryboardFile</key> - <string>Main</string> - <key>NSPrincipalClass</key> - <string>NSApplication</string> -</dict> -</plist> diff --git a/tools/Vulkan-Tools/cube/macOS/cube/Resources/Main.storyboard b/tools/Vulkan-Tools/cube/macOS/cube/Resources/Main.storyboard deleted file mode 100644 index edc63148..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cube/Resources/Main.storyboard +++ /dev/null @@ -1,131 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15G26a" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS"> - <dependencies> - <deployment identifier="macosx"/> - <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/> - </dependencies> - <scenes> - <!--Application--> - <scene sceneID="JPo-4y-FX3"> - <objects> - <application id="hnw-xV-0zn" sceneMemberID="viewController"> - <menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6"> - <items> - <menuItem title="VkCube" id="1Xt-HY-uBw"> - <modifierMask key="keyEquivalentModifierMask"/> - <menu key="submenu" title="VkCube" systemMenu="apple" id="uQy-DD-JDr"> - <items> - <menuItem title="About Demo" id="5kV-Vb-QxS"> - <modifierMask key="keyEquivalentModifierMask"/> - <connections> - <action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/> - </connections> - </menuItem> - <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/> - <menuItem title="Hide Demo" keyEquivalent="h" id="Olw-nP-bQN"> - <connections> - <action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/> - </connections> - </menuItem> - <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO"> - <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/> - <connections> - <action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/> - </connections> - </menuItem> - <menuItem title="Show All" id="Kd2-mp-pUS"> - <modifierMask key="keyEquivalentModifierMask"/> - <connections> - <action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/> - </connections> - </menuItem> - <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/> - <menuItem title="Quit Demo" keyEquivalent="q" id="4sb-4s-VLi"> - <connections> - <action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/> - </connections> - </menuItem> - </items> - </menu> - </menuItem> - <menuItem title="Window" id="aUF-d1-5bR"> - <modifierMask key="keyEquivalentModifierMask"/> - <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo"> - <items> - <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV"> - <connections> - <action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/> - </connections> - </menuItem> - <menuItem title="Zoom" id="R4o-n2-Eq4"> - <modifierMask key="keyEquivalentModifierMask"/> - <connections> - <action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/> - </connections> - </menuItem> - <menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/> - <menuItem title="Bring All to Front" id="LE2-aR-0XJ"> - <modifierMask key="keyEquivalentModifierMask"/> - <connections> - <action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/> - </connections> - </menuItem> - </items> - </menu> - </menuItem> - <menuItem title="Help" id="wpr-3q-Mcd"> - <modifierMask key="keyEquivalentModifierMask"/> - <menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ"> - <items> - <menuItem title="VkCube Help" keyEquivalent="?" id="FKE-Sm-Kum"> - <connections> - <action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/> - </connections> - </menuItem> - </items> - </menu> - </menuItem> - </items> - </menu> - <connections> - <outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/> - </connections> - </application> - <customObject id="Voe-Tx-rLC" customClass="AppDelegate"/> - <customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/> - </objects> - <point key="canvasLocation" x="83.5" y="-47"/> - </scene> - <!--Window Controller--> - <scene sceneID="R2V-B0-nI4"> - <objects> - <windowController id="B8D-0N-5wS" sceneMemberID="viewController"> - <window key="window" title="VkCube" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA"> - <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/> - <rect key="contentRect" x="1051" y="656" width="300" height="200"/> - <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/> - <value key="minSize" type="size" width="300" height="200"/> - </window> - <connections> - <segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/> - </connections> - </windowController> - <customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/> - </objects> - <point key="canvasLocation" x="83" y="146"/> - </scene> - <!--Demo View Controller--> - <scene sceneID="hIz-AP-VOD"> - <objects> - <viewController id="XfG-lQ-9wD" customClass="DemoViewController" sceneMemberID="viewController"> - <view key="view" id="m2S-Jp-Qdl" customClass="DemoView"> - <rect key="frame" x="0.0" y="0.0" width="400" height="300"/> - <autoresizingMask key="autoresizingMask"/> - </view> - </viewController> - <customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/> - </objects> - <point key="canvasLocation" x="83" y="564"/> - </scene> - </scenes> -</document> diff --git a/tools/Vulkan-Tools/cube/macOS/cube/Resources/VulkanIcon.icns b/tools/Vulkan-Tools/cube/macOS/cube/Resources/VulkanIcon.icns Binary files differdeleted file mode 100644 index fb82fb7d..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cube/Resources/VulkanIcon.icns +++ /dev/null diff --git a/tools/Vulkan-Tools/cube/macOS/cube/main.m b/tools/Vulkan-Tools/cube/macOS/cube/main.m deleted file mode 100644 index cf9e0d89..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cube/main.m +++ /dev/null @@ -1,21 +0,0 @@ -/* - * main.m - * - * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Cocoa/Cocoa.h> - -int main(int argc, const char* argv[]) { return NSApplicationMain(argc, argv); } diff --git a/tools/Vulkan-Tools/cube/macOS/cubepp/AppDelegate.h b/tools/Vulkan-Tools/cube/macOS/cubepp/AppDelegate.h deleted file mode 100644 index 0b1dfe49..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cubepp/AppDelegate.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * AppDelegate.h - * - * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Cocoa/Cocoa.h> - -@interface AppDelegate : NSObject<NSApplicationDelegate> - -@end diff --git a/tools/Vulkan-Tools/cube/macOS/cubepp/AppDelegate.mm b/tools/Vulkan-Tools/cube/macOS/cubepp/AppDelegate.mm deleted file mode 100644 index c1ee96b4..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cubepp/AppDelegate.mm +++ /dev/null @@ -1,48 +0,0 @@ -/* - * AppDelegate.m - * - * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "AppDelegate.h" -#import "DemoViewController.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - // Insert code here to initialize your application -} - -- (void)applicationWillTerminate:(NSNotification *)aNotification { - NSApplication *app = aNotification.object; - NSArray<NSWindow *> *windows = app.windows; - for (NSUInteger i = 0; i < windows.count; ++i) { - NSViewController *viewController = windows[i].contentViewController; - if ([viewController isKindOfClass:[DemoViewController class]]) { - [(DemoViewController *)viewController quit]; - break; - } - } -} - -- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender { - return YES; -} - -@end diff --git a/tools/Vulkan-Tools/cube/macOS/cubepp/CMakeLists.txt b/tools/Vulkan-Tools/cube/macOS/cubepp/CMakeLists.txt deleted file mode 100644 index 6390db0b..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cubepp/CMakeLists.txt +++ /dev/null @@ -1,91 +0,0 @@ -# ~~~ -# Copyright (c) 2018-2024 Valve Corporation -# Copyright (c) 2018-2024 LunarG, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ~~~ - -# VkCube Application Bundle - -set(cubepp_RESOURCES ${CMAKE_CURRENT_LIST_DIR}/Resources/VulkanIcon.icns) -if(NOT APPLE_USE_SYSTEM_ICD) - list(APPEND cubepp_RESOURCES ${PROJECT_BINARY_DIR}/staging-json/MoltenVK_icd.json) -endif() - -# Have Xcode handle the Storyboard -if(XCODE) - set(cubepp_RESOURCES ${cubepp_RESOURCES} ${CMAKE_CURRENT_LIST_DIR}/Resources/Main.storyboard) -endif() - -add_executable(vkcubepp MACOSX_BUNDLE) - -target_sources(vkcubepp PRIVATE - main.mm - AppDelegate.mm - AppDelegate.h - DemoViewController.h - DemoViewController.mm - ${cubepp_RESOURCES} - ../../cube.vert.inc - ../../cube.frag.inc -) - -# Handle the Storyboard ourselves -if(NOT XCODE) - # Compile the storyboard file with the ibtool. - add_custom_command(TARGET vkcubepp POST_BUILD - COMMAND ${IBTOOL} - --errors - --warnings - --notices - --output-format human-readable-text - --compile ${CMAKE_CURRENT_BINARY_DIR}/vkcubepp.app/Contents/Resources/Main.storyboardc - ${CMAKE_CURRENT_LIST_DIR}/Resources/Main.storyboard - COMMENT "Compiling storyboard") -endif() - -if(NOT APPLE_USE_SYSTEM_ICD) - add_dependencies(vkcubepp MoltenVK_icd-staging-json) -endif() - -# Include demo source code dir because the MacOS vkcubepp's Objective-C source includes the "original" vkcubepp application C++ source -# code. -target_include_directories(vkcubepp PRIVATE ${CMAKE_CURRENT_LIST_DIR}) - -# We do this so vkcubepp is linked to an individual library and NOT a framework. -target_link_libraries(vkcubepp Vulkan::Loader "-framework Cocoa -framework QuartzCore") - -set_target_properties(vkcubepp PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_LIST_DIR}/Info.plist) - -# The RESOURCE target property cannot be used in conjunction with the MACOSX_PACKAGE_LOCATION property. We need fine-grained -# control over the Resource directory, so we have to specify the destination of all the resource files on a per-destination- -# directory basis. If all the files went into the top-level Resource directory, then we could simply set the RESOURCE property to a -# list of all the resource files. -set_source_files_properties(${cubepp_RESOURCES} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") -if(NOT APPLE_USE_SYSTEM_ICD) - set_source_files_properties("${PROJECT_BINARY_DIR}/staging-json/MoltenVK_icd.json" - PROPERTIES - MACOSX_PACKAGE_LOCATION - "Resources/vulkan/icd.d") - - # Copy the MoltenVK lib into the bundle. - if(XCODE) - add_custom_command(TARGET vkcubepp POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy "${MOLTENVK_DIR}/Package/Release/MoltenVK/dynamic/dylib/macOS/libMoltenVK.dylib" - ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/vkcubepp.app/Contents/Frameworks/libMoltenVK.dylib) - else() - add_custom_command(TARGET vkcubepp POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy "${MOLTENVK_DIR}/Package/Release/MoltenVK/dynamic/dylib/macOS/libMoltenVK.dylib" - ${CMAKE_CURRENT_BINARY_DIR}/vkcubepp.app/Contents/Frameworks/libMoltenVK.dylib) - endif() -endif() diff --git a/tools/Vulkan-Tools/cube/macOS/cubepp/DemoViewController.h b/tools/Vulkan-Tools/cube/macOS/cubepp/DemoViewController.h deleted file mode 100644 index 6d7ca215..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cubepp/DemoViewController.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * DemoViewController.h - * - * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <AppKit/AppKit.h> - -#pragma mark - -#pragma mark DemoViewController - -/** The main view controller for the demo storyboard. */ -@interface DemoViewController : NSViewController - -- (void)quit; - -@end - -#pragma mark - -#pragma mark DemoView - -/** The Metal-compatibile view for the demo Storyboard. */ -@interface DemoView : NSView -@end diff --git a/tools/Vulkan-Tools/cube/macOS/cubepp/DemoViewController.mm b/tools/Vulkan-Tools/cube/macOS/cubepp/DemoViewController.mm deleted file mode 100644 index fbb17797..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cubepp/DemoViewController.mm +++ /dev/null @@ -1,118 +0,0 @@ -/* - * DemoViewController.m - * - * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "DemoViewController.h" -#import <QuartzCore/CAMetalLayer.h> - -#include "cube.cpp" - -#pragma mark - -#pragma mark DemoViewController - -@implementation DemoViewController { - CVDisplayLinkRef _displayLink; - struct Demo demo; - NSTimer* _timer; -} - -- (void)dealloc { - [self quit]; - [super dealloc]; -} - -- (void)quit { - CVDisplayLinkRelease(_displayLink); - demo.cleanup(); -} - -/** Since this is a single-view app, initialize Vulkan during view loading. */ -- (void)viewDidLoad { - [super viewDidLoad]; - - self.view.wantsLayer = YES; // Back the view with a layer created by the makeBackingLayer method. - - // Convert incoming args to "C" argc/argv strings - NSArray *args = [[NSProcessInfo processInfo] arguments]; - const char** argv = (const char**) alloca(sizeof(char*) * args.count); - for(unsigned int i = 0; i < args.count; i++) { - NSString *s = args[i]; - argv[i] = s.UTF8String; - } - - demo_main(demo, self.view.layer, args.count, argv); - - // Monitor the rendering loop for a quit condition - _timer = [NSTimer scheduledTimerWithTimeInterval: 0.2 - target: self - selector: @selector(onTick:) - userInfo: self - repeats: YES]; - - // Start the rendering loop - CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink); - CVDisplayLinkSetOutputCallback(_displayLink, &DisplayLinkCallback, &demo); - CVDisplayLinkStart(_displayLink); -} - -// Close the window if the demo is in a Quit state --(void)onTick:(NSTimer*)timer { - if (demo.quit) { - [[[self view] window] close]; - } -} - -#pragma mark Display loop callback function - -/** Rendering loop callback function for use with a CVDisplayLink. */ -static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, - const CVTimeStamp* outputTime, - CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* target) { - struct Demo* demo = (struct Demo*)target; - demo->run<WsiPlatform::metal>(); - if (demo->quit) { - CVDisplayLinkStop(displayLink); - } - return kCVReturnSuccess; -} - -@end - -#pragma mark - -#pragma mark DemoView - -@implementation DemoView - -/** Indicates that the view wants to draw using the backing layer instead of using drawRect:. */ -- (BOOL)wantsUpdateLayer { - return YES; -} - -/** Returns a Metal-compatible layer. */ -+ (Class)layerClass { - return [CAMetalLayer class]; -} - -/** If the wantsLayer property is set to YES, this method will be invoked to return a layer instance. */ -- (CALayer*)makeBackingLayer { - CALayer* layer = [self.class.layerClass layer]; - CGSize viewScale = [self convertSizeToBacking:CGSizeMake(1.0, 1.0)]; - layer.contentsScale = MIN(viewScale.width, viewScale.height); - return layer; -} - -@end diff --git a/tools/Vulkan-Tools/cube/macOS/cubepp/Info.plist b/tools/Vulkan-Tools/cube/macOS/cubepp/Info.plist deleted file mode 100644 index d0b74e01..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cubepp/Info.plist +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>English</string> - <key>CFBundleExecutable</key> - <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> - <key>CFBundleGetInfoString</key> - <string>VkCubepp</string> - <key>CFBundleIconFile</key> - <string>VulkanIcon.icns</string> - <key>CFBundleIdentifier</key> - <string>com.lunarg.cubepp</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleLongVersionString</key> - <string>1.0</string> - <key>CFBundleName</key> - <string>VkCubepp</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>CFBundleShortVersionString</key> - <string>1.0</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1.0</string> - <key>CSResourcesFileMapped</key> - <true/> - <key>NSHumanReadableCopyright</key> - <string>Copyright (c) 2018 The Khronos Group Inc. LunarG Inc. All rights reserved.</string> - <key>NSMainStoryboardFile</key> - <string>Main</string> - <key>NSPrincipalClass</key> - <string>NSApplication</string> -</dict> -</plist> diff --git a/tools/Vulkan-Tools/cube/macOS/cubepp/Resources/Main.storyboard b/tools/Vulkan-Tools/cube/macOS/cubepp/Resources/Main.storyboard deleted file mode 100644 index abae39be..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cubepp/Resources/Main.storyboard +++ /dev/null @@ -1,131 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15G26a" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS"> - <dependencies> - <deployment identifier="macosx"/> - <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/> - </dependencies> - <scenes> - <!--Application--> - <scene sceneID="JPo-4y-FX3"> - <objects> - <application id="hnw-xV-0zn" sceneMemberID="viewController"> - <menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6"> - <items> - <menuItem title="VkCubepp" id="1Xt-HY-uBw"> - <modifierMask key="keyEquivalentModifierMask"/> - <menu key="submenu" title="VkCubepp" systemMenu="apple" id="uQy-DD-JDr"> - <items> - <menuItem title="About Demo" id="5kV-Vb-QxS"> - <modifierMask key="keyEquivalentModifierMask"/> - <connections> - <action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/> - </connections> - </menuItem> - <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/> - <menuItem title="Hide Demo" keyEquivalent="h" id="Olw-nP-bQN"> - <connections> - <action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/> - </connections> - </menuItem> - <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO"> - <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/> - <connections> - <action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/> - </connections> - </menuItem> - <menuItem title="Show All" id="Kd2-mp-pUS"> - <modifierMask key="keyEquivalentModifierMask"/> - <connections> - <action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/> - </connections> - </menuItem> - <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/> - <menuItem title="Quit Demo" keyEquivalent="q" id="4sb-4s-VLi"> - <connections> - <action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/> - </connections> - </menuItem> - </items> - </menu> - </menuItem> - <menuItem title="Window" id="aUF-d1-5bR"> - <modifierMask key="keyEquivalentModifierMask"/> - <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo"> - <items> - <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV"> - <connections> - <action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/> - </connections> - </menuItem> - <menuItem title="Zoom" id="R4o-n2-Eq4"> - <modifierMask key="keyEquivalentModifierMask"/> - <connections> - <action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/> - </connections> - </menuItem> - <menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/> - <menuItem title="Bring All to Front" id="LE2-aR-0XJ"> - <modifierMask key="keyEquivalentModifierMask"/> - <connections> - <action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/> - </connections> - </menuItem> - </items> - </menu> - </menuItem> - <menuItem title="Help" id="wpr-3q-Mcd"> - <modifierMask key="keyEquivalentModifierMask"/> - <menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ"> - <items> - <menuItem title="VkCubepp Help" keyEquivalent="?" id="FKE-Sm-Kum"> - <connections> - <action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/> - </connections> - </menuItem> - </items> - </menu> - </menuItem> - </items> - </menu> - <connections> - <outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/> - </connections> - </application> - <customObject id="Voe-Tx-rLC" customClass="AppDelegate"/> - <customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/> - </objects> - <point key="canvasLocation" x="83.5" y="-47"/> - </scene> - <!--Window Controller--> - <scene sceneID="R2V-B0-nI4"> - <objects> - <windowController id="B8D-0N-5wS" sceneMemberID="viewController"> - <window key="window" title="VkCubepp" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA"> - <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/> - <rect key="contentRect" x="1051" y="656" width="300" height="200"/> - <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/> - <value key="minSize" type="size" width="300" height="200"/> - </window> - <connections> - <segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/> - </connections> - </windowController> - <customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/> - </objects> - <point key="canvasLocation" x="83" y="146"/> - </scene> - <!--Demo View Controller--> - <scene sceneID="hIz-AP-VOD"> - <objects> - <viewController id="XfG-lQ-9wD" customClass="DemoViewController" sceneMemberID="viewController"> - <view key="view" id="m2S-Jp-Qdl" customClass="DemoView"> - <rect key="frame" x="0.0" y="0.0" width="400" height="300"/> - <autoresizingMask key="autoresizingMask"/> - </view> - </viewController> - <customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/> - </objects> - <point key="canvasLocation" x="83" y="564"/> - </scene> - </scenes> -</document> diff --git a/tools/Vulkan-Tools/cube/macOS/cubepp/Resources/VulkanIcon.icns b/tools/Vulkan-Tools/cube/macOS/cubepp/Resources/VulkanIcon.icns Binary files differdeleted file mode 100644 index fb82fb7d..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cubepp/Resources/VulkanIcon.icns +++ /dev/null diff --git a/tools/Vulkan-Tools/cube/macOS/cubepp/main.mm b/tools/Vulkan-Tools/cube/macOS/cubepp/main.mm deleted file mode 100644 index cf9e0d89..00000000 --- a/tools/Vulkan-Tools/cube/macOS/cubepp/main.mm +++ /dev/null @@ -1,21 +0,0 @@ -/* - * main.m - * - * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Cocoa/Cocoa.h> - -int main(int argc, const char* argv[]) { return NSApplicationMain(argc, argv); } diff --git a/tools/Vulkan-Tools/cube/object_type_string_helper.h b/tools/Vulkan-Tools/cube/object_type_string_helper.h deleted file mode 100644 index 0469b801..00000000 --- a/tools/Vulkan-Tools/cube/object_type_string_helper.h +++ /dev/null @@ -1,107 +0,0 @@ -/*************************************************************************** - * - * Copyright (c) 2018 The Khronos Group Inc. - * Copyright (c) 2018 Valve Corporation - * Copyright (c) 2018 LunarG, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Author: Mark Lobodzinski <mark@lunarg.com> - * - ****************************************************************************/ - -#pragma once -#ifdef _MSC_VER -#pragma warning(disable : 4065) -#endif - -#include <vulkan/vulkan.h> - -static inline const char* string_VkObjectType(VkObjectType input_value) { - switch ((VkObjectType)input_value) { - case VK_OBJECT_TYPE_QUERY_POOL: - return "VK_OBJECT_TYPE_QUERY_POOL"; - case VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION: - return "VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION"; - case VK_OBJECT_TYPE_SEMAPHORE: - return "VK_OBJECT_TYPE_SEMAPHORE"; - case VK_OBJECT_TYPE_SHADER_MODULE: - return "VK_OBJECT_TYPE_SHADER_MODULE"; - case VK_OBJECT_TYPE_SWAPCHAIN_KHR: - return "VK_OBJECT_TYPE_SWAPCHAIN_KHR"; - case VK_OBJECT_TYPE_SAMPLER: - return "VK_OBJECT_TYPE_SAMPLER"; - case VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV: - return "VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV"; - case VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT: - return "VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT"; - case VK_OBJECT_TYPE_IMAGE: - return "VK_OBJECT_TYPE_IMAGE"; - case VK_OBJECT_TYPE_UNKNOWN: - return "VK_OBJECT_TYPE_UNKNOWN"; - case VK_OBJECT_TYPE_DESCRIPTOR_POOL: - return "VK_OBJECT_TYPE_DESCRIPTOR_POOL"; - case VK_OBJECT_TYPE_COMMAND_BUFFER: - return "VK_OBJECT_TYPE_COMMAND_BUFFER"; - case VK_OBJECT_TYPE_BUFFER: - return "VK_OBJECT_TYPE_BUFFER"; - case VK_OBJECT_TYPE_SURFACE_KHR: - return "VK_OBJECT_TYPE_SURFACE_KHR"; - case VK_OBJECT_TYPE_INSTANCE: - return "VK_OBJECT_TYPE_INSTANCE"; - case VK_OBJECT_TYPE_VALIDATION_CACHE_EXT: - return "VK_OBJECT_TYPE_VALIDATION_CACHE_EXT"; - case VK_OBJECT_TYPE_IMAGE_VIEW: - return "VK_OBJECT_TYPE_IMAGE_VIEW"; - case VK_OBJECT_TYPE_DESCRIPTOR_SET: - return "VK_OBJECT_TYPE_DESCRIPTOR_SET"; - case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT: - return "VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT"; - case VK_OBJECT_TYPE_COMMAND_POOL: - return "VK_OBJECT_TYPE_COMMAND_POOL"; - case VK_OBJECT_TYPE_PHYSICAL_DEVICE: - return "VK_OBJECT_TYPE_PHYSICAL_DEVICE"; - case VK_OBJECT_TYPE_DISPLAY_KHR: - return "VK_OBJECT_TYPE_DISPLAY_KHR"; - case VK_OBJECT_TYPE_BUFFER_VIEW: - return "VK_OBJECT_TYPE_BUFFER_VIEW"; - case VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT: - return "VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT"; - case VK_OBJECT_TYPE_FRAMEBUFFER: - return "VK_OBJECT_TYPE_FRAMEBUFFER"; - case VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE: - return "VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE"; - case VK_OBJECT_TYPE_PIPELINE_CACHE: - return "VK_OBJECT_TYPE_PIPELINE_CACHE"; - case VK_OBJECT_TYPE_PIPELINE_LAYOUT: - return "VK_OBJECT_TYPE_PIPELINE_LAYOUT"; - case VK_OBJECT_TYPE_DEVICE_MEMORY: - return "VK_OBJECT_TYPE_DEVICE_MEMORY"; - case VK_OBJECT_TYPE_FENCE: - return "VK_OBJECT_TYPE_FENCE"; - case VK_OBJECT_TYPE_QUEUE: - return "VK_OBJECT_TYPE_QUEUE"; - case VK_OBJECT_TYPE_DEVICE: - return "VK_OBJECT_TYPE_DEVICE"; - case VK_OBJECT_TYPE_RENDER_PASS: - return "VK_OBJECT_TYPE_RENDER_PASS"; - case VK_OBJECT_TYPE_DISPLAY_MODE_KHR: - return "VK_OBJECT_TYPE_DISPLAY_MODE_KHR"; - case VK_OBJECT_TYPE_EVENT: - return "VK_OBJECT_TYPE_EVENT"; - case VK_OBJECT_TYPE_PIPELINE: - return "VK_OBJECT_TYPE_PIPELINE"; - default: - return "Unhandled VkObjectType"; - } -} diff --git a/tools/Vulkan-Tools/cube/wayland_loader.h b/tools/Vulkan-Tools/cube/wayland_loader.h deleted file mode 100644 index 7d7d9141..00000000 --- a/tools/Vulkan-Tools/cube/wayland_loader.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2024 The Khronos Group Inc. - * Copyright (c) 2024 Valve Corporation - * Copyright (c) 2024 LunarG, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Author: Charles Giessen <charles@lunarg.com> - */ - -#pragma once - -#include <stdbool.h> -#include <stdlib.h> -#include <dlfcn.h> - -#include <wayland-client-core.h> - -typedef struct wl_display *(*PFN_wl_display_connect)(const char *name); -typedef int (*PFN_wl_display_flush)(struct wl_display *display); -typedef int (*PFN_wl_display_dispatch)(struct wl_display *display); -typedef int (*PFN_wl_display_prepare_read)(struct wl_display *display); -typedef int (*PFN_wl_display_dispatch_pending)(struct wl_display *display); -typedef int (*PFN_wl_display_read_events)(struct wl_display *display); -typedef void (*PFN_wl_proxy_marshal)(struct wl_proxy *p, uint32_t opcode, ...); -typedef struct wl_proxy *(*PFN_wl_proxy_marshal_constructor)(struct wl_proxy *proxy, uint32_t opcode, - const struct wl_interface *interface, ...); -typedef struct wl_proxy *(*PFN_wl_proxy_marshal_constructor_versioned)(struct wl_proxy *proxy, uint32_t opcode, - const struct wl_interface *interface, uint32_t version, ...); -typedef struct wl_proxy *(*PFN_wl_proxy_marshal_flags)(struct wl_proxy *proxy, uint32_t opcode, - const struct wl_interface *interface, uint32_t version, uint32_t flags, ...); -typedef uint32_t (*PFN_wl_proxy_get_version)(struct wl_proxy *proxy); -typedef int (*PFN_wl_proxy_add_listener)(struct wl_proxy *proxy, void (**implementation)(void), void *data); -typedef void (*PFN_wl_proxy_destroy)(struct wl_proxy *proxy); -typedef int (*PFN_wl_display_roundtrip)(struct wl_display *display); -typedef void (*PFN_wl_display_disconnect)(struct wl_display *display); - -static PFN_wl_display_connect cube_wl_display_connect = NULL; -static PFN_wl_display_flush cube_wl_display_flush = NULL; -static PFN_wl_display_dispatch cube_wl_display_dispatch = NULL; -static PFN_wl_display_prepare_read cube_wl_display_prepare_read = NULL; -static PFN_wl_display_dispatch_pending cube_wl_display_dispatch_pending = NULL; -static PFN_wl_display_read_events cube_wl_display_read_events = NULL; -static PFN_wl_proxy_marshal cube_wl_proxy_marshal = NULL; -static PFN_wl_proxy_marshal_constructor cube_wl_proxy_marshal_constructor = NULL; -static PFN_wl_proxy_marshal_constructor_versioned cube_wl_proxy_marshal_constructor_versioned = NULL; -static PFN_wl_proxy_marshal_flags cube_wl_proxy_marshal_flags = NULL; -static PFN_wl_proxy_get_version cube_wl_proxy_get_version = NULL; -static PFN_wl_proxy_add_listener cube_wl_proxy_add_listener = NULL; -static PFN_wl_proxy_destroy cube_wl_proxy_destroy = NULL; -static PFN_wl_display_roundtrip cube_wl_display_roundtrip = NULL; -static PFN_wl_display_disconnect cube_wl_display_disconnect = NULL; - -// Use macro's to redefine the PFN's as the functions in client code -#define wl_display_connect cube_wl_display_connect -#define wl_display_flush cube_wl_display_flush -#define wl_display_dispatch cube_wl_display_dispatch -#define wl_display_prepare_read cube_wl_display_prepare_read -#define wl_display_dispatch_pending cube_wl_display_dispatch_pending -#define wl_display_read_events cube_wl_display_read_events -#define wl_proxy_marshal cube_wl_proxy_marshal -#define wl_proxy_marshal_constructor cube_wl_proxy_marshal_constructor -#define wl_proxy_marshal_constructor_versioned cube_wl_proxy_marshal_constructor_versioned -#define wl_proxy_marshal_flags cube_wl_proxy_marshal_flags -#define wl_proxy_get_version cube_wl_proxy_get_version -#define wl_proxy_add_listener cube_wl_proxy_add_listener -#define wl_proxy_destroy cube_wl_proxy_destroy -#define wl_display_roundtrip cube_wl_display_roundtrip -#define wl_display_disconnect cube_wl_display_disconnect - -static inline void *initialize_wayland() { - void *wayland_library = NULL; - if (NULL == wayland_library) { - wayland_library = dlopen("libwayland-client.so.0", RTLD_NOW | RTLD_LOCAL); - } - if (NULL == wayland_library) { - wayland_library = dlopen("libwayland-client.so", RTLD_NOW | RTLD_LOCAL); - } - if (NULL == wayland_library) { - return NULL; - } - -#ifdef __cplusplus -#define TYPE_CONVERSION(type) reinterpret_cast<type> -#else -#define TYPE_CONVERSION(type) -#endif - cube_wl_display_connect = TYPE_CONVERSION(PFN_wl_display_connect)(dlsym(wayland_library, "wl_display_connect")); - cube_wl_display_flush = TYPE_CONVERSION(PFN_wl_display_flush)(dlsym(wayland_library, "wl_display_flush")); - cube_wl_display_dispatch = TYPE_CONVERSION(PFN_wl_display_dispatch)(dlsym(wayland_library, "wl_display_dispatch")); - cube_wl_display_prepare_read = TYPE_CONVERSION(PFN_wl_display_prepare_read)(dlsym(wayland_library, "wl_display_prepare_read")); - cube_wl_display_dispatch_pending = - TYPE_CONVERSION(PFN_wl_display_dispatch_pending)(dlsym(wayland_library, "wl_display_dispatch_pending")); - cube_wl_display_read_events = TYPE_CONVERSION(PFN_wl_display_read_events)(dlsym(wayland_library, "wl_display_read_events")); - cube_wl_proxy_marshal = TYPE_CONVERSION(PFN_wl_proxy_marshal)(dlsym(wayland_library, "wl_proxy_marshal")); - cube_wl_proxy_marshal_constructor = - TYPE_CONVERSION(PFN_wl_proxy_marshal_constructor)(dlsym(wayland_library, "wl_proxy_marshal_constructor")); - cube_wl_proxy_marshal_constructor_versioned = TYPE_CONVERSION(PFN_wl_proxy_marshal_constructor_versioned)( - dlsym(wayland_library, "wl_proxy_marshal_constructor_versioned")); - cube_wl_proxy_marshal_flags = TYPE_CONVERSION(PFN_wl_proxy_marshal_flags)(dlsym(wayland_library, "wl_proxy_marshal_flags")); - cube_wl_proxy_get_version = TYPE_CONVERSION(PFN_wl_proxy_get_version)(dlsym(wayland_library, "wl_proxy_get_version")); - cube_wl_proxy_add_listener = TYPE_CONVERSION(PFN_wl_proxy_add_listener)(dlsym(wayland_library, "wl_proxy_add_listener")); - cube_wl_proxy_destroy = TYPE_CONVERSION(PFN_wl_proxy_destroy)(dlsym(wayland_library, "wl_proxy_destroy")); - cube_wl_display_roundtrip = TYPE_CONVERSION(PFN_wl_display_roundtrip)(dlsym(wayland_library, "wl_display_roundtrip")); - cube_wl_display_disconnect = TYPE_CONVERSION(PFN_wl_display_disconnect)(dlsym(wayland_library, "wl_display_disconnect")); - - return wayland_library; -} - -#include "xdg-shell-client-header.h" -#include "xdg-decoration-client-header.h" diff --git a/tools/Vulkan-Tools/cube/xcb_loader.h b/tools/Vulkan-Tools/cube/xcb_loader.h deleted file mode 100644 index cecd2540..00000000 --- a/tools/Vulkan-Tools/cube/xcb_loader.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2024 The Khronos Group Inc. - * Copyright (c) 2024 Valve Corporation - * Copyright (c) 2024 LunarG, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Author: Charles Giessen <charles@lunarg.com> - */ - -#pragma once - -#include <dlfcn.h> -#include <stdlib.h> - -#include <xcb/xcb.h> - -typedef xcb_void_cookie_t (*PFN_xcb_destroy_window)(xcb_connection_t *c, xcb_window_t window); -typedef void (*PFN_xcb_disconnect)(xcb_connection_t *c); -typedef int (*PFN_xcb_flush)(xcb_connection_t *c); -typedef xcb_generic_event_t *(*PFN_xcb_wait_for_event)(xcb_connection_t *c); -typedef xcb_generic_event_t *(*PFN_xcb_poll_for_event)(xcb_connection_t *c); -typedef uint32_t (*PFN_xcb_generate_id)(xcb_connection_t *c); -typedef xcb_void_cookie_t (*PFN_xcb_create_window)(xcb_connection_t *c, uint8_t depth, xcb_window_t wid, xcb_window_t parent, - int16_t x, int16_t y, uint16_t width, uint16_t height, uint16_t border_width, - uint16_t _class, xcb_visualid_t visual, uint32_t value_mask, - const void *value_list); -typedef xcb_intern_atom_cookie_t (*PFN_xcb_intern_atom)(xcb_connection_t *c, uint8_t only_if_exists, uint16_t name_len, - const char *name); -typedef xcb_intern_atom_reply_t *(*PFN_xcb_intern_atom_reply)(xcb_connection_t *c, xcb_intern_atom_cookie_t cookie /**< */, - xcb_generic_error_t **e); -typedef xcb_void_cookie_t (*PFN_xcb_change_property)(xcb_connection_t *c, uint8_t mode, xcb_window_t window, xcb_atom_t property, - xcb_atom_t type, uint8_t format, uint32_t data_len, const void *data); -typedef xcb_void_cookie_t (*PFN_xcb_map_window)(xcb_connection_t *c, xcb_window_t window); -typedef xcb_void_cookie_t (*PFN_xcb_configure_window)(xcb_connection_t *c, xcb_window_t window, uint16_t value_mask, - const void *value_list); -typedef xcb_connection_t *(*PFN_xcb_connect)(const char *displayname, int *screenp); -typedef int (*PFN_xcb_connection_has_error)(xcb_connection_t *c); -typedef const struct xcb_setup_t *(*PFN_xcb_get_setup)(xcb_connection_t *c); -typedef xcb_screen_iterator_t (*PFN_xcb_setup_roots_iterator)(const xcb_setup_t *R); -typedef void (*PFN_xcb_screen_next)(xcb_screen_iterator_t *i); - -static PFN_xcb_destroy_window cube_xcb_destroy_window = NULL; -static PFN_xcb_disconnect cube_xcb_disconnect = NULL; -static PFN_xcb_flush cube_xcb_flush = NULL; -static PFN_xcb_wait_for_event cube_xcb_wait_for_event = NULL; -static PFN_xcb_poll_for_event cube_xcb_poll_for_event = NULL; -static PFN_xcb_generate_id cube_xcb_generate_id = NULL; -static PFN_xcb_create_window cube_xcb_create_window = NULL; -static PFN_xcb_intern_atom cube_xcb_intern_atom = NULL; -static PFN_xcb_intern_atom_reply cube_xcb_intern_atom_reply = NULL; -static PFN_xcb_change_property cube_xcb_change_property = NULL; -static PFN_xcb_map_window cube_xcb_map_window = NULL; -static PFN_xcb_configure_window cube_xcb_configure_window = NULL; -static PFN_xcb_connect cube_xcb_connect = NULL; -static PFN_xcb_connection_has_error cube_xcb_connection_has_error = NULL; -static PFN_xcb_get_setup cube_xcb_get_setup = NULL; -static PFN_xcb_setup_roots_iterator cube_xcb_setup_roots_iterator = NULL; -static PFN_xcb_screen_next cube_xcb_screen_next = NULL; - -#define xcb_destroy_window cube_xcb_destroy_window -#define xcb_disconnect cube_xcb_disconnect -#define xcb_flush cube_xcb_flush -#define xcb_wait_for_event cube_xcb_wait_for_event -#define xcb_poll_for_event cube_xcb_poll_for_event -#define xcb_generate_id cube_xcb_generate_id -#define xcb_create_window cube_xcb_create_window -#define xcb_intern_atom cube_xcb_intern_atom -#define xcb_intern_atom_reply cube_xcb_intern_atom_reply -#define xcb_change_property cube_xcb_change_property -#define xcb_map_window cube_xcb_map_window -#define xcb_configure_window cube_xcb_configure_window -#define xcb_connect cube_xcb_connect -#define xcb_connection_has_error cube_xcb_connection_has_error -#define xcb_get_setup cube_xcb_get_setup -#define xcb_setup_roots_iterator cube_xcb_setup_roots_iterator -#define xcb_screen_next cube_xcb_screen_next - -void *initialize_xcb() { - void *xcb_library = NULL; - if (NULL == xcb_library) { - xcb_library = dlopen("libxcb.so.1", RTLD_NOW | RTLD_LOCAL); - } - if (NULL == xcb_library) { - xcb_library = dlopen("libxcb.so", RTLD_NOW | RTLD_LOCAL); - } - if (NULL == xcb_library) { - return NULL; - } - -#ifdef __cplusplus -#define TYPE_CONVERSION(type) reinterpret_cast<type> -#else -#define TYPE_CONVERSION(type) -#endif - - cube_xcb_destroy_window = TYPE_CONVERSION(PFN_xcb_destroy_window)(dlsym(xcb_library, "xcb_destroy_window")); - cube_xcb_disconnect = TYPE_CONVERSION(PFN_xcb_disconnect)(dlsym(xcb_library, "xcb_disconnect")); - cube_xcb_flush = TYPE_CONVERSION(PFN_xcb_flush)(dlsym(xcb_library, "xcb_flush")); - cube_xcb_wait_for_event = TYPE_CONVERSION(PFN_xcb_wait_for_event)(dlsym(xcb_library, "xcb_wait_for_event")); - cube_xcb_poll_for_event = TYPE_CONVERSION(PFN_xcb_poll_for_event)(dlsym(xcb_library, "xcb_poll_for_event")); - cube_xcb_generate_id = TYPE_CONVERSION(PFN_xcb_generate_id)(dlsym(xcb_library, "xcb_generate_id")); - cube_xcb_create_window = TYPE_CONVERSION(PFN_xcb_create_window)(dlsym(xcb_library, "xcb_create_window")); - cube_xcb_intern_atom = TYPE_CONVERSION(PFN_xcb_intern_atom)(dlsym(xcb_library, "xcb_intern_atom")); - cube_xcb_intern_atom_reply = TYPE_CONVERSION(PFN_xcb_intern_atom_reply)(dlsym(xcb_library, "xcb_intern_atom_reply")); - cube_xcb_change_property = TYPE_CONVERSION(PFN_xcb_change_property)(dlsym(xcb_library, "xcb_change_property")); - cube_xcb_map_window = TYPE_CONVERSION(PFN_xcb_map_window)(dlsym(xcb_library, "xcb_map_window")); - cube_xcb_configure_window = TYPE_CONVERSION(PFN_xcb_configure_window)(dlsym(xcb_library, "xcb_configure_window")); - cube_xcb_connect = TYPE_CONVERSION(PFN_xcb_connect)(dlsym(xcb_library, "xcb_connect")); - cube_xcb_connection_has_error = TYPE_CONVERSION(PFN_xcb_connection_has_error)(dlsym(xcb_library, "xcb_connection_has_error")); - cube_xcb_get_setup = TYPE_CONVERSION(PFN_xcb_get_setup)(dlsym(xcb_library, "xcb_get_setup")); - cube_xcb_setup_roots_iterator = TYPE_CONVERSION(PFN_xcb_setup_roots_iterator)(dlsym(xcb_library, "xcb_setup_roots_iterator")); - cube_xcb_screen_next = TYPE_CONVERSION(PFN_xcb_screen_next)(dlsym(xcb_library, "xcb_screen_next")); - - return xcb_library; -} diff --git a/tools/Vulkan-Tools/cube/xlib_loader.h b/tools/Vulkan-Tools/cube/xlib_loader.h deleted file mode 100644 index 5553558d..00000000 --- a/tools/Vulkan-Tools/cube/xlib_loader.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2024 The Khronos Group Inc. - * Copyright (c) 2024 Valve Corporation - * Copyright (c) 2024 LunarG, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Author: Charles Giessen <charles@lunarg.com> - */ - -#pragma once - -#include <dlfcn.h> -#include <stdlib.h> - -#include <X11/Xutil.h> - -typedef int (*PFN_XDestroyWindow)(Display*, Window); -typedef Display* (*PFN_XOpenDisplay)(_Xconst char*); -typedef Colormap (*PFN_XCreateColormap)(Display*, Window, Visual*, int); -typedef Window (*PFN_XCreateWindow)(Display*, Window, int, int, unsigned int, unsigned int, unsigned int, int, unsigned int, - Visual*, unsigned long, XSetWindowAttributes*); -typedef int (*PFN_XSelectInput)(Display*, Window, long); -typedef int (*PFN_XMapWindow)(Display*, Window); -typedef Atom (*PFN_XInternAtom)(Display*, _Xconst char*, Bool); -typedef int (*PFN_XNextEvent)(Display*, XEvent*); -typedef int (*PFN_XPending)(Display*); -typedef XVisualInfo* (*PFN_XGetVisualInfo)(Display*, long, XVisualInfo*, int*); -typedef int (*PFN_XCloseDisplay)(Display* /* display */ -); -typedef Status (*PFN_XInitThreads)(void); -typedef int (*PFN_XFlush)(Display* /* display */ -); -typedef Status (*PFN_XSetWMProtocols)(Display*, Window, Atom*, int); - -static PFN_XDestroyWindow cube_XDestroyWindow = NULL; -static PFN_XOpenDisplay cube_XOpenDisplay = NULL; -static PFN_XCreateColormap cube_XCreateColormap = NULL; -static PFN_XCreateWindow cube_XCreateWindow = NULL; -static PFN_XSelectInput cube_XSelectInput = NULL; -static PFN_XMapWindow cube_XMapWindow = NULL; -static PFN_XInternAtom cube_XInternAtom = NULL; -static PFN_XNextEvent cube_XNextEvent = NULL; -static PFN_XPending cube_XPending = NULL; -static PFN_XGetVisualInfo cube_XGetVisualInfo = NULL; -static PFN_XCloseDisplay cube_XCloseDisplay = NULL; -static PFN_XInitThreads cube_XInitThreads = NULL; -static PFN_XFlush cube_XFlush = NULL; -static PFN_XSetWMProtocols cube_XSetWMProtocols = NULL; - -#define XDestroyWindow cube_XDestroyWindow -#define XOpenDisplay cube_XOpenDisplay -#define XCreateColormap cube_XCreateColormap -#define XCreateWindow cube_XCreateWindow -#define XSelectInput cube_XSelectInput -#define XMapWindow cube_XMapWindow -#define XInternAtom cube_XInternAtom -#define XNextEvent cube_XNextEvent -#define XPending cube_XPending -#define XGetVisualInfo cube_XGetVisualInfo -#define XCloseDisplay cube_XCloseDisplay -#define XInitThreads cube_XInitThreads -#define XFlush cube_XFlush -#define XSetWMProtocols cube_XSetWMProtocols - -void* initialize_xlib() { - void* xlib_library = NULL; - if (NULL == xlib_library) { - xlib_library = dlopen("libX11.so.6", RTLD_NOW | RTLD_LOCAL); - } - if (NULL == xlib_library) { - xlib_library = dlopen("libX11.so", RTLD_NOW | RTLD_LOCAL); - } - if (NULL == xlib_library) { - return NULL; - } - -#ifdef __cplusplus -#define TYPE_CONVERSION(type) reinterpret_cast<type> -#else -#define TYPE_CONVERSION(type) -#endif - - cube_XDestroyWindow = TYPE_CONVERSION(PFN_XDestroyWindow)(dlsym(xlib_library, "XDestroyWindow")); - cube_XOpenDisplay = TYPE_CONVERSION(PFN_XOpenDisplay)(dlsym(xlib_library, "XOpenDisplay")); - cube_XCreateColormap = TYPE_CONVERSION(PFN_XCreateColormap)(dlsym(xlib_library, "XCreateColormap")); - cube_XCreateWindow = TYPE_CONVERSION(PFN_XCreateWindow)(dlsym(xlib_library, "XCreateWindow")); - cube_XSelectInput = TYPE_CONVERSION(PFN_XSelectInput)(dlsym(xlib_library, "XSelectInput")); - cube_XMapWindow = TYPE_CONVERSION(PFN_XMapWindow)(dlsym(xlib_library, "XMapWindow")); - cube_XInternAtom = TYPE_CONVERSION(PFN_XInternAtom)(dlsym(xlib_library, "XInternAtom")); - cube_XNextEvent = TYPE_CONVERSION(PFN_XNextEvent)(dlsym(xlib_library, "XNextEvent")); - cube_XPending = TYPE_CONVERSION(PFN_XPending)(dlsym(xlib_library, "XPending")); - cube_XGetVisualInfo = TYPE_CONVERSION(PFN_XGetVisualInfo)(dlsym(xlib_library, "XGetVisualInfo")); - cube_XCloseDisplay = TYPE_CONVERSION(PFN_XCloseDisplay)(dlsym(xlib_library, "XCloseDisplay")); - cube_XInitThreads = TYPE_CONVERSION(PFN_XInitThreads)(dlsym(xlib_library, "XInitThreads")); - cube_XFlush = TYPE_CONVERSION(PFN_XFlush)(dlsym(xlib_library, "XFlush")); - cube_XSetWMProtocols = TYPE_CONVERSION(PFN_XSetWMProtocols)(dlsym(xlib_library, "XSetWMProtocols")); - - return xlib_library; -} |
