aboutsummaryrefslogtreecommitdiff
path: root/tools/Vulkan-Tools/cube
diff options
context:
space:
mode:
authorLizzy Fleckenstein <lizzy@vlhl.dev>2026-04-12 21:37:16 +0200
committerLizzy Fleckenstein <lizzy@vlhl.dev>2026-04-12 21:37:16 +0200
commit165c94e3c1742dabaac73b20662e4d4c823dd310 (patch)
tree957d80074c5d0c62db8a92cc97b26646280f4b32 /tools/Vulkan-Tools/cube
parent4fd35dd290c212ed716adeb3be4dea71775e00dd (diff)
downloadusermoji-165c94e3c1742dabaac73b20662e4d4c823dd310.tar.xz
mkcube: use animtool
Diffstat (limited to 'tools/Vulkan-Tools/cube')
-rw-r--r--tools/Vulkan-Tools/cube/BUILD.gn185
-rw-r--r--tools/Vulkan-Tools/cube/CMakeLists.txt371
-rw-r--r--tools/Vulkan-Tools/cube/android/AndroidManifest.xml26
-rw-r--r--tools/Vulkan-Tools/cube/android/CMakeLists.txt57
-rw-r--r--tools/Vulkan-Tools/cube/android/android_util.cpp84
-rw-r--r--tools/Vulkan-Tools/cube/android/android_util.h32
-rw-r--r--tools/Vulkan-Tools/cube/cube.c5235
-rw-r--r--tools/Vulkan-Tools/cube/cube.cpp4252
-rw-r--r--tools/Vulkan-Tools/cube/cube.frag54
-rw-r--r--tools/Vulkan-Tools/cube/cube.frag.inc84
-rw-r--r--tools/Vulkan-Tools/cube/cube.vert38
-rw-r--r--tools/Vulkan-Tools/cube/cube.vert.inc50
-rw-r--r--tools/Vulkan-Tools/cube/cube_functions.h355
-rw-r--r--tools/Vulkan-Tools/cube/fuchsia/flatland_view.cpp210
-rw-r--r--tools/Vulkan-Tools/cube/fuchsia/flatland_view.h102
-rw-r--r--tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-fb-protected.cml27
-rw-r--r--tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-fb.cml26
-rw-r--r--tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-scenic-protected.cml45
-rw-r--r--tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-scenic.cml36
-rw-r--r--tools/Vulkan-Tools/cube/gettime.h68
-rw-r--r--tools/Vulkan-Tools/cube/linmath.h608
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cube/AppDelegate.h23
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cube/AppDelegate.m48
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cube/CMakeLists.txt93
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cube/DemoViewController.h36
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cube/DemoViewController.m119
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cube/Info.plist38
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cube/Resources/Main.storyboard131
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cube/Resources/VulkanIcon.icnsbin157001 -> 0 bytes
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cube/main.m21
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cubepp/AppDelegate.h23
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cubepp/AppDelegate.mm48
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cubepp/CMakeLists.txt91
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cubepp/DemoViewController.h36
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cubepp/DemoViewController.mm118
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cubepp/Info.plist38
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cubepp/Resources/Main.storyboard131
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cubepp/Resources/VulkanIcon.icnsbin157001 -> 0 bytes
-rw-r--r--tools/Vulkan-Tools/cube/macOS/cubepp/main.mm21
-rw-r--r--tools/Vulkan-Tools/cube/object_type_string_helper.h107
-rw-r--r--tools/Vulkan-Tools/cube/wayland_loader.h121
-rw-r--r--tools/Vulkan-Tools/cube/xcb_loader.h126
-rw-r--r--tools/Vulkan-Tools/cube/xlib_loader.h110
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, &current_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, &current_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, &current_submission, &current_swapchain_resource);
-
- if (demo->separate_present_queue) {
- demo_build_image_ownership_cmd(demo, &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
- vkResetFences(demo->device, 1, &current_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 = &current_submission.image_acquired_semaphore;
- submit_info.commandBufferCount = 1;
- submit_info.pCommandBuffers = &current_submission.cmd;
- submit_info.signalSemaphoreCount = 1;
- submit_info.pSignalSemaphores = &current_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 = &current_swapchain_resource.draw_complete_semaphore;
- submit_info.commandBufferCount = 1;
- submit_info.pCommandBuffers = &current_submission.graphics_to_present_cmd;
- submit_info.signalSemaphoreCount = 1;
- submit_info.pSignalSemaphores = &current_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) ? &current_swapchain_resource.image_ownership_semaphore
- : &current_swapchain_resource.draw_complete_semaphore,
- .swapchainCount = 1,
- .pSwapchains = &demo->swapchain,
- .pImageIndices = &current_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 = &rect;
-
- regions.sType = VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR;
- regions.pNext = present.pNext;
- regions.swapchainCount = present.swapchainCount;
- regions.pRegions = &region;
- present.pNext = &regions;
- }
-
- 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 = &image;
- }
-
- 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, &copy_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, &registry_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 &current_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(),
- &current_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 &current_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, &registry_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 = &image;
- }
- 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, &copy_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
deleted file mode 100644
index fb82fb7d..00000000
--- a/tools/Vulkan-Tools/cube/macOS/cube/Resources/VulkanIcon.icns
+++ /dev/null
Binary files differ
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
deleted file mode 100644
index fb82fb7d..00000000
--- a/tools/Vulkan-Tools/cube/macOS/cubepp/Resources/VulkanIcon.icns
+++ /dev/null
Binary files differ
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;
-}