├── .appveyor.yml ├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── External ├── Volk │ ├── volk.c │ └── volk.h └── Vulkan-Headers │ ├── vk_video │ ├── vulkan_video_codec_h264std.h │ ├── vulkan_video_codec_h264std_decode.h │ ├── vulkan_video_codec_h264std_encode.h │ ├── vulkan_video_codec_h265std.h │ ├── vulkan_video_codec_h265std_decode.h │ ├── vulkan_video_codec_h265std_encode.h │ └── vulkan_video_codecs_common.h │ └── vulkan │ ├── vk_enum_string_helper.h │ ├── vk_icd.h │ ├── vk_layer.h │ ├── vk_platform.h │ ├── vulkan.h │ ├── vulkan_android.h │ ├── vulkan_beta.h │ ├── vulkan_core.h │ ├── vulkan_directfb.h │ ├── vulkan_fuchsia.h │ ├── vulkan_ggp.h │ ├── vulkan_ios.h │ ├── vulkan_macos.h │ ├── vulkan_metal.h │ ├── vulkan_screen.h │ ├── vulkan_vi.h │ ├── vulkan_wayland.h │ ├── vulkan_win32.h │ ├── vulkan_xcb.h │ ├── vulkan_xlib.h │ └── vulkan_xlib_xrandr.h ├── LICENSE ├── README.md ├── Rush ├── .clang-format ├── GfxBitmapFont.cpp ├── GfxBitmapFont.h ├── GfxCommon.cpp ├── GfxCommon.h ├── GfxDevice.h ├── GfxDeviceMtl.h ├── GfxDeviceMtl.mm ├── GfxDeviceVK.cpp ├── GfxDeviceVK.h ├── GfxEmbeddedShaders.cpp ├── GfxEmbeddedShaders.h ├── GfxEmbeddedShadersMSL.cpp ├── GfxPrimitiveBatch.cpp ├── GfxPrimitiveBatch.h ├── MathCommon.h ├── MathTypes.cpp ├── MathTypes.h ├── Platform.cpp ├── Platform.h ├── PlatformLinux.cpp ├── PlatformMac.mm ├── PlatformWin32.cpp ├── Rush.h ├── Rush.natvis ├── RushC.cpp ├── RushC.h ├── UtilArray.h ├── UtilBuffer.h ├── UtilCamera.cpp ├── UtilCamera.h ├── UtilColor.h ├── UtilDataStream.h ├── UtilFile.cpp ├── UtilFile.h ├── UtilHash.h ├── UtilLinearAllocator.h ├── UtilLog.cpp ├── UtilLog.h ├── UtilMemory.h ├── UtilRandom.h ├── UtilResourcePool.h ├── UtilString.h ├── UtilTimer.cpp ├── UtilTimer.h ├── UtilTuple.h ├── Window.cpp ├── Window.h ├── WindowMac.h ├── WindowMac.mm ├── WindowWin32.cpp ├── WindowWin32.h ├── WindowXCB.cpp └── WindowXCB.h ├── Scripts ├── cmake-vs2017-vk.cmd ├── cmake-vs2019-vk.cmd └── embed_shaders.py └── Shaders └── Primitive.hlsl /.appveyor.yml: -------------------------------------------------------------------------------- 1 | shallow_clone: true 2 | 3 | os: 4 | - Visual Studio 2022 5 | 6 | configuration: 7 | - Debug 8 | - RelWithDebInfo 9 | 10 | install: 11 | - cmake -G "Visual Studio 17 2022" -DRUSH_RENDER_API=VK -B.\Build\vs2022-vk -H. 12 | 13 | build: 14 | project: .\Build\vs2022-vk\Rush.sln 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Project files 35 | *.sublime-workspace 36 | 37 | # Local build files 38 | Build 39 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | matrix: 2 | include: 3 | - os: osx 4 | compiler: clang 5 | language: cpp 6 | osx_image: xcode9.4 7 | env: 8 | - CMAKE_ARGS="-DRUSH_RENDER_API=NULL" 9 | - os: linux 10 | compiler: gcc 11 | language: cpp 12 | env: 13 | - CMAKE_ARGS="-DRUSH_RENDER_API=VK" 14 | - os: windows 15 | language: shell 16 | env: 17 | - CMAKE_ARGS="-A x64 -DRUSH_RENDER_API=VK" 18 | 19 | notifications: 20 | email: false 21 | 22 | install: 23 | - if [ $TRAVIS_OS_NAME = linux ]; then sudo apt-get install libxcb-xkb-dev libxcb-keysyms1-dev libx11-dev -y; fi 24 | 25 | before_script: 26 | - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then PATH=$PATH:/c/Program\ Files/CMake/bin; fi 27 | 28 | script: 29 | - mkdir build 30 | - cd build 31 | - cmake ${CMAKE_ARGS} .. 32 | - cmake --build . 33 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20) 2 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 3 | 4 | project(Rush VERSION 0.1.0.0) 5 | 6 | set(RUSH_RENDER_API "NULL" CACHE STRING "Select renderer type") 7 | 8 | option(RUSH_CLANG_TIDY "Run clang-tidy static analysis" OFF) 9 | 10 | if (RUSH_CLANG_TIDY) 11 | set(RUSH_CLANG_TIDY_CHECKS 12 | * 13 | -*avoid-c-arrays 14 | -*braces-around-statements 15 | -*deprecated-headers 16 | -*magic-numbers 17 | -*uppercase-literal-suffix 18 | -*use-auto 19 | -cppcoreguidelines* 20 | -fuchsia* 21 | -google-readability-casting 22 | -google-readability-todo 23 | -hicpp* 24 | -misc-non-private-member-variables-in-classes 25 | -readability-implicit-bool-conversion 26 | hicpp-member-init 27 | ) 28 | string(REPLACE ";" "," RUSH_CLANG_TIDY_CHECKS "${RUSH_CLANG_TIDY_CHECKS}") 29 | set(CMAKE_CXX_CLANG_TIDY clang-tidy; -checks=${RUSH_CLANG_TIDY_CHECKS}) 30 | endif() 31 | 32 | # NOTE: only Vulkan renderer is currently supported 33 | set_property(CACHE RUSH_RENDER_API PROPERTY STRINGS 34 | NULL 35 | VK 36 | MTL 37 | ) 38 | 39 | add_library(Rush STATIC 40 | Rush/GfxBitmapFont.cpp 41 | Rush/GfxBitmapFont.h 42 | Rush/GfxCommon.cpp 43 | Rush/GfxCommon.h 44 | Rush/GfxDevice.h 45 | Rush/GfxDeviceVK.cpp 46 | Rush/GfxDeviceVK.h 47 | Rush/GfxEmbeddedShaders.cpp 48 | Rush/GfxEmbeddedShaders.h 49 | Rush/GfxEmbeddedShadersMSL.cpp 50 | Rush/GfxPrimitiveBatch.cpp 51 | Rush/GfxPrimitiveBatch.h 52 | Rush/MathCommon.h 53 | Rush/MathTypes.cpp 54 | Rush/MathTypes.h 55 | Rush/Platform.cpp 56 | Rush/Platform.h 57 | Rush/PlatformLinux.cpp 58 | Rush/PlatformWin32.cpp 59 | Rush/Rush.h 60 | Rush/UtilArray.h 61 | Rush/UtilBuffer.h 62 | Rush/UtilCamera.cpp 63 | Rush/UtilCamera.h 64 | Rush/UtilColor.h 65 | Rush/UtilDataStream.h 66 | Rush/UtilFile.cpp 67 | Rush/UtilFile.h 68 | Rush/UtilHash.h 69 | Rush/UtilLinearAllocator.h 70 | Rush/UtilLog.cpp 71 | Rush/UtilLog.h 72 | Rush/UtilMemory.h 73 | Rush/UtilRandom.h 74 | Rush/UtilResourcePool.h 75 | Rush/UtilString.h 76 | Rush/UtilTimer.cpp 77 | Rush/UtilTimer.h 78 | Rush/UtilTuple.h 79 | Rush/Window.cpp 80 | Rush/Window.h 81 | Rush/WindowWin32.cpp 82 | Rush/WindowWin32.h 83 | Rush/WindowXCB.cpp 84 | Rush/WindowXCB.h 85 | ) 86 | 87 | set_property(TARGET Rush PROPERTY CXX_STANDARD 20) 88 | 89 | target_include_directories(Rush INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}") 90 | target_compile_features(Rush PUBLIC cxx_std_14) 91 | 92 | if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") 93 | 94 | target_compile_definitions(Rush PUBLIC 95 | RUSH_PLATFORM_WINDOWS 96 | ) 97 | target_compile_definitions(Rush PRIVATE 98 | NOMINMAX 99 | WIN32_LEAN_AND_MEAN 100 | ) 101 | 102 | set(RUSH_VULKAN_PLATFORM VK_USE_PLATFORM_WIN32_KHR) 103 | 104 | elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") 105 | 106 | target_compile_definitions(Rush PUBLIC 107 | RUSH_PLATFORM_LINUX 108 | ) 109 | # Should try to detect XCB support, but assume it exists in standard locations for now... 110 | # find_package(XCB REQUIRED) 111 | # target_include_directories(Rush PRIVATE ${XCB_INCLUDE_DIRS}) 112 | # target_link_libraries(Rush INTERFACE ${XCB_LIBRARIES}) 113 | target_link_libraries(Rush INTERFACE xcb xcb-keysyms pthread dl) 114 | 115 | set(RUSH_VULKAN_PLATFORM VK_USE_PLATFORM_XCB_KHR) 116 | 117 | elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 118 | 119 | target_compile_definitions(Rush PUBLIC 120 | RUSH_PLATFORM_MAC 121 | ) 122 | target_sources(Rush PRIVATE 123 | Rush/PlatformMac.mm 124 | Rush/WindowMac.h 125 | Rush/WindowMac.mm 126 | ) 127 | 128 | set(RUSH_VULKAN_PLATFORM VK_USE_PLATFORM_MACOS_MVK) 129 | 130 | endif() 131 | 132 | if (${RUSH_RENDER_API} MATCHES "NULL") 133 | target_compile_definitions(Rush PUBLIC 134 | RUSH_RENDER_API=RUSH_RENDER_API_NULL 135 | ) 136 | endif() 137 | 138 | if (${RUSH_RENDER_API} MATCHES "VK") 139 | target_compile_definitions(Rush PUBLIC 140 | RUSH_RENDER_API=RUSH_RENDER_API_VK 141 | VK_ENABLE_BETA_EXTENSIONS=1 142 | ${RUSH_VULKAN_PLATFORM} 143 | ) 144 | target_include_directories(Rush PUBLIC 145 | External/Vulkan-Headers 146 | External/Volk 147 | ) 148 | target_sources(Rush PRIVATE 149 | External/Volk/volk.c 150 | External/Volk/volk.h 151 | ) 152 | endif() 153 | 154 | if (${RUSH_RENDER_API} MATCHES "MTL") 155 | target_compile_definitions(Rush PUBLIC 156 | RUSH_RENDER_API=RUSH_RENDER_API_MTL 157 | ) 158 | target_sources(Rush PRIVATE 159 | Rush/GfxDeviceMtl.h 160 | Rush/GfxDeviceMtl.mm 161 | ) 162 | endif() 163 | 164 | if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 165 | find_library(Metal_LIBRARIES Metal) 166 | find_library(AppKit_LIBRARIES AppKit) 167 | find_library(QuartzCore_LIBRARIES QuartzCore) 168 | target_link_libraries(Rush INTERFACE 169 | ${Metal_LIBRARIES} 170 | ${AppKit_LIBRARIES} 171 | ${QuartzCore_LIBRARIES} 172 | ) 173 | endif() 174 | 175 | source_group("" FILES ${RUSH_SRC}) 176 | 177 | if (MSVC) 178 | target_sources(Rush PRIVATE 179 | Rush/Rush.natvis 180 | ) 181 | target_compile_options(Rush PRIVATE 182 | -W4 183 | -WX 184 | -wd4201 # nonstandard extension used: nameless struct/union 185 | -wd4100 # unreferenced formal parameter 186 | -wd4505 # unreferenced local function has been removed 187 | -wd5054 # operator '|': deprecated between enumerations of different types 188 | ) 189 | # target_compile_options(Rush PRIVATE ) 190 | #-WX -w4201 -w4100 -wd4514 191 | else() 192 | target_compile_options(Rush PRIVATE -Wall) 193 | endif() 194 | 195 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vk_video/vulkan_video_codec_h264std_decode.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_VIDEO_CODEC_H264STD_DECODE_H_ 2 | #define VULKAN_VIDEO_CODEC_H264STD_DECODE_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define vulkan_video_codec_h264std_decode 1 23 | 24 | #define VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0) 25 | 26 | #define STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_LIST_SIZE 2 27 | #define VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_API_VERSION_1_0_0 28 | #define VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h264_decode" 29 | 30 | typedef enum StdVideoDecodeH264FieldOrderCount { 31 | STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_TOP = 0, 32 | STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_BOTTOM = 1, 33 | STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_INVALID = 0x7FFFFFFF, 34 | STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_MAX_ENUM = 0x7FFFFFFF 35 | } StdVideoDecodeH264FieldOrderCount; 36 | typedef struct StdVideoDecodeH264PictureInfoFlags { 37 | uint32_t field_pic_flag : 1; 38 | uint32_t is_intra : 1; 39 | uint32_t IdrPicFlag : 1; 40 | uint32_t bottom_field_flag : 1; 41 | uint32_t is_reference : 1; 42 | uint32_t complementary_field_pair : 1; 43 | } StdVideoDecodeH264PictureInfoFlags; 44 | 45 | typedef struct StdVideoDecodeH264PictureInfo { 46 | StdVideoDecodeH264PictureInfoFlags flags; 47 | uint8_t seq_parameter_set_id; 48 | uint8_t pic_parameter_set_id; 49 | uint8_t reserved1; 50 | uint8_t reserved2; 51 | uint16_t frame_num; 52 | uint16_t idr_pic_id; 53 | int32_t PicOrderCnt[STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_LIST_SIZE]; 54 | } StdVideoDecodeH264PictureInfo; 55 | 56 | typedef struct StdVideoDecodeH264ReferenceInfoFlags { 57 | uint32_t top_field_flag : 1; 58 | uint32_t bottom_field_flag : 1; 59 | uint32_t used_for_long_term_reference : 1; 60 | uint32_t is_non_existing : 1; 61 | } StdVideoDecodeH264ReferenceInfoFlags; 62 | 63 | typedef struct StdVideoDecodeH264ReferenceInfo { 64 | StdVideoDecodeH264ReferenceInfoFlags flags; 65 | uint16_t FrameNum; 66 | uint16_t reserved; 67 | int32_t PicOrderCnt[STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_LIST_SIZE]; 68 | } StdVideoDecodeH264ReferenceInfo; 69 | 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vk_video/vulkan_video_codec_h264std_encode.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_VIDEO_CODEC_H264STD_ENCODE_H_ 2 | #define VULKAN_VIDEO_CODEC_H264STD_ENCODE_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define vulkan_video_codec_h264std_encode 1 23 | // Vulkan 0.9 provisional Vulkan video H.264 encode std specification version number 24 | #define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_0_9_9 VK_MAKE_VIDEO_STD_VERSION(0, 9, 9) 25 | 26 | #define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_0_9_9 27 | #define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h264_encode" 28 | typedef struct StdVideoEncodeH264WeightTableFlags { 29 | uint32_t luma_weight_l0_flag; 30 | uint32_t chroma_weight_l0_flag; 31 | uint32_t luma_weight_l1_flag; 32 | uint32_t chroma_weight_l1_flag; 33 | } StdVideoEncodeH264WeightTableFlags; 34 | 35 | typedef struct StdVideoEncodeH264WeightTable { 36 | StdVideoEncodeH264WeightTableFlags flags; 37 | uint8_t luma_log2_weight_denom; 38 | uint8_t chroma_log2_weight_denom; 39 | int8_t luma_weight_l0[STD_VIDEO_H264_MAX_NUM_LIST_REF]; 40 | int8_t luma_offset_l0[STD_VIDEO_H264_MAX_NUM_LIST_REF]; 41 | int8_t chroma_weight_l0[STD_VIDEO_H264_MAX_NUM_LIST_REF][STD_VIDEO_H264_MAX_CHROMA_PLANES]; 42 | int8_t chroma_offset_l0[STD_VIDEO_H264_MAX_NUM_LIST_REF][STD_VIDEO_H264_MAX_CHROMA_PLANES]; 43 | int8_t luma_weight_l1[STD_VIDEO_H264_MAX_NUM_LIST_REF]; 44 | int8_t luma_offset_l1[STD_VIDEO_H264_MAX_NUM_LIST_REF]; 45 | int8_t chroma_weight_l1[STD_VIDEO_H264_MAX_NUM_LIST_REF][STD_VIDEO_H264_MAX_CHROMA_PLANES]; 46 | int8_t chroma_offset_l1[STD_VIDEO_H264_MAX_NUM_LIST_REF][STD_VIDEO_H264_MAX_CHROMA_PLANES]; 47 | } StdVideoEncodeH264WeightTable; 48 | 49 | typedef struct StdVideoEncodeH264SliceHeaderFlags { 50 | uint32_t direct_spatial_mv_pred_flag : 1; 51 | uint32_t num_ref_idx_active_override_flag : 1; 52 | uint32_t no_output_of_prior_pics_flag : 1; 53 | uint32_t adaptive_ref_pic_marking_mode_flag : 1; 54 | uint32_t no_prior_references_available_flag : 1; 55 | } StdVideoEncodeH264SliceHeaderFlags; 56 | 57 | typedef struct StdVideoEncodeH264PictureInfoFlags { 58 | uint32_t idr_flag : 1; 59 | uint32_t is_reference_flag : 1; 60 | uint32_t used_for_long_term_reference : 1; 61 | } StdVideoEncodeH264PictureInfoFlags; 62 | 63 | typedef struct StdVideoEncodeH264ReferenceInfoFlags { 64 | uint32_t used_for_long_term_reference : 1; 65 | } StdVideoEncodeH264ReferenceInfoFlags; 66 | 67 | typedef struct StdVideoEncodeH264ReferenceListsInfoFlags { 68 | uint32_t ref_pic_list_modification_flag_l0 : 1; 69 | uint32_t ref_pic_list_modification_flag_l1 : 1; 70 | } StdVideoEncodeH264ReferenceListsInfoFlags; 71 | 72 | typedef struct StdVideoEncodeH264RefListModEntry { 73 | StdVideoH264ModificationOfPicNumsIdc modification_of_pic_nums_idc; 74 | uint16_t abs_diff_pic_num_minus1; 75 | uint16_t long_term_pic_num; 76 | } StdVideoEncodeH264RefListModEntry; 77 | 78 | typedef struct StdVideoEncodeH264RefPicMarkingEntry { 79 | StdVideoH264MemMgmtControlOp operation; 80 | uint16_t difference_of_pic_nums_minus1; 81 | uint16_t long_term_pic_num; 82 | uint16_t long_term_frame_idx; 83 | uint16_t max_long_term_frame_idx_plus1; 84 | } StdVideoEncodeH264RefPicMarkingEntry; 85 | 86 | typedef struct StdVideoEncodeH264ReferenceListsInfo { 87 | StdVideoEncodeH264ReferenceListsInfoFlags flags; 88 | uint8_t refPicList0EntryCount; 89 | uint8_t refPicList1EntryCount; 90 | uint8_t refList0ModOpCount; 91 | uint8_t refList1ModOpCount; 92 | uint8_t refPicMarkingOpCount; 93 | uint8_t reserved1[7]; 94 | const uint8_t* pRefPicList0Entries; 95 | const uint8_t* pRefPicList1Entries; 96 | const StdVideoEncodeH264RefListModEntry* pRefList0ModOperations; 97 | const StdVideoEncodeH264RefListModEntry* pRefList1ModOperations; 98 | const StdVideoEncodeH264RefPicMarkingEntry* pRefPicMarkingOperations; 99 | } StdVideoEncodeH264ReferenceListsInfo; 100 | 101 | typedef struct StdVideoEncodeH264PictureInfo { 102 | StdVideoEncodeH264PictureInfoFlags flags; 103 | uint8_t seq_parameter_set_id; 104 | uint8_t pic_parameter_set_id; 105 | uint16_t reserved1; 106 | StdVideoH264PictureType pictureType; 107 | uint32_t frame_num; 108 | int32_t PicOrderCnt; 109 | } StdVideoEncodeH264PictureInfo; 110 | 111 | typedef struct StdVideoEncodeH264ReferenceInfo { 112 | StdVideoEncodeH264ReferenceInfoFlags flags; 113 | StdVideoH264PictureType pictureType; 114 | uint32_t FrameNum; 115 | int32_t PicOrderCnt; 116 | uint16_t long_term_pic_num; 117 | uint16_t long_term_frame_idx; 118 | } StdVideoEncodeH264ReferenceInfo; 119 | 120 | typedef struct StdVideoEncodeH264SliceHeader { 121 | StdVideoEncodeH264SliceHeaderFlags flags; 122 | uint32_t first_mb_in_slice; 123 | StdVideoH264SliceType slice_type; 124 | uint16_t idr_pic_id; 125 | uint8_t num_ref_idx_l0_active_minus1; 126 | uint8_t num_ref_idx_l1_active_minus1; 127 | StdVideoH264CabacInitIdc cabac_init_idc; 128 | StdVideoH264DisableDeblockingFilterIdc disable_deblocking_filter_idc; 129 | int8_t slice_alpha_c0_offset_div2; 130 | int8_t slice_beta_offset_div2; 131 | uint16_t reserved1; 132 | uint32_t reserved2; 133 | const StdVideoEncodeH264WeightTable* pWeightTable; 134 | } StdVideoEncodeH264SliceHeader; 135 | 136 | 137 | #ifdef __cplusplus 138 | } 139 | #endif 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vk_video/vulkan_video_codec_h265std_decode.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_VIDEO_CODEC_H265STD_DECODE_H_ 2 | #define VULKAN_VIDEO_CODEC_H265STD_DECODE_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define vulkan_video_codec_h265std_decode 1 23 | 24 | #define VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0) 25 | 26 | #define STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE 8 27 | #define VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_API_VERSION_1_0_0 28 | #define VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h265_decode" 29 | typedef struct StdVideoDecodeH265PictureInfoFlags { 30 | uint32_t IrapPicFlag : 1; 31 | uint32_t IdrPicFlag : 1; 32 | uint32_t IsReference : 1; 33 | uint32_t short_term_ref_pic_set_sps_flag : 1; 34 | } StdVideoDecodeH265PictureInfoFlags; 35 | 36 | typedef struct StdVideoDecodeH265PictureInfo { 37 | StdVideoDecodeH265PictureInfoFlags flags; 38 | uint8_t sps_video_parameter_set_id; 39 | uint8_t pps_seq_parameter_set_id; 40 | uint8_t pps_pic_parameter_set_id; 41 | uint8_t NumDeltaPocsOfRefRpsIdx; 42 | int32_t PicOrderCntVal; 43 | uint16_t NumBitsForSTRefPicSetInSlice; 44 | uint16_t reserved; 45 | uint8_t RefPicSetStCurrBefore[STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE]; 46 | uint8_t RefPicSetStCurrAfter[STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE]; 47 | uint8_t RefPicSetLtCurr[STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE]; 48 | } StdVideoDecodeH265PictureInfo; 49 | 50 | typedef struct StdVideoDecodeH265ReferenceInfoFlags { 51 | uint32_t used_for_long_term_reference : 1; 52 | uint32_t unused_for_reference : 1; 53 | } StdVideoDecodeH265ReferenceInfoFlags; 54 | 55 | typedef struct StdVideoDecodeH265ReferenceInfo { 56 | StdVideoDecodeH265ReferenceInfoFlags flags; 57 | int32_t PicOrderCntVal; 58 | } StdVideoDecodeH265ReferenceInfo; 59 | 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vk_video/vulkan_video_codec_h265std_encode.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_VIDEO_CODEC_H265STD_ENCODE_H_ 2 | #define VULKAN_VIDEO_CODEC_H265STD_ENCODE_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define vulkan_video_codec_h265std_encode 1 23 | // Vulkan 0.9 provisional Vulkan video H.265 encode std specification version number 24 | #define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_0_9_10 VK_MAKE_VIDEO_STD_VERSION(0, 9, 10) 25 | 26 | #define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_0_9_10 27 | #define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h265_encode" 28 | typedef struct StdVideoEncodeH265WeightTableFlags { 29 | uint16_t luma_weight_l0_flag; 30 | uint16_t chroma_weight_l0_flag; 31 | uint16_t luma_weight_l1_flag; 32 | uint16_t chroma_weight_l1_flag; 33 | } StdVideoEncodeH265WeightTableFlags; 34 | 35 | typedef struct StdVideoEncodeH265WeightTable { 36 | StdVideoEncodeH265WeightTableFlags flags; 37 | uint8_t luma_log2_weight_denom; 38 | int8_t delta_chroma_log2_weight_denom; 39 | int8_t delta_luma_weight_l0[STD_VIDEO_H265_MAX_NUM_LIST_REF]; 40 | int8_t luma_offset_l0[STD_VIDEO_H265_MAX_NUM_LIST_REF]; 41 | int8_t delta_chroma_weight_l0[STD_VIDEO_H265_MAX_NUM_LIST_REF][STD_VIDEO_H265_MAX_CHROMA_PLANES]; 42 | int8_t delta_chroma_offset_l0[STD_VIDEO_H265_MAX_NUM_LIST_REF][STD_VIDEO_H265_MAX_CHROMA_PLANES]; 43 | int8_t delta_luma_weight_l1[STD_VIDEO_H265_MAX_NUM_LIST_REF]; 44 | int8_t luma_offset_l1[STD_VIDEO_H265_MAX_NUM_LIST_REF]; 45 | int8_t delta_chroma_weight_l1[STD_VIDEO_H265_MAX_NUM_LIST_REF][STD_VIDEO_H265_MAX_CHROMA_PLANES]; 46 | int8_t delta_chroma_offset_l1[STD_VIDEO_H265_MAX_NUM_LIST_REF][STD_VIDEO_H265_MAX_CHROMA_PLANES]; 47 | } StdVideoEncodeH265WeightTable; 48 | 49 | typedef struct StdVideoEncodeH265SliceSegmentHeaderFlags { 50 | uint32_t first_slice_segment_in_pic_flag : 1; 51 | uint32_t no_output_of_prior_pics_flag : 1; 52 | uint32_t dependent_slice_segment_flag : 1; 53 | uint32_t pic_output_flag : 1; 54 | uint32_t short_term_ref_pic_set_sps_flag : 1; 55 | uint32_t slice_temporal_mvp_enable_flag : 1; 56 | uint32_t slice_sao_luma_flag : 1; 57 | uint32_t slice_sao_chroma_flag : 1; 58 | uint32_t num_ref_idx_active_override_flag : 1; 59 | uint32_t mvd_l1_zero_flag : 1; 60 | uint32_t cabac_init_flag : 1; 61 | uint32_t cu_chroma_qp_offset_enabled_flag : 1; 62 | uint32_t deblocking_filter_override_flag : 1; 63 | uint32_t slice_deblocking_filter_disabled_flag : 1; 64 | uint32_t collocated_from_l0_flag : 1; 65 | uint32_t slice_loop_filter_across_slices_enabled_flag : 1; 66 | } StdVideoEncodeH265SliceSegmentHeaderFlags; 67 | 68 | typedef struct StdVideoEncodeH265SliceSegmentLongTermRefPics { 69 | uint8_t num_long_term_sps; 70 | uint8_t num_long_term_pics; 71 | uint8_t lt_idx_sps[STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS]; 72 | uint8_t poc_lsb_lt[STD_VIDEO_H265_MAX_LONG_TERM_PICS]; 73 | uint16_t used_by_curr_pic_lt_flag; 74 | uint8_t delta_poc_msb_present_flag[STD_VIDEO_H265_MAX_DELTA_POC]; 75 | uint8_t delta_poc_msb_cycle_lt[STD_VIDEO_H265_MAX_DELTA_POC]; 76 | } StdVideoEncodeH265SliceSegmentLongTermRefPics; 77 | 78 | typedef struct StdVideoEncodeH265SliceSegmentHeader { 79 | StdVideoEncodeH265SliceSegmentHeaderFlags flags; 80 | StdVideoH265SliceType slice_type; 81 | uint32_t slice_segment_address; 82 | uint8_t short_term_ref_pic_set_idx; 83 | uint8_t collocated_ref_idx; 84 | uint8_t num_ref_idx_l0_active_minus1; 85 | uint8_t num_ref_idx_l1_active_minus1; 86 | uint8_t MaxNumMergeCand; 87 | int8_t slice_cb_qp_offset; 88 | int8_t slice_cr_qp_offset; 89 | int8_t slice_beta_offset_div2; 90 | int8_t slice_tc_offset_div2; 91 | int8_t slice_act_y_qp_offset; 92 | int8_t slice_act_cb_qp_offset; 93 | int8_t slice_act_cr_qp_offset; 94 | const StdVideoH265ShortTermRefPicSet* pShortTermRefPicSet; 95 | const StdVideoEncodeH265SliceSegmentLongTermRefPics* pLongTermRefPics; 96 | const StdVideoEncodeH265WeightTable* pWeightTable; 97 | } StdVideoEncodeH265SliceSegmentHeader; 98 | 99 | typedef struct StdVideoEncodeH265ReferenceListsInfoFlags { 100 | uint32_t ref_pic_list_modification_flag_l0 : 1; 101 | uint32_t ref_pic_list_modification_flag_l1 : 1; 102 | } StdVideoEncodeH265ReferenceListsInfoFlags; 103 | 104 | typedef struct StdVideoEncodeH265ReferenceListsInfo { 105 | StdVideoEncodeH265ReferenceListsInfoFlags flags; 106 | uint8_t num_ref_idx_l0_active_minus1; 107 | uint8_t num_ref_idx_l1_active_minus1; 108 | uint16_t reserved1; 109 | const uint8_t* pRefPicList0Entries; 110 | const uint8_t* pRefPicList1Entries; 111 | const uint8_t* pRefList0Modifications; 112 | const uint8_t* pRefList1Modifications; 113 | } StdVideoEncodeH265ReferenceListsInfo; 114 | 115 | typedef struct StdVideoEncodeH265PictureInfoFlags { 116 | uint32_t is_reference_flag : 1; 117 | uint32_t IrapPicFlag : 1; 118 | uint32_t long_term_flag : 1; 119 | uint32_t discardable_flag : 1; 120 | uint32_t cross_layer_bla_flag : 1; 121 | } StdVideoEncodeH265PictureInfoFlags; 122 | 123 | typedef struct StdVideoEncodeH265PictureInfo { 124 | StdVideoEncodeH265PictureInfoFlags flags; 125 | StdVideoH265PictureType PictureType; 126 | uint8_t sps_video_parameter_set_id; 127 | uint8_t pps_seq_parameter_set_id; 128 | uint8_t pps_pic_parameter_set_id; 129 | uint8_t TemporalId; 130 | int32_t PicOrderCntVal; 131 | } StdVideoEncodeH265PictureInfo; 132 | 133 | typedef struct StdVideoEncodeH265ReferenceInfoFlags { 134 | uint32_t used_for_long_term_reference : 1; 135 | uint32_t unused_for_reference : 1; 136 | } StdVideoEncodeH265ReferenceInfoFlags; 137 | 138 | typedef struct StdVideoEncodeH265ReferenceInfo { 139 | StdVideoEncodeH265ReferenceInfoFlags flags; 140 | StdVideoH265PictureType PictureType; 141 | int32_t PicOrderCntVal; 142 | uint8_t TemporalId; 143 | } StdVideoEncodeH265ReferenceInfo; 144 | 145 | 146 | #ifdef __cplusplus 147 | } 148 | #endif 149 | 150 | #endif 151 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vk_video/vulkan_video_codecs_common.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_VIDEO_CODECS_COMMON_H_ 2 | #define VULKAN_VIDEO_CODECS_COMMON_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define vulkan_video_codecs_common 1 23 | #define VK_MAKE_VIDEO_STD_VERSION(major, minor, patch) \ 24 | ((((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch))) 25 | 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vulkan/vk_icd.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: vk_icd.h 3 | // 4 | /* 5 | * Copyright (c) 2015-2023 LunarG, Inc. 6 | * Copyright (c) 2015-2023 The Khronos Group Inc. 7 | * Copyright (c) 2015-2023 Valve Corporation 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | */ 22 | #pragma once 23 | 24 | #include "vulkan.h" 25 | #include 26 | 27 | // Loader-ICD version negotiation API. Versions add the following features: 28 | // Version 0 - Initial. Doesn't support vk_icdGetInstanceProcAddr 29 | // or vk_icdNegotiateLoaderICDInterfaceVersion. 30 | // Version 1 - Add support for vk_icdGetInstanceProcAddr. 31 | // Version 2 - Add Loader/ICD Interface version negotiation 32 | // via vk_icdNegotiateLoaderICDInterfaceVersion. 33 | // Version 3 - Add ICD creation/destruction of KHR_surface objects. 34 | // Version 4 - Add unknown physical device extension querying via 35 | // vk_icdGetPhysicalDeviceProcAddr. 36 | // Version 5 - Tells ICDs that the loader is now paying attention to the 37 | // application version of Vulkan passed into the ApplicationInfo 38 | // structure during vkCreateInstance. This will tell the ICD 39 | // that if the loader is older, it should automatically fail a 40 | // call for any API version > 1.0. Otherwise, the loader will 41 | // manually determine if it can support the expected version. 42 | // Version 6 - Add support for vk_icdEnumerateAdapterPhysicalDevices. 43 | // Version 7 - If an ICD supports any of the following functions, they must be 44 | // queryable with vk_icdGetInstanceProcAddr: 45 | // vk_icdNegotiateLoaderICDInterfaceVersion 46 | // vk_icdGetPhysicalDeviceProcAddr 47 | // vk_icdEnumerateAdapterPhysicalDevices (Windows only) 48 | // In addition, these functions no longer need to be exported directly. 49 | // This version allows drivers provided through the extension 50 | // VK_LUNARG_direct_driver_loading be able to support the entire 51 | // Driver-Loader interface. 52 | 53 | #define CURRENT_LOADER_ICD_INTERFACE_VERSION 7 54 | #define MIN_SUPPORTED_LOADER_ICD_INTERFACE_VERSION 0 55 | #define MIN_PHYS_DEV_EXTENSION_ICD_INTERFACE_VERSION 4 56 | 57 | // Old typedefs that don't follow a proper naming convention but are preserved for compatibility 58 | typedef VkResult(VKAPI_PTR *PFN_vkNegotiateLoaderICDInterfaceVersion)(uint32_t *pVersion); 59 | // This is defined in vk_layer.h which will be found by the loader, but if an ICD is building against this 60 | // file directly, it won't be found. 61 | #ifndef PFN_GetPhysicalDeviceProcAddr 62 | typedef PFN_vkVoidFunction(VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char *pName); 63 | #endif 64 | 65 | // Typedefs for loader/ICD interface 66 | typedef VkResult (VKAPI_PTR *PFN_vk_icdNegotiateLoaderICDInterfaceVersion)(uint32_t* pVersion); 67 | typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vk_icdGetInstanceProcAddr)(VkInstance instance, const char* pName); 68 | typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vk_icdGetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName); 69 | #if defined(VK_USE_PLATFORM_WIN32_KHR) 70 | typedef VkResult (VKAPI_PTR *PFN_vk_icdEnumerateAdapterPhysicalDevices)(VkInstance instance, LUID adapterLUID, 71 | uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); 72 | #endif 73 | 74 | // Prototypes for loader/ICD interface 75 | #if !defined(VK_NO_PROTOTYPES) 76 | #ifdef __cplusplus 77 | extern "C" { 78 | #endif 79 | VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pVersion); 80 | VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName); 81 | VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName); 82 | #if defined(VK_USE_PLATFORM_WIN32_KHR) 83 | VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID, 84 | uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); 85 | #endif 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | #endif 90 | 91 | /* 92 | * The ICD must reserve space for a pointer for the loader's dispatch 93 | * table, at the start of . 94 | * The ICD must initialize this variable using the SET_LOADER_MAGIC_VALUE macro. 95 | */ 96 | 97 | #define ICD_LOADER_MAGIC 0x01CDC0DE 98 | 99 | typedef union { 100 | uintptr_t loaderMagic; 101 | void *loaderData; 102 | } VK_LOADER_DATA; 103 | 104 | static inline void set_loader_magic_value(void *pNewObject) { 105 | VK_LOADER_DATA *loader_info = (VK_LOADER_DATA *)pNewObject; 106 | loader_info->loaderMagic = ICD_LOADER_MAGIC; 107 | } 108 | 109 | static inline bool valid_loader_magic_value(void *pNewObject) { 110 | const VK_LOADER_DATA *loader_info = (VK_LOADER_DATA *)pNewObject; 111 | return (loader_info->loaderMagic & 0xffffffff) == ICD_LOADER_MAGIC; 112 | } 113 | 114 | /* 115 | * Windows and Linux ICDs will treat VkSurfaceKHR as a pointer to a struct that 116 | * contains the platform-specific connection and surface information. 117 | */ 118 | typedef enum { 119 | VK_ICD_WSI_PLATFORM_MIR, 120 | VK_ICD_WSI_PLATFORM_WAYLAND, 121 | VK_ICD_WSI_PLATFORM_WIN32, 122 | VK_ICD_WSI_PLATFORM_XCB, 123 | VK_ICD_WSI_PLATFORM_XLIB, 124 | VK_ICD_WSI_PLATFORM_ANDROID, 125 | VK_ICD_WSI_PLATFORM_MACOS, 126 | VK_ICD_WSI_PLATFORM_IOS, 127 | VK_ICD_WSI_PLATFORM_DISPLAY, 128 | VK_ICD_WSI_PLATFORM_HEADLESS, 129 | VK_ICD_WSI_PLATFORM_METAL, 130 | VK_ICD_WSI_PLATFORM_DIRECTFB, 131 | VK_ICD_WSI_PLATFORM_VI, 132 | VK_ICD_WSI_PLATFORM_GGP, 133 | VK_ICD_WSI_PLATFORM_SCREEN, 134 | VK_ICD_WSI_PLATFORM_FUCHSIA, 135 | } VkIcdWsiPlatform; 136 | 137 | typedef struct { 138 | VkIcdWsiPlatform platform; 139 | } VkIcdSurfaceBase; 140 | 141 | #ifdef VK_USE_PLATFORM_MIR_KHR 142 | typedef struct { 143 | VkIcdSurfaceBase base; 144 | MirConnection *connection; 145 | MirSurface *mirSurface; 146 | } VkIcdSurfaceMir; 147 | #endif // VK_USE_PLATFORM_MIR_KHR 148 | 149 | #ifdef VK_USE_PLATFORM_WAYLAND_KHR 150 | typedef struct { 151 | VkIcdSurfaceBase base; 152 | struct wl_display *display; 153 | struct wl_surface *surface; 154 | } VkIcdSurfaceWayland; 155 | #endif // VK_USE_PLATFORM_WAYLAND_KHR 156 | 157 | #ifdef VK_USE_PLATFORM_WIN32_KHR 158 | typedef struct { 159 | VkIcdSurfaceBase base; 160 | HINSTANCE hinstance; 161 | HWND hwnd; 162 | } VkIcdSurfaceWin32; 163 | #endif // VK_USE_PLATFORM_WIN32_KHR 164 | 165 | #ifdef VK_USE_PLATFORM_XCB_KHR 166 | typedef struct { 167 | VkIcdSurfaceBase base; 168 | xcb_connection_t *connection; 169 | xcb_window_t window; 170 | } VkIcdSurfaceXcb; 171 | #endif // VK_USE_PLATFORM_XCB_KHR 172 | 173 | #ifdef VK_USE_PLATFORM_XLIB_KHR 174 | typedef struct { 175 | VkIcdSurfaceBase base; 176 | Display *dpy; 177 | Window window; 178 | } VkIcdSurfaceXlib; 179 | #endif // VK_USE_PLATFORM_XLIB_KHR 180 | 181 | #ifdef VK_USE_PLATFORM_DIRECTFB_EXT 182 | typedef struct { 183 | VkIcdSurfaceBase base; 184 | IDirectFB *dfb; 185 | IDirectFBSurface *surface; 186 | } VkIcdSurfaceDirectFB; 187 | #endif // VK_USE_PLATFORM_DIRECTFB_EXT 188 | 189 | #ifdef VK_USE_PLATFORM_ANDROID_KHR 190 | typedef struct { 191 | VkIcdSurfaceBase base; 192 | struct ANativeWindow *window; 193 | } VkIcdSurfaceAndroid; 194 | #endif // VK_USE_PLATFORM_ANDROID_KHR 195 | 196 | #ifdef VK_USE_PLATFORM_MACOS_MVK 197 | typedef struct { 198 | VkIcdSurfaceBase base; 199 | const void *pView; 200 | } VkIcdSurfaceMacOS; 201 | #endif // VK_USE_PLATFORM_MACOS_MVK 202 | 203 | #ifdef VK_USE_PLATFORM_IOS_MVK 204 | typedef struct { 205 | VkIcdSurfaceBase base; 206 | const void *pView; 207 | } VkIcdSurfaceIOS; 208 | #endif // VK_USE_PLATFORM_IOS_MVK 209 | 210 | #ifdef VK_USE_PLATFORM_GGP 211 | typedef struct { 212 | VkIcdSurfaceBase base; 213 | GgpStreamDescriptor streamDescriptor; 214 | } VkIcdSurfaceGgp; 215 | #endif // VK_USE_PLATFORM_GGP 216 | 217 | typedef struct { 218 | VkIcdSurfaceBase base; 219 | VkDisplayModeKHR displayMode; 220 | uint32_t planeIndex; 221 | uint32_t planeStackIndex; 222 | VkSurfaceTransformFlagBitsKHR transform; 223 | float globalAlpha; 224 | VkDisplayPlaneAlphaFlagBitsKHR alphaMode; 225 | VkExtent2D imageExtent; 226 | } VkIcdSurfaceDisplay; 227 | 228 | typedef struct { 229 | VkIcdSurfaceBase base; 230 | } VkIcdSurfaceHeadless; 231 | 232 | #ifdef VK_USE_PLATFORM_METAL_EXT 233 | typedef struct { 234 | VkIcdSurfaceBase base; 235 | const CAMetalLayer *pLayer; 236 | } VkIcdSurfaceMetal; 237 | #endif // VK_USE_PLATFORM_METAL_EXT 238 | 239 | #ifdef VK_USE_PLATFORM_VI_NN 240 | typedef struct { 241 | VkIcdSurfaceBase base; 242 | void *window; 243 | } VkIcdSurfaceVi; 244 | #endif // VK_USE_PLATFORM_VI_NN 245 | 246 | #ifdef VK_USE_PLATFORM_SCREEN_QNX 247 | typedef struct { 248 | VkIcdSurfaceBase base; 249 | struct _screen_context *context; 250 | struct _screen_window *window; 251 | } VkIcdSurfaceScreen; 252 | #endif // VK_USE_PLATFORM_SCREEN_QNX 253 | 254 | #ifdef VK_USE_PLATFORM_FUCHSIA 255 | typedef struct { 256 | VkIcdSurfaceBase base; 257 | } VkIcdSurfaceImagePipe; 258 | #endif // VK_USE_PLATFORM_FUCHSIA 259 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vulkan/vk_layer.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: vk_layer.h 3 | // 4 | /* 5 | * Copyright (c) 2015-2023 LunarG, Inc. 6 | * Copyright (c) 2015-2023 The Khronos Group Inc. 7 | * Copyright (c) 2015-2023 Valve Corporation 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | */ 22 | #pragma once 23 | 24 | /* Need to define dispatch table 25 | * Core struct can then have ptr to dispatch table at the top 26 | * Along with object ptrs for current and next OBJ 27 | */ 28 | 29 | #include "vulkan_core.h" 30 | 31 | #define MAX_NUM_UNKNOWN_EXTS 250 32 | 33 | // Loader-Layer version negotiation API. Versions add the following features: 34 | // Versions 0/1 - Initial. Doesn't support vk_layerGetPhysicalDeviceProcAddr 35 | // or vk_icdNegotiateLoaderLayerInterfaceVersion. 36 | // Version 2 - Add support for vk_layerGetPhysicalDeviceProcAddr and 37 | // vk_icdNegotiateLoaderLayerInterfaceVersion. 38 | #define CURRENT_LOADER_LAYER_INTERFACE_VERSION 2 39 | #define MIN_SUPPORTED_LOADER_LAYER_INTERFACE_VERSION 1 40 | 41 | #define VK_CURRENT_CHAIN_VERSION 1 42 | 43 | // Typedef for use in the interfaces below 44 | typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName); 45 | 46 | // Version negotiation values 47 | typedef enum VkNegotiateLayerStructType { 48 | LAYER_NEGOTIATE_UNINTIALIZED = 0, 49 | LAYER_NEGOTIATE_INTERFACE_STRUCT = 1, 50 | } VkNegotiateLayerStructType; 51 | 52 | // Version negotiation structures 53 | typedef struct VkNegotiateLayerInterface { 54 | VkNegotiateLayerStructType sType; 55 | void *pNext; 56 | uint32_t loaderLayerInterfaceVersion; 57 | PFN_vkGetInstanceProcAddr pfnGetInstanceProcAddr; 58 | PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr; 59 | PFN_GetPhysicalDeviceProcAddr pfnGetPhysicalDeviceProcAddr; 60 | } VkNegotiateLayerInterface; 61 | 62 | // Version negotiation functions 63 | typedef VkResult (VKAPI_PTR *PFN_vkNegotiateLoaderLayerInterfaceVersion)(VkNegotiateLayerInterface *pVersionStruct); 64 | 65 | // Function prototype for unknown physical device extension command 66 | typedef VkResult(VKAPI_PTR *PFN_PhysDevExt)(VkPhysicalDevice phys_device); 67 | 68 | // ------------------------------------------------------------------------------------------------ 69 | // CreateInstance and CreateDevice support structures 70 | 71 | /* Sub type of structure for instance and device loader ext of CreateInfo. 72 | * When sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO 73 | * or sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO 74 | * then VkLayerFunction indicates struct type pointed to by pNext 75 | */ 76 | typedef enum VkLayerFunction_ { 77 | VK_LAYER_LINK_INFO = 0, 78 | VK_LOADER_DATA_CALLBACK = 1, 79 | VK_LOADER_LAYER_CREATE_DEVICE_CALLBACK = 2, 80 | VK_LOADER_FEATURES = 3, 81 | } VkLayerFunction; 82 | 83 | typedef struct VkLayerInstanceLink_ { 84 | struct VkLayerInstanceLink_ *pNext; 85 | PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr; 86 | PFN_GetPhysicalDeviceProcAddr pfnNextGetPhysicalDeviceProcAddr; 87 | } VkLayerInstanceLink; 88 | 89 | /* 90 | * When creating the device chain the loader needs to pass 91 | * down information about it's device structure needed at 92 | * the end of the chain. Passing the data via the 93 | * VkLayerDeviceInfo avoids issues with finding the 94 | * exact instance being used. 95 | */ 96 | typedef struct VkLayerDeviceInfo_ { 97 | void *device_info; 98 | PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr; 99 | } VkLayerDeviceInfo; 100 | 101 | typedef VkResult (VKAPI_PTR *PFN_vkSetInstanceLoaderData)(VkInstance instance, 102 | void *object); 103 | typedef VkResult (VKAPI_PTR *PFN_vkSetDeviceLoaderData)(VkDevice device, 104 | void *object); 105 | typedef VkResult (VKAPI_PTR *PFN_vkLayerCreateDevice)(VkInstance instance, VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, 106 | const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, PFN_vkGetInstanceProcAddr layerGIPA, PFN_vkGetDeviceProcAddr *nextGDPA); 107 | typedef void (VKAPI_PTR *PFN_vkLayerDestroyDevice)(VkDevice physicalDevice, const VkAllocationCallbacks *pAllocator, PFN_vkDestroyDevice destroyFunction); 108 | 109 | typedef enum VkLoaderFeastureFlagBits { 110 | VK_LOADER_FEATURE_PHYSICAL_DEVICE_SORTING = 0x00000001, 111 | } VkLoaderFlagBits; 112 | typedef VkFlags VkLoaderFeatureFlags; 113 | 114 | typedef struct { 115 | VkStructureType sType; // VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO 116 | const void *pNext; 117 | VkLayerFunction function; 118 | union { 119 | VkLayerInstanceLink *pLayerInfo; 120 | PFN_vkSetInstanceLoaderData pfnSetInstanceLoaderData; 121 | struct { 122 | PFN_vkLayerCreateDevice pfnLayerCreateDevice; 123 | PFN_vkLayerDestroyDevice pfnLayerDestroyDevice; 124 | } layerDevice; 125 | VkLoaderFeatureFlags loaderFeatures; 126 | } u; 127 | } VkLayerInstanceCreateInfo; 128 | 129 | typedef struct VkLayerDeviceLink_ { 130 | struct VkLayerDeviceLink_ *pNext; 131 | PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr; 132 | PFN_vkGetDeviceProcAddr pfnNextGetDeviceProcAddr; 133 | } VkLayerDeviceLink; 134 | 135 | typedef struct { 136 | VkStructureType sType; // VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO 137 | const void *pNext; 138 | VkLayerFunction function; 139 | union { 140 | VkLayerDeviceLink *pLayerInfo; 141 | PFN_vkSetDeviceLoaderData pfnSetDeviceLoaderData; 142 | } u; 143 | } VkLayerDeviceCreateInfo; 144 | 145 | #ifdef __cplusplus 146 | extern "C" { 147 | #endif 148 | 149 | VKAPI_ATTR VkResult VKAPI_CALL vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface *pVersionStruct); 150 | 151 | typedef enum VkChainType { 152 | VK_CHAIN_TYPE_UNKNOWN = 0, 153 | VK_CHAIN_TYPE_ENUMERATE_INSTANCE_EXTENSION_PROPERTIES = 1, 154 | VK_CHAIN_TYPE_ENUMERATE_INSTANCE_LAYER_PROPERTIES = 2, 155 | VK_CHAIN_TYPE_ENUMERATE_INSTANCE_VERSION = 3, 156 | } VkChainType; 157 | 158 | typedef struct VkChainHeader { 159 | VkChainType type; 160 | uint32_t version; 161 | uint32_t size; 162 | } VkChainHeader; 163 | 164 | typedef struct VkEnumerateInstanceExtensionPropertiesChain { 165 | VkChainHeader header; 166 | VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceExtensionPropertiesChain *, const char *, uint32_t *, 167 | VkExtensionProperties *); 168 | const struct VkEnumerateInstanceExtensionPropertiesChain *pNextLink; 169 | 170 | #if defined(__cplusplus) 171 | inline VkResult CallDown(const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) const { 172 | return pfnNextLayer(pNextLink, pLayerName, pPropertyCount, pProperties); 173 | } 174 | #endif 175 | } VkEnumerateInstanceExtensionPropertiesChain; 176 | 177 | typedef struct VkEnumerateInstanceLayerPropertiesChain { 178 | VkChainHeader header; 179 | VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceLayerPropertiesChain *, uint32_t *, VkLayerProperties *); 180 | const struct VkEnumerateInstanceLayerPropertiesChain *pNextLink; 181 | 182 | #if defined(__cplusplus) 183 | inline VkResult CallDown(uint32_t *pPropertyCount, VkLayerProperties *pProperties) const { 184 | return pfnNextLayer(pNextLink, pPropertyCount, pProperties); 185 | } 186 | #endif 187 | } VkEnumerateInstanceLayerPropertiesChain; 188 | 189 | typedef struct VkEnumerateInstanceVersionChain { 190 | VkChainHeader header; 191 | VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceVersionChain *, uint32_t *); 192 | const struct VkEnumerateInstanceVersionChain *pNextLink; 193 | 194 | #if defined(__cplusplus) 195 | inline VkResult CallDown(uint32_t *pApiVersion) const { 196 | return pfnNextLayer(pNextLink, pApiVersion); 197 | } 198 | #endif 199 | } VkEnumerateInstanceVersionChain; 200 | 201 | #ifdef __cplusplus 202 | } 203 | #endif 204 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vulkan/vk_platform.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: vk_platform.h 3 | // 4 | /* 5 | ** Copyright 2014-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | 11 | #ifndef VK_PLATFORM_H_ 12 | #define VK_PLATFORM_H_ 13 | 14 | #ifdef __cplusplus 15 | extern "C" 16 | { 17 | #endif // __cplusplus 18 | 19 | /* 20 | *************************************************************************************************** 21 | * Platform-specific directives and type declarations 22 | *************************************************************************************************** 23 | */ 24 | 25 | /* Platform-specific calling convention macros. 26 | * 27 | * Platforms should define these so that Vulkan clients call Vulkan commands 28 | * with the same calling conventions that the Vulkan implementation expects. 29 | * 30 | * VKAPI_ATTR - Placed before the return type in function declarations. 31 | * Useful for C++11 and GCC/Clang-style function attribute syntax. 32 | * VKAPI_CALL - Placed after the return type in function declarations. 33 | * Useful for MSVC-style calling convention syntax. 34 | * VKAPI_PTR - Placed between the '(' and '*' in function pointer types. 35 | * 36 | * Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void); 37 | * Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void); 38 | */ 39 | #if defined(_WIN32) 40 | // On Windows, Vulkan commands use the stdcall convention 41 | #define VKAPI_ATTR 42 | #define VKAPI_CALL __stdcall 43 | #define VKAPI_PTR VKAPI_CALL 44 | #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7 45 | #error "Vulkan is not supported for the 'armeabi' NDK ABI" 46 | #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE) 47 | // On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" 48 | // calling convention, i.e. float parameters are passed in registers. This 49 | // is true even if the rest of the application passes floats on the stack, 50 | // as it does by default when compiling for the armeabi-v7a NDK ABI. 51 | #define VKAPI_ATTR __attribute__((pcs("aapcs-vfp"))) 52 | #define VKAPI_CALL 53 | #define VKAPI_PTR VKAPI_ATTR 54 | #else 55 | // On other platforms, use the default calling convention 56 | #define VKAPI_ATTR 57 | #define VKAPI_CALL 58 | #define VKAPI_PTR 59 | #endif 60 | 61 | #if !defined(VK_NO_STDDEF_H) 62 | #include 63 | #endif // !defined(VK_NO_STDDEF_H) 64 | 65 | #if !defined(VK_NO_STDINT_H) 66 | #if defined(_MSC_VER) && (_MSC_VER < 1600) 67 | typedef signed __int8 int8_t; 68 | typedef unsigned __int8 uint8_t; 69 | typedef signed __int16 int16_t; 70 | typedef unsigned __int16 uint16_t; 71 | typedef signed __int32 int32_t; 72 | typedef unsigned __int32 uint32_t; 73 | typedef signed __int64 int64_t; 74 | typedef unsigned __int64 uint64_t; 75 | #else 76 | #include 77 | #endif 78 | #endif // !defined(VK_NO_STDINT_H) 79 | 80 | #ifdef __cplusplus 81 | } // extern "C" 82 | #endif // __cplusplus 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vulkan/vulkan.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_H_ 2 | #define VULKAN_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | #include "vk_platform.h" 11 | #include "vulkan_core.h" 12 | 13 | #ifdef VK_USE_PLATFORM_ANDROID_KHR 14 | #include "vulkan_android.h" 15 | #endif 16 | 17 | #ifdef VK_USE_PLATFORM_FUCHSIA 18 | #include 19 | #include "vulkan_fuchsia.h" 20 | #endif 21 | 22 | #ifdef VK_USE_PLATFORM_IOS_MVK 23 | #include "vulkan_ios.h" 24 | #endif 25 | 26 | 27 | #ifdef VK_USE_PLATFORM_MACOS_MVK 28 | #include "vulkan_macos.h" 29 | #endif 30 | 31 | #ifdef VK_USE_PLATFORM_METAL_EXT 32 | #include "vulkan_metal.h" 33 | #endif 34 | 35 | #ifdef VK_USE_PLATFORM_VI_NN 36 | #include "vulkan_vi.h" 37 | #endif 38 | 39 | 40 | #ifdef VK_USE_PLATFORM_WAYLAND_KHR 41 | #include "vulkan_wayland.h" 42 | #endif 43 | 44 | 45 | #ifdef VK_USE_PLATFORM_WIN32_KHR 46 | #include 47 | #include "vulkan_win32.h" 48 | #endif 49 | 50 | 51 | #ifdef VK_USE_PLATFORM_XCB_KHR 52 | #include 53 | #include "vulkan_xcb.h" 54 | #endif 55 | 56 | 57 | #ifdef VK_USE_PLATFORM_XLIB_KHR 58 | #include 59 | #include "vulkan_xlib.h" 60 | #endif 61 | 62 | 63 | #ifdef VK_USE_PLATFORM_DIRECTFB_EXT 64 | #include 65 | #include "vulkan_directfb.h" 66 | #endif 67 | 68 | 69 | #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT 70 | #include 71 | #include 72 | #include "vulkan_xlib_xrandr.h" 73 | #endif 74 | 75 | 76 | #ifdef VK_USE_PLATFORM_GGP 77 | #include 78 | #include "vulkan_ggp.h" 79 | #endif 80 | 81 | 82 | #ifdef VK_USE_PLATFORM_SCREEN_QNX 83 | #include 84 | #include "vulkan_screen.h" 85 | #endif 86 | 87 | 88 | #ifdef VK_USE_PLATFORM_SCI 89 | #include 90 | #include 91 | #include "vulkan_sci.h" 92 | #endif 93 | 94 | 95 | #ifdef VK_ENABLE_BETA_EXTENSIONS 96 | #include "vulkan_beta.h" 97 | #endif 98 | 99 | #endif // VULKAN_H_ 100 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vulkan/vulkan_android.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_ANDROID_H_ 2 | #define VULKAN_ANDROID_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_KHR_android_surface 1 23 | struct ANativeWindow; 24 | #define VK_KHR_ANDROID_SURFACE_SPEC_VERSION 6 25 | #define VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "VK_KHR_android_surface" 26 | typedef VkFlags VkAndroidSurfaceCreateFlagsKHR; 27 | typedef struct VkAndroidSurfaceCreateInfoKHR { 28 | VkStructureType sType; 29 | const void* pNext; 30 | VkAndroidSurfaceCreateFlagsKHR flags; 31 | struct ANativeWindow* window; 32 | } VkAndroidSurfaceCreateInfoKHR; 33 | 34 | typedef VkResult (VKAPI_PTR *PFN_vkCreateAndroidSurfaceKHR)(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 35 | 36 | #ifndef VK_NO_PROTOTYPES 37 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR( 38 | VkInstance instance, 39 | const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, 40 | const VkAllocationCallbacks* pAllocator, 41 | VkSurfaceKHR* pSurface); 42 | #endif 43 | 44 | 45 | #define VK_ANDROID_external_memory_android_hardware_buffer 1 46 | struct AHardwareBuffer; 47 | #define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 5 48 | #define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME "VK_ANDROID_external_memory_android_hardware_buffer" 49 | typedef struct VkAndroidHardwareBufferUsageANDROID { 50 | VkStructureType sType; 51 | void* pNext; 52 | uint64_t androidHardwareBufferUsage; 53 | } VkAndroidHardwareBufferUsageANDROID; 54 | 55 | typedef struct VkAndroidHardwareBufferPropertiesANDROID { 56 | VkStructureType sType; 57 | void* pNext; 58 | VkDeviceSize allocationSize; 59 | uint32_t memoryTypeBits; 60 | } VkAndroidHardwareBufferPropertiesANDROID; 61 | 62 | typedef struct VkAndroidHardwareBufferFormatPropertiesANDROID { 63 | VkStructureType sType; 64 | void* pNext; 65 | VkFormat format; 66 | uint64_t externalFormat; 67 | VkFormatFeatureFlags formatFeatures; 68 | VkComponentMapping samplerYcbcrConversionComponents; 69 | VkSamplerYcbcrModelConversion suggestedYcbcrModel; 70 | VkSamplerYcbcrRange suggestedYcbcrRange; 71 | VkChromaLocation suggestedXChromaOffset; 72 | VkChromaLocation suggestedYChromaOffset; 73 | } VkAndroidHardwareBufferFormatPropertiesANDROID; 74 | 75 | typedef struct VkImportAndroidHardwareBufferInfoANDROID { 76 | VkStructureType sType; 77 | const void* pNext; 78 | struct AHardwareBuffer* buffer; 79 | } VkImportAndroidHardwareBufferInfoANDROID; 80 | 81 | typedef struct VkMemoryGetAndroidHardwareBufferInfoANDROID { 82 | VkStructureType sType; 83 | const void* pNext; 84 | VkDeviceMemory memory; 85 | } VkMemoryGetAndroidHardwareBufferInfoANDROID; 86 | 87 | typedef struct VkExternalFormatANDROID { 88 | VkStructureType sType; 89 | void* pNext; 90 | uint64_t externalFormat; 91 | } VkExternalFormatANDROID; 92 | 93 | typedef struct VkAndroidHardwareBufferFormatProperties2ANDROID { 94 | VkStructureType sType; 95 | void* pNext; 96 | VkFormat format; 97 | uint64_t externalFormat; 98 | VkFormatFeatureFlags2 formatFeatures; 99 | VkComponentMapping samplerYcbcrConversionComponents; 100 | VkSamplerYcbcrModelConversion suggestedYcbcrModel; 101 | VkSamplerYcbcrRange suggestedYcbcrRange; 102 | VkChromaLocation suggestedXChromaOffset; 103 | VkChromaLocation suggestedYChromaOffset; 104 | } VkAndroidHardwareBufferFormatProperties2ANDROID; 105 | 106 | typedef VkResult (VKAPI_PTR *PFN_vkGetAndroidHardwareBufferPropertiesANDROID)(VkDevice device, const struct AHardwareBuffer* buffer, VkAndroidHardwareBufferPropertiesANDROID* pProperties); 107 | typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryAndroidHardwareBufferANDROID)(VkDevice device, const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo, struct AHardwareBuffer** pBuffer); 108 | 109 | #ifndef VK_NO_PROTOTYPES 110 | VKAPI_ATTR VkResult VKAPI_CALL vkGetAndroidHardwareBufferPropertiesANDROID( 111 | VkDevice device, 112 | const struct AHardwareBuffer* buffer, 113 | VkAndroidHardwareBufferPropertiesANDROID* pProperties); 114 | 115 | VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryAndroidHardwareBufferANDROID( 116 | VkDevice device, 117 | const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo, 118 | struct AHardwareBuffer** pBuffer); 119 | #endif 120 | 121 | #ifdef __cplusplus 122 | } 123 | #endif 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vulkan/vulkan_directfb.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_DIRECTFB_H_ 2 | #define VULKAN_DIRECTFB_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_EXT_directfb_surface 1 23 | #define VK_EXT_DIRECTFB_SURFACE_SPEC_VERSION 1 24 | #define VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME "VK_EXT_directfb_surface" 25 | typedef VkFlags VkDirectFBSurfaceCreateFlagsEXT; 26 | typedef struct VkDirectFBSurfaceCreateInfoEXT { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkDirectFBSurfaceCreateFlagsEXT flags; 30 | IDirectFB* dfb; 31 | IDirectFBSurface* surface; 32 | } VkDirectFBSurfaceCreateInfoEXT; 33 | 34 | typedef VkResult (VKAPI_PTR *PFN_vkCreateDirectFBSurfaceEXT)(VkInstance instance, const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 35 | typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, IDirectFB* dfb); 36 | 37 | #ifndef VK_NO_PROTOTYPES 38 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateDirectFBSurfaceEXT( 39 | VkInstance instance, 40 | const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo, 41 | const VkAllocationCallbacks* pAllocator, 42 | VkSurfaceKHR* pSurface); 43 | 44 | VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceDirectFBPresentationSupportEXT( 45 | VkPhysicalDevice physicalDevice, 46 | uint32_t queueFamilyIndex, 47 | IDirectFB* dfb); 48 | #endif 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vulkan/vulkan_ggp.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_GGP_H_ 2 | #define VULKAN_GGP_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_GGP_stream_descriptor_surface 1 23 | #define VK_GGP_STREAM_DESCRIPTOR_SURFACE_SPEC_VERSION 1 24 | #define VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME "VK_GGP_stream_descriptor_surface" 25 | typedef VkFlags VkStreamDescriptorSurfaceCreateFlagsGGP; 26 | typedef struct VkStreamDescriptorSurfaceCreateInfoGGP { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkStreamDescriptorSurfaceCreateFlagsGGP flags; 30 | GgpStreamDescriptor streamDescriptor; 31 | } VkStreamDescriptorSurfaceCreateInfoGGP; 32 | 33 | typedef VkResult (VKAPI_PTR *PFN_vkCreateStreamDescriptorSurfaceGGP)(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 34 | 35 | #ifndef VK_NO_PROTOTYPES 36 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateStreamDescriptorSurfaceGGP( 37 | VkInstance instance, 38 | const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo, 39 | const VkAllocationCallbacks* pAllocator, 40 | VkSurfaceKHR* pSurface); 41 | #endif 42 | 43 | 44 | #define VK_GGP_frame_token 1 45 | #define VK_GGP_FRAME_TOKEN_SPEC_VERSION 1 46 | #define VK_GGP_FRAME_TOKEN_EXTENSION_NAME "VK_GGP_frame_token" 47 | typedef struct VkPresentFrameTokenGGP { 48 | VkStructureType sType; 49 | const void* pNext; 50 | GgpFrameToken frameToken; 51 | } VkPresentFrameTokenGGP; 52 | 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vulkan/vulkan_ios.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_IOS_H_ 2 | #define VULKAN_IOS_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_MVK_ios_surface 1 23 | #define VK_MVK_IOS_SURFACE_SPEC_VERSION 3 24 | #define VK_MVK_IOS_SURFACE_EXTENSION_NAME "VK_MVK_ios_surface" 25 | typedef VkFlags VkIOSSurfaceCreateFlagsMVK; 26 | typedef struct VkIOSSurfaceCreateInfoMVK { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkIOSSurfaceCreateFlagsMVK flags; 30 | const void* pView; 31 | } VkIOSSurfaceCreateInfoMVK; 32 | 33 | typedef VkResult (VKAPI_PTR *PFN_vkCreateIOSSurfaceMVK)(VkInstance instance, const VkIOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 34 | 35 | #ifndef VK_NO_PROTOTYPES 36 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateIOSSurfaceMVK( 37 | VkInstance instance, 38 | const VkIOSSurfaceCreateInfoMVK* pCreateInfo, 39 | const VkAllocationCallbacks* pAllocator, 40 | VkSurfaceKHR* pSurface); 41 | #endif 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vulkan/vulkan_macos.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_MACOS_H_ 2 | #define VULKAN_MACOS_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_MVK_macos_surface 1 23 | #define VK_MVK_MACOS_SURFACE_SPEC_VERSION 3 24 | #define VK_MVK_MACOS_SURFACE_EXTENSION_NAME "VK_MVK_macos_surface" 25 | typedef VkFlags VkMacOSSurfaceCreateFlagsMVK; 26 | typedef struct VkMacOSSurfaceCreateInfoMVK { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkMacOSSurfaceCreateFlagsMVK flags; 30 | const void* pView; 31 | } VkMacOSSurfaceCreateInfoMVK; 32 | 33 | typedef VkResult (VKAPI_PTR *PFN_vkCreateMacOSSurfaceMVK)(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 34 | 35 | #ifndef VK_NO_PROTOTYPES 36 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK( 37 | VkInstance instance, 38 | const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, 39 | const VkAllocationCallbacks* pAllocator, 40 | VkSurfaceKHR* pSurface); 41 | #endif 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vulkan/vulkan_metal.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_METAL_H_ 2 | #define VULKAN_METAL_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_EXT_metal_surface 1 23 | #ifdef __OBJC__ 24 | @class CAMetalLayer; 25 | #else 26 | typedef void CAMetalLayer; 27 | #endif 28 | 29 | #define VK_EXT_METAL_SURFACE_SPEC_VERSION 1 30 | #define VK_EXT_METAL_SURFACE_EXTENSION_NAME "VK_EXT_metal_surface" 31 | typedef VkFlags VkMetalSurfaceCreateFlagsEXT; 32 | typedef struct VkMetalSurfaceCreateInfoEXT { 33 | VkStructureType sType; 34 | const void* pNext; 35 | VkMetalSurfaceCreateFlagsEXT flags; 36 | const CAMetalLayer* pLayer; 37 | } VkMetalSurfaceCreateInfoEXT; 38 | 39 | typedef VkResult (VKAPI_PTR *PFN_vkCreateMetalSurfaceEXT)(VkInstance instance, const VkMetalSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 40 | 41 | #ifndef VK_NO_PROTOTYPES 42 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT( 43 | VkInstance instance, 44 | const VkMetalSurfaceCreateInfoEXT* pCreateInfo, 45 | const VkAllocationCallbacks* pAllocator, 46 | VkSurfaceKHR* pSurface); 47 | #endif 48 | 49 | 50 | #define VK_EXT_metal_objects 1 51 | #ifdef __OBJC__ 52 | @protocol MTLDevice; 53 | typedef id MTLDevice_id; 54 | #else 55 | typedef void* MTLDevice_id; 56 | #endif 57 | 58 | #ifdef __OBJC__ 59 | @protocol MTLCommandQueue; 60 | typedef id MTLCommandQueue_id; 61 | #else 62 | typedef void* MTLCommandQueue_id; 63 | #endif 64 | 65 | #ifdef __OBJC__ 66 | @protocol MTLBuffer; 67 | typedef id MTLBuffer_id; 68 | #else 69 | typedef void* MTLBuffer_id; 70 | #endif 71 | 72 | #ifdef __OBJC__ 73 | @protocol MTLTexture; 74 | typedef id MTLTexture_id; 75 | #else 76 | typedef void* MTLTexture_id; 77 | #endif 78 | 79 | typedef struct __IOSurface* IOSurfaceRef; 80 | #ifdef __OBJC__ 81 | @protocol MTLSharedEvent; 82 | typedef id MTLSharedEvent_id; 83 | #else 84 | typedef void* MTLSharedEvent_id; 85 | #endif 86 | 87 | #define VK_EXT_METAL_OBJECTS_SPEC_VERSION 1 88 | #define VK_EXT_METAL_OBJECTS_EXTENSION_NAME "VK_EXT_metal_objects" 89 | 90 | typedef enum VkExportMetalObjectTypeFlagBitsEXT { 91 | VK_EXPORT_METAL_OBJECT_TYPE_METAL_DEVICE_BIT_EXT = 0x00000001, 92 | VK_EXPORT_METAL_OBJECT_TYPE_METAL_COMMAND_QUEUE_BIT_EXT = 0x00000002, 93 | VK_EXPORT_METAL_OBJECT_TYPE_METAL_BUFFER_BIT_EXT = 0x00000004, 94 | VK_EXPORT_METAL_OBJECT_TYPE_METAL_TEXTURE_BIT_EXT = 0x00000008, 95 | VK_EXPORT_METAL_OBJECT_TYPE_METAL_IOSURFACE_BIT_EXT = 0x00000010, 96 | VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT = 0x00000020, 97 | VK_EXPORT_METAL_OBJECT_TYPE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF 98 | } VkExportMetalObjectTypeFlagBitsEXT; 99 | typedef VkFlags VkExportMetalObjectTypeFlagsEXT; 100 | typedef struct VkExportMetalObjectCreateInfoEXT { 101 | VkStructureType sType; 102 | const void* pNext; 103 | VkExportMetalObjectTypeFlagBitsEXT exportObjectType; 104 | } VkExportMetalObjectCreateInfoEXT; 105 | 106 | typedef struct VkExportMetalObjectsInfoEXT { 107 | VkStructureType sType; 108 | const void* pNext; 109 | } VkExportMetalObjectsInfoEXT; 110 | 111 | typedef struct VkExportMetalDeviceInfoEXT { 112 | VkStructureType sType; 113 | const void* pNext; 114 | MTLDevice_id mtlDevice; 115 | } VkExportMetalDeviceInfoEXT; 116 | 117 | typedef struct VkExportMetalCommandQueueInfoEXT { 118 | VkStructureType sType; 119 | const void* pNext; 120 | VkQueue queue; 121 | MTLCommandQueue_id mtlCommandQueue; 122 | } VkExportMetalCommandQueueInfoEXT; 123 | 124 | typedef struct VkExportMetalBufferInfoEXT { 125 | VkStructureType sType; 126 | const void* pNext; 127 | VkDeviceMemory memory; 128 | MTLBuffer_id mtlBuffer; 129 | } VkExportMetalBufferInfoEXT; 130 | 131 | typedef struct VkImportMetalBufferInfoEXT { 132 | VkStructureType sType; 133 | const void* pNext; 134 | MTLBuffer_id mtlBuffer; 135 | } VkImportMetalBufferInfoEXT; 136 | 137 | typedef struct VkExportMetalTextureInfoEXT { 138 | VkStructureType sType; 139 | const void* pNext; 140 | VkImage image; 141 | VkImageView imageView; 142 | VkBufferView bufferView; 143 | VkImageAspectFlagBits plane; 144 | MTLTexture_id mtlTexture; 145 | } VkExportMetalTextureInfoEXT; 146 | 147 | typedef struct VkImportMetalTextureInfoEXT { 148 | VkStructureType sType; 149 | const void* pNext; 150 | VkImageAspectFlagBits plane; 151 | MTLTexture_id mtlTexture; 152 | } VkImportMetalTextureInfoEXT; 153 | 154 | typedef struct VkExportMetalIOSurfaceInfoEXT { 155 | VkStructureType sType; 156 | const void* pNext; 157 | VkImage image; 158 | IOSurfaceRef ioSurface; 159 | } VkExportMetalIOSurfaceInfoEXT; 160 | 161 | typedef struct VkImportMetalIOSurfaceInfoEXT { 162 | VkStructureType sType; 163 | const void* pNext; 164 | IOSurfaceRef ioSurface; 165 | } VkImportMetalIOSurfaceInfoEXT; 166 | 167 | typedef struct VkExportMetalSharedEventInfoEXT { 168 | VkStructureType sType; 169 | const void* pNext; 170 | VkSemaphore semaphore; 171 | VkEvent event; 172 | MTLSharedEvent_id mtlSharedEvent; 173 | } VkExportMetalSharedEventInfoEXT; 174 | 175 | typedef struct VkImportMetalSharedEventInfoEXT { 176 | VkStructureType sType; 177 | const void* pNext; 178 | MTLSharedEvent_id mtlSharedEvent; 179 | } VkImportMetalSharedEventInfoEXT; 180 | 181 | typedef void (VKAPI_PTR *PFN_vkExportMetalObjectsEXT)(VkDevice device, VkExportMetalObjectsInfoEXT* pMetalObjectsInfo); 182 | 183 | #ifndef VK_NO_PROTOTYPES 184 | VKAPI_ATTR void VKAPI_CALL vkExportMetalObjectsEXT( 185 | VkDevice device, 186 | VkExportMetalObjectsInfoEXT* pMetalObjectsInfo); 187 | #endif 188 | 189 | #ifdef __cplusplus 190 | } 191 | #endif 192 | 193 | #endif 194 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vulkan/vulkan_screen.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_SCREEN_H_ 2 | #define VULKAN_SCREEN_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_QNX_screen_surface 1 23 | #define VK_QNX_SCREEN_SURFACE_SPEC_VERSION 1 24 | #define VK_QNX_SCREEN_SURFACE_EXTENSION_NAME "VK_QNX_screen_surface" 25 | typedef VkFlags VkScreenSurfaceCreateFlagsQNX; 26 | typedef struct VkScreenSurfaceCreateInfoQNX { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkScreenSurfaceCreateFlagsQNX flags; 30 | struct _screen_context* context; 31 | struct _screen_window* window; 32 | } VkScreenSurfaceCreateInfoQNX; 33 | 34 | typedef VkResult (VKAPI_PTR *PFN_vkCreateScreenSurfaceQNX)(VkInstance instance, const VkScreenSurfaceCreateInfoQNX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 35 | typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct _screen_window* window); 36 | 37 | #ifndef VK_NO_PROTOTYPES 38 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateScreenSurfaceQNX( 39 | VkInstance instance, 40 | const VkScreenSurfaceCreateInfoQNX* pCreateInfo, 41 | const VkAllocationCallbacks* pAllocator, 42 | VkSurfaceKHR* pSurface); 43 | 44 | VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceScreenPresentationSupportQNX( 45 | VkPhysicalDevice physicalDevice, 46 | uint32_t queueFamilyIndex, 47 | struct _screen_window* window); 48 | #endif 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vulkan/vulkan_vi.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_VI_H_ 2 | #define VULKAN_VI_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_NN_vi_surface 1 23 | #define VK_NN_VI_SURFACE_SPEC_VERSION 1 24 | #define VK_NN_VI_SURFACE_EXTENSION_NAME "VK_NN_vi_surface" 25 | typedef VkFlags VkViSurfaceCreateFlagsNN; 26 | typedef struct VkViSurfaceCreateInfoNN { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkViSurfaceCreateFlagsNN flags; 30 | void* window; 31 | } VkViSurfaceCreateInfoNN; 32 | 33 | typedef VkResult (VKAPI_PTR *PFN_vkCreateViSurfaceNN)(VkInstance instance, const VkViSurfaceCreateInfoNN* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 34 | 35 | #ifndef VK_NO_PROTOTYPES 36 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateViSurfaceNN( 37 | VkInstance instance, 38 | const VkViSurfaceCreateInfoNN* pCreateInfo, 39 | const VkAllocationCallbacks* pAllocator, 40 | VkSurfaceKHR* pSurface); 41 | #endif 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vulkan/vulkan_wayland.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_WAYLAND_H_ 2 | #define VULKAN_WAYLAND_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_KHR_wayland_surface 1 23 | #define VK_KHR_WAYLAND_SURFACE_SPEC_VERSION 6 24 | #define VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "VK_KHR_wayland_surface" 25 | typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; 26 | typedef struct VkWaylandSurfaceCreateInfoKHR { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkWaylandSurfaceCreateFlagsKHR flags; 30 | struct wl_display* display; 31 | struct wl_surface* surface; 32 | } VkWaylandSurfaceCreateInfoKHR; 33 | 34 | typedef VkResult (VKAPI_PTR *PFN_vkCreateWaylandSurfaceKHR)(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 35 | typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display* display); 36 | 37 | #ifndef VK_NO_PROTOTYPES 38 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR( 39 | VkInstance instance, 40 | const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, 41 | const VkAllocationCallbacks* pAllocator, 42 | VkSurfaceKHR* pSurface); 43 | 44 | VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR( 45 | VkPhysicalDevice physicalDevice, 46 | uint32_t queueFamilyIndex, 47 | struct wl_display* display); 48 | #endif 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vulkan/vulkan_xcb.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_XCB_H_ 2 | #define VULKAN_XCB_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_KHR_xcb_surface 1 23 | #define VK_KHR_XCB_SURFACE_SPEC_VERSION 6 24 | #define VK_KHR_XCB_SURFACE_EXTENSION_NAME "VK_KHR_xcb_surface" 25 | typedef VkFlags VkXcbSurfaceCreateFlagsKHR; 26 | typedef struct VkXcbSurfaceCreateInfoKHR { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkXcbSurfaceCreateFlagsKHR flags; 30 | xcb_connection_t* connection; 31 | xcb_window_t window; 32 | } VkXcbSurfaceCreateInfoKHR; 33 | 34 | typedef VkResult (VKAPI_PTR *PFN_vkCreateXcbSurfaceKHR)(VkInstance instance, const VkXcbSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 35 | typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id); 36 | 37 | #ifndef VK_NO_PROTOTYPES 38 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR( 39 | VkInstance instance, 40 | const VkXcbSurfaceCreateInfoKHR* pCreateInfo, 41 | const VkAllocationCallbacks* pAllocator, 42 | VkSurfaceKHR* pSurface); 43 | 44 | VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR( 45 | VkPhysicalDevice physicalDevice, 46 | uint32_t queueFamilyIndex, 47 | xcb_connection_t* connection, 48 | xcb_visualid_t visual_id); 49 | #endif 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vulkan/vulkan_xlib.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_XLIB_H_ 2 | #define VULKAN_XLIB_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_KHR_xlib_surface 1 23 | #define VK_KHR_XLIB_SURFACE_SPEC_VERSION 6 24 | #define VK_KHR_XLIB_SURFACE_EXTENSION_NAME "VK_KHR_xlib_surface" 25 | typedef VkFlags VkXlibSurfaceCreateFlagsKHR; 26 | typedef struct VkXlibSurfaceCreateInfoKHR { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkXlibSurfaceCreateFlagsKHR flags; 30 | Display* dpy; 31 | Window window; 32 | } VkXlibSurfaceCreateInfoKHR; 33 | 34 | typedef VkResult (VKAPI_PTR *PFN_vkCreateXlibSurfaceKHR)(VkInstance instance, const VkXlibSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 35 | typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display* dpy, VisualID visualID); 36 | 37 | #ifndef VK_NO_PROTOTYPES 38 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR( 39 | VkInstance instance, 40 | const VkXlibSurfaceCreateInfoKHR* pCreateInfo, 41 | const VkAllocationCallbacks* pAllocator, 42 | VkSurfaceKHR* pSurface); 43 | 44 | VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR( 45 | VkPhysicalDevice physicalDevice, 46 | uint32_t queueFamilyIndex, 47 | Display* dpy, 48 | VisualID visualID); 49 | #endif 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/vulkan/vulkan_xlib_xrandr.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_XLIB_XRANDR_H_ 2 | #define VULKAN_XLIB_XRANDR_H_ 1 3 | 4 | /* 5 | ** Copyright 2015-2023 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_EXT_acquire_xlib_display 1 23 | #define VK_EXT_ACQUIRE_XLIB_DISPLAY_SPEC_VERSION 1 24 | #define VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME "VK_EXT_acquire_xlib_display" 25 | typedef VkResult (VKAPI_PTR *PFN_vkAcquireXlibDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, VkDisplayKHR display); 26 | typedef VkResult (VKAPI_PTR *PFN_vkGetRandROutputDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, RROutput rrOutput, VkDisplayKHR* pDisplay); 27 | 28 | #ifndef VK_NO_PROTOTYPES 29 | VKAPI_ATTR VkResult VKAPI_CALL vkAcquireXlibDisplayEXT( 30 | VkPhysicalDevice physicalDevice, 31 | Display* dpy, 32 | VkDisplayKHR display); 33 | 34 | VKAPI_ATTR VkResult VKAPI_CALL vkGetRandROutputDisplayEXT( 35 | VkPhysicalDevice physicalDevice, 36 | Display* dpy, 37 | RROutput rrOutput, 38 | VkDisplayKHR* pDisplay); 39 | #endif 40 | 41 | #ifdef __cplusplus 42 | } 43 | #endif 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Yuriy O'Donnell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # librush 2 | Graphics prototyping framework 3 | -------------------------------------------------------------------------------- /Rush/.clang-format: -------------------------------------------------------------------------------- 1 | AccessModifierOffset: -4 2 | AlignAfterOpenBracket: false 3 | AlignConsecutiveAssignments: true 4 | AlignConsecutiveDeclarations: true 5 | AlignEscapedNewlinesLeft: false 6 | AlignOperands: true 7 | AlignTrailingComments: true 8 | AllowAllParametersOfDeclarationOnNextLine: true 9 | AllowShortBlocksOnASingleLine: true 10 | AllowShortCaseLabelsOnASingleLine: true 11 | AllowShortFunctionsOnASingleLine: All 12 | AllowShortIfStatementsOnASingleLine: false 13 | AllowShortLoopsOnASingleLine: false 14 | AlwaysBreakAfterDefinitionReturnType: false 15 | AlwaysBreakBeforeMultilineStrings: false 16 | AlwaysBreakTemplateDeclarations: false 17 | BasedOnStyle: LLVM 18 | BinPackArguments: true 19 | BinPackParameters: true 20 | BreakBeforeBinaryOperators: None 21 | BreakBeforeBraces: Allman 22 | BreakBeforeTernaryOperators: true 23 | BreakConstructorInitializersBeforeComma: true 24 | ColumnLimit: 120 25 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 26 | ConstructorInitializerIndentWidth: 0 27 | ContinuationIndentWidth: 4 28 | Cpp11BracedListStyle: true 29 | DerivePointerAlignment: false 30 | DisableFormat: false 31 | ExperimentalAutoDetectBinPacking: true 32 | IndentCaseLabels: false 33 | IndentFunctionDeclarationAfterType: false 34 | IndentWidth: 4 35 | IndentWrappedFunctionNames: false 36 | KeepEmptyLinesAtTheStartOfBlocks: true 37 | Language: Cpp 38 | MaxEmptyLinesToKeep: 1 39 | NamespaceIndentation: None 40 | PenaltyBreakBeforeFirstCallParameter: 19 41 | PenaltyBreakComment: 300 42 | PenaltyBreakFirstLessLess: 120 43 | PenaltyBreakString: 1000 44 | PenaltyExcessCharacter: 1000000 45 | PenaltyReturnTypeOnItsOwnLine: 60 46 | PointerAlignment: Left 47 | SpaceAfterCStyleCast: false 48 | SpaceBeforeAssignmentOperators: true 49 | SpaceBeforeParens: ControlStatements 50 | SpaceInEmptyParentheses: false 51 | SpacesBeforeTrailingComments: 1 52 | SpacesInAngles: false 53 | SpacesInContainerLiterals: true 54 | SpacesInCStyleCastParentheses: false 55 | SpacesInParentheses: false 56 | SpacesInSquareBrackets: false 57 | Standard: Cpp11 58 | TabWidth: 4 59 | UseTab: ForIndentation 60 | -------------------------------------------------------------------------------- /Rush/GfxBitmapFont.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rush.h" 4 | 5 | #include "GfxCommon.h" 6 | #include "GfxPrimitiveBatch.h" 7 | #include "UtilArray.h" 8 | 9 | namespace Rush 10 | { 11 | class DataStream; 12 | 13 | // Class for working with AngelCode BMFont files. 14 | // More details here: http://www.angelcode.com/products/bmfont/ 15 | // Current simple implementation is only suitable for ASCI single-byte encoding. 16 | class BitmapFontDesc 17 | { 18 | public: 19 | enum 20 | { 21 | MaxFontPages = 16, 22 | InvalidPage = 0xFF 23 | }; 24 | 25 | struct CharData 26 | { 27 | u16 x, y, width, height; 28 | s16 offsetX, offsetY, advanceX; 29 | u8 page, chan; 30 | }; 31 | 32 | struct PageData 33 | { 34 | char filename[128]; 35 | }; 36 | 37 | BitmapFontDesc(); 38 | 39 | bool read(DataStream& stream); 40 | 41 | CharData m_chars[256]; 42 | PageData m_pages[MaxFontPages]; 43 | u32 m_pageCount; 44 | u32 m_size; 45 | }; 46 | 47 | struct BitmapFontData 48 | { 49 | BitmapFontDesc font; 50 | DynamicArray pixels; 51 | u32 width = 0; 52 | u32 height = 0; 53 | }; 54 | 55 | class BitmapFontRenderer 56 | { 57 | public: 58 | BitmapFontRenderer(const BitmapFontData& data); 59 | BitmapFontRenderer(const void* headerData, size_t headerSize, const void* pixelsData, size_t pixelsSize, u32 width, 60 | u32 height, GfxFormat format); 61 | ~BitmapFontRenderer(); 62 | 63 | // returns position after the last drawn character 64 | Vec2 draw(PrimitiveBatch* batch, const Vec2& pos, const char* str, ColorRGBA8 col = ColorRGBA8::White(), 65 | bool flush = true); 66 | 67 | // returns the width and height of the text block in pixels 68 | Vec2 measure(const char* str); 69 | 70 | static BitmapFontData createEmbeddedFont(bool shadow = true, u32 padX = 0, u32 padY = 0); 71 | 72 | void setScale(Vec2 scale) { m_scale = scale; }; 73 | void setScale(float scale) { m_scale = Vec2(scale); }; 74 | 75 | const BitmapFontDesc& getFontDesc() const { return m_fontDesc; } 76 | const DynamicArray>& getTextures() const { return m_textures; } 77 | const DynamicArray& getTextureDescs() const { return m_textureDesc; } 78 | const TexturedQuad2D* getCharQuads() const { return m_chars; } 79 | Vec2 GetScale() const { return m_scale; } 80 | 81 | private: 82 | void createSprites(); 83 | 84 | private: 85 | BitmapFontDesc m_fontDesc; 86 | DynamicArray> m_textures; 87 | DynamicArray m_textureDesc; 88 | TexturedQuad2D m_chars[256]; 89 | Vec2 m_scale; 90 | }; 91 | 92 | // Draw characters into a 32bpp RGBA bitmap. 93 | // Only code-page 437 characters ' ' (32) to '~' (126) are supported. 94 | // Tabs, line breaks, etc.are not handled. An empty space will be emitted for unsupported characters. 95 | void EmbeddedFont_Blit6x8(u32* output, u32 width, u32 Color, const char* str); 96 | } 97 | -------------------------------------------------------------------------------- /Rush/GfxDeviceMtl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GfxDevice.h" 4 | 5 | #if RUSH_RENDER_API == RUSH_RENDER_API_MTL 6 | 7 | #include "UtilResourcePool.h" 8 | #include "Window.h" 9 | 10 | #import 11 | #import 12 | #import 13 | #import 14 | 15 | namespace Rush 16 | { 17 | 18 | struct ShaderMTL : GfxRefCount 19 | { 20 | u32 uniqueId = 0; 21 | 22 | id library = nil; 23 | id function = nil; 24 | 25 | static ShaderMTL create(const GfxShaderSource& code); 26 | void destroy(); 27 | }; 28 | 29 | struct VertexFormatMTL : GfxRefCount 30 | { 31 | u32 uniqueId = 0; 32 | GfxVertexFormatDesc desc; 33 | MTLVertexDescriptor* native = nil; 34 | void destroy(); 35 | }; 36 | 37 | struct BufferMTL : GfxRefCount 38 | { 39 | u32 uniqueId = 0; 40 | id native = nil; 41 | u32 stride = 0; 42 | MTLIndexType indexType = MTLIndexTypeUInt32; 43 | 44 | void destroy(); 45 | }; 46 | 47 | struct DescriptorSetMTL : GfxRefCount 48 | { 49 | u32 uniqueId = 0; 50 | GfxDescriptorSetDesc desc; 51 | DynamicArray constantBufferOffsets; 52 | DynamicArray constantBuffers; 53 | DynamicArray textures; 54 | DynamicArray samplers; 55 | DynamicArray storageImages; 56 | DynamicArray storageBuffers; 57 | 58 | id encoder = nil; // #todo: pool argument encoders by descriptor set desc 59 | id argBuffer = nil; 60 | u32 argBufferOffset = 0; // #todo: pool and sub-allocate arg buffers 61 | u32 argBufferSize = 0; 62 | 63 | void destroy(); 64 | }; 65 | 66 | struct TechniqueMTL : GfxRefCount 67 | { 68 | u32 uniqueId = 0; 69 | 70 | GfxTechniqueDesc desc; 71 | 72 | GfxRef vf; 73 | GfxRef vs; 74 | GfxRef ps; 75 | 76 | id computePipeline = nil; 77 | 78 | u32 constantBufferOffset = 0; 79 | u32 samplerOffset = 0; 80 | u32 sampledImageOffset = 0; 81 | u32 storageImageOffset = 0; 82 | u32 storageBufferOffset = 0; 83 | u32 descriptorSetCount = 0; 84 | 85 | Tuple3 workGroupSize = {}; 86 | 87 | DescriptorSetMTL defaultDescriptorSet; 88 | 89 | void destroy(); 90 | }; 91 | 92 | struct DepthStencilStateMTL : GfxRefCount 93 | { 94 | u32 uniqueId = 0; 95 | id native = nil; 96 | void destroy(); 97 | }; 98 | 99 | struct RasterizerStateMTL : GfxRefCount 100 | { 101 | u32 uniqueId = 0; 102 | GfxRasterizerDesc desc; 103 | void destroy(); 104 | }; 105 | 106 | struct TextureMTL : GfxRefCount 107 | { 108 | u32 uniqueId = 0; 109 | id native = nil; 110 | GfxTextureDesc desc; 111 | static TextureMTL create(const GfxTextureDesc& desc, const GfxTextureData* data, u32 count, const void* pixels); 112 | void destroy(); 113 | }; 114 | 115 | struct BlendStateMTL : GfxRefCount 116 | { 117 | u32 uniqueId = 0; 118 | GfxBlendStateDesc desc; 119 | void destroy(); 120 | }; 121 | 122 | struct SamplerMTL : GfxRefCount 123 | { 124 | u32 uniqueId = 0; 125 | id native = nil; 126 | void destroy(); 127 | }; 128 | 129 | class GfxDevice : public GfxRefCount 130 | { 131 | public: 132 | 133 | GfxDevice(Window* window, const GfxConfig& cfg); 134 | ~GfxDevice(); 135 | 136 | u32 generateId(); 137 | 138 | void beginFrame(); 139 | void createDefaultDepthBuffer(u32 width, u32 height); 140 | 141 | id m_metalDevice = nil; 142 | id m_commandQueue = nil; 143 | CAMetalLayer* m_metalLayer = nil; 144 | 145 | ResourcePool m_vertexShaders; 146 | ResourcePool m_pixelShaders; 147 | ResourcePool m_computeShaders; 148 | ResourcePool m_vertexFormats; 149 | ResourcePool m_buffers; 150 | ResourcePool m_techniques; 151 | ResourcePool m_depthStencilStates; 152 | ResourcePool m_rasterizerStates; 153 | ResourcePool m_textures; 154 | ResourcePool m_blendStates; 155 | ResourcePool m_samplers; 156 | ResourcePool m_descriptorSets; 157 | 158 | template 159 | static GfxOwn makeOwn(HandleType h) { return GfxOwn(h); } 160 | 161 | Window* m_window = nullptr; 162 | WindowEventListener m_resizeEvents; 163 | 164 | GfxCapability m_caps; 165 | GfxStats m_stats; 166 | 167 | u32 m_uniqueResourceCounter = 1; 168 | 169 | id m_drawable = nil; 170 | id m_backBufferTexture = nil; 171 | MTLPixelFormat m_backBufferPixelFormat = MTLPixelFormatInvalid; 172 | id m_commandBuffer = nil; 173 | 174 | GfxRef m_defaultDepthBuffer; 175 | }; 176 | 177 | class GfxContext : public GfxRefCount 178 | { 179 | public: 180 | 181 | enum 182 | { 183 | MaxSampledImages = 16, 184 | MaxStorageImages = 8, 185 | MaxVertexStreams = 8, 186 | MaxConstantBuffers = 4, 187 | MaxStorageBuffers = 4, 188 | MaxSamplers = 4, 189 | MaxDescriptorSets = 4, 190 | }; 191 | 192 | GfxContext(); 193 | ~GfxContext(); 194 | 195 | void applyState(); 196 | 197 | enum DirtyStateFlag 198 | { 199 | DirtyStateFlag_Technique = 1 << 0, 200 | DirtyStateFlag_PrimitiveType = 1 << 1, 201 | DirtyStateFlag_VertexBuffer = 1 << 2, 202 | DirtyStateFlag_IndexBuffer = 1 << 3, 203 | DirtyStateFlag_Texture = 1 << 4, 204 | DirtyStateFlag_BlendState = 1 << 5, 205 | DirtyStateFlag_DepthStencilState = 1 << 6, 206 | DirtyStateFlag_RasterizerState = 1 << 7, 207 | DirtyStateFlag_Sampler = 1 << 8, 208 | DirtyStateFlag_ConstantBuffer = 1 << 9, 209 | DirtyStateFlag_StorageImage = 1 << 10, 210 | DirtyStateFlag_StorageBuffer = 1 << 11, 211 | DirtyStateFlag_DescriptorSet = 1 << 12, 212 | 213 | DirtyStateFlag_Descriptors = DirtyStateFlag_ConstantBuffer | DirtyStateFlag_Texture | DirtyStateFlag_Sampler | DirtyStateFlag_StorageImage | DirtyStateFlag_StorageBuffer, 214 | 215 | DirtyStateFlag_Pipeline = DirtyStateFlag_Technique | DirtyStateFlag_PrimitiveType | DirtyStateFlag_BlendState | DirtyStateFlag_DepthStencilState | DirtyStateFlag_RasterizerState, 216 | }; 217 | 218 | u32 m_dirtyState = 0xFFFFFFFF; 219 | 220 | id m_commandEncoder = nil; 221 | id m_computeCommandEncoder = nil; 222 | id m_depthStencilState = nil; 223 | 224 | GfxRef m_pendingTechnique; 225 | GfxRef m_pendingBlendState; 226 | GfxRef m_pendingRasterizerState; 227 | GfxRef m_pendingDepthStencilState; 228 | GfxRef m_constantBuffers[MaxConstantBuffers]; 229 | u32 m_constantBufferOffsets[MaxConstantBuffers] = {}; 230 | GfxRef m_samplers[MaxSamplers]; 231 | GfxRef m_sampledImages[MaxSampledImages]; 232 | GfxRef m_storageImages[MaxStorageImages]; 233 | GfxRef m_storageBuffers[MaxStorageBuffers]; 234 | GfxRef m_descriptorSets[MaxDescriptorSets]; 235 | GfxPassDesc m_passDesc; 236 | 237 | MTLIndexType m_indexType = MTLIndexTypeUInt32; 238 | u32 m_indexStride = 4; 239 | id m_indexBuffer = nil; 240 | 241 | MTLPrimitiveType m_primitiveType = MTLPrimitiveTypeTriangle; 242 | MTLPrimitiveTopologyClass m_primitiveTopology = MTLPrimitiveTopologyClassUnspecified; 243 | 244 | }; 245 | 246 | } 247 | 248 | #endif 249 | -------------------------------------------------------------------------------- /Rush/GfxEmbeddedShaders.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | // clang-format off 4 | namespace Rush 5 | { 6 | extern const unsigned char SPV_psMain_data[]; 7 | extern const size_t SPV_psMain_size; 8 | extern const unsigned char SPV_psMainTextured_data[]; 9 | extern const size_t SPV_psMainTextured_size; 10 | extern const unsigned char SPV_vsMain3D_data[]; 11 | extern const size_t SPV_vsMain3D_size; 12 | extern const unsigned char SPV_vsMain2D_data[]; 13 | extern const size_t SPV_vsMain2D_size; 14 | extern const unsigned char DXBC_psMain_data[]; 15 | extern const size_t DXBC_psMain_size; 16 | extern const unsigned char DXBC_psMainTextured_data[]; 17 | extern const size_t DXBC_psMainTextured_size; 18 | extern const unsigned char DXBC_vsMain3D_data[]; 19 | extern const size_t DXBC_vsMain3D_size; 20 | extern const unsigned char DXBC_vsMain2D_data[]; 21 | extern const size_t DXBC_vsMain2D_size; 22 | } -------------------------------------------------------------------------------- /Rush/GfxEmbeddedShadersMSL.cpp: -------------------------------------------------------------------------------- 1 | #include "GfxEmbeddedShaders.h" 2 | 3 | namespace Rush 4 | { 5 | 6 | const char* MSL_EmbeddedShaders = R"( 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace metal; 12 | 13 | struct Constants 14 | { 15 | float4x4 matViewProj; 16 | float4 transform2D; 17 | float4 color; 18 | }; 19 | 20 | struct VSInput 21 | { 22 | float3 pos [[attribute(0)]]; 23 | float2 tex [[attribute(1)]]; 24 | float4 col [[attribute(2)]]; 25 | }; 26 | 27 | struct PSInput 28 | { 29 | float2 tex [[attribute(0)]]; 30 | float4 col [[attribute(1)]]; 31 | }; 32 | 33 | struct VSOutput 34 | { 35 | float4 pos [[position]]; 36 | float2 tex; 37 | float4 col; 38 | }; 39 | 40 | struct ResourcesPlain 41 | { 42 | constant Constants* cb [[id(0)]]; 43 | }; 44 | 45 | struct ResourcesTextured 46 | { 47 | constant Constants* cb [[id(0)]]; 48 | sampler s [[id(1)]]; 49 | texture2d t [[id(2)]]; 50 | }; 51 | 52 | vertex VSOutput vsMain3D( 53 | VSInput v [[stage_in]], 54 | constant ResourcesPlain& resources [[buffer(0)]]) 55 | { 56 | VSOutput res; 57 | res.pos = float4(v.pos, 1) * resources.cb->matViewProj; 58 | res.col = v.col * resources.cb->color; 59 | res.tex = v.tex; 60 | return res; 61 | } 62 | 63 | vertex VSOutput vsMain2D( 64 | VSInput v [[stage_in]], 65 | constant ResourcesPlain& resources [[buffer(0)]]) 66 | { 67 | VSOutput res; 68 | res.pos.xy = v.pos.xy * resources.cb->transform2D.xy + resources.cb->transform2D.zw; 69 | res.pos.zw = float2(v.pos.z, 1); 70 | res.col = v.col * resources.cb->color; 71 | res.tex = v.tex; 72 | return res; 73 | } 74 | 75 | fragment float4 psMain( 76 | PSInput v [[stage_in]], 77 | constant ResourcesPlain& resources [[buffer(0)]]) 78 | { 79 | return v.col; 80 | } 81 | 82 | fragment float4 psMainTextured( 83 | PSInput v [[stage_in]], 84 | constant ResourcesTextured& resources [[buffer(0)]]) 85 | { 86 | return v.col * resources.t.sample(resources.s, v.tex); 87 | } 88 | )"; 89 | 90 | } 91 | -------------------------------------------------------------------------------- /Rush/GfxPrimitiveBatch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GfxDevice.h" 4 | #include "MathTypes.h" 5 | #include "UtilColor.h" 6 | #include "UtilLinearAllocator.h" 7 | #include "UtilArray.h" 8 | #include "UtilTuple.h" 9 | 10 | namespace Rush 11 | { 12 | struct TexturedQuad2D 13 | { 14 | Vec2 pos[4]; 15 | Vec2 tex[4]; 16 | }; 17 | 18 | struct TexturedQuad3D 19 | { 20 | Vec3 pos[4]; 21 | Vec2 tex[4]; 22 | }; 23 | 24 | class PrimitiveBatch 25 | { 26 | public: 27 | enum SamplerState 28 | { 29 | SamplerState_Point, 30 | SamplerState_Linear, 31 | 32 | SamplerState_COUNT 33 | }; 34 | 35 | enum BatchMode 36 | { 37 | BatchMode_Invalid, 38 | BatchMode_2D, 39 | BatchMode_3D, 40 | 41 | BatchMode_COUNT 42 | }; 43 | 44 | struct BatchVertex 45 | { 46 | Vec3 pos; 47 | Vec2 tex; 48 | ColorRGBA8 col; 49 | }; 50 | 51 | public: 52 | PrimitiveBatch(u32 maxBatchVertices = 12000); 53 | ~PrimitiveBatch(); 54 | 55 | Vec4 getTransform2D() const { return m_constants.transform2D; } 56 | const Mat4& getViewProjMatrix() const { return m_constants.viewProjMatrix; } 57 | 58 | void begin2D(const Vec2& scale, const Vec2& bias); 59 | void begin2D(float width, float height); 60 | void begin2D(const Tuple2i& size) { begin2D((float)size.x, (float)size.y); } 61 | void begin2D(const Tuple2u& size) { begin2D((float)size.x, (float)size.y); } 62 | void begin2D(const Tuple2f& size) { begin2D(size.x, size.y); } 63 | void begin2D(const Vec2& size) { begin2D(size.x, size.y); } 64 | void begin2D(const Box2& bounds); 65 | void end2D(); 66 | 67 | void begin3D(const Mat4& viewProjMatrix); 68 | void end3D(); 69 | 70 | void setColor(ColorRGBA color); 71 | void setTexture(GfxTextureArg tex); 72 | void setSampler(GfxSamplerArg smp); 73 | void setSampler(SamplerState smp); 74 | void setPrimitive(GfxPrimitive prim); 75 | 76 | void drawLine(float ax, float ay, float bx, float by, const ColorRGBA8& color = ColorRGBA8::White()); 77 | void drawLine( 78 | float ax, float ay, float az, float bx, float by, float bz, const ColorRGBA8& color = ColorRGBA8::White()); 79 | void drawLine(const Vec2& a, const Vec2& b, const ColorRGBA8& color = ColorRGBA8::White()); 80 | void drawLine(const Vec3& a, const Vec3& b, const ColorRGBA8& color = ColorRGBA8::White()); 81 | void drawLine(const Line2& line, const ColorRGBA8& color = ColorRGBA8::White()); 82 | void drawLine(const Line2& line, const ColorRGBA8& colorStart, const ColorRGBA8& colorEnd); 83 | void drawLine(const Line3& line, const ColorRGBA8& color = ColorRGBA8::White()); 84 | void drawLine(const Line3& line, const ColorRGBA8& colorStart, const ColorRGBA8& colorEnd); 85 | void drawRect(const Box2& rect, const ColorRGBA8& color = ColorRGBA8::White()); 86 | 87 | void drawTriangle(const Vec2& a, const Vec2& b, const Vec2& c, const ColorRGBA8& color); 88 | void drawTriangle(const Vec2& pa, const Vec2& pb, const Vec2& pc, const ColorRGBA8& ca, const ColorRGBA8& cb, 89 | const ColorRGBA8& cc); 90 | 91 | void drawTriangle(const Vec3& a, const Vec3& b, const Vec3& c, const ColorRGBA8& color); 92 | void drawTriangle(const Vec3& pa, const Vec3& pb, const Vec3& pc, const ColorRGBA8& ca, const ColorRGBA8& cb, 93 | const ColorRGBA8& cc); 94 | 95 | void drawTexturedQuad(const Box2& rect, ColorRGBA8 color = ColorRGBA8::White()); 96 | void drawTexturedQuad(const TexturedQuad2D* q, ColorRGBA8 color = ColorRGBA8::White()); 97 | void drawTexturedQuad(const TexturedQuad3D* q, ColorRGBA8 color = ColorRGBA8::White()); 98 | 99 | void drawTexturedQuad(const Vec2& a, const Vec2& b, const Vec2& c, const Vec2& d, 100 | ColorRGBA8 color = ColorRGBA8::White(), const Vec2& ta = Vec2(0, 0), const Vec2& tb = Vec2(1, 0), 101 | const Vec2& tc = Vec2(1, 1), const Vec2& td = Vec2(0, 1)); 102 | 103 | void drawTexturedQuad(const Vec3& pa, const Vec3& pb, const Vec3& pc, const Vec3& pd, 104 | ColorRGBA8 color = ColorRGBA8::White(), const Vec2& ta = Vec2(0, 0), const Vec2& tb = Vec2(1, 0), 105 | const Vec2& tc = Vec2(1, 1), const Vec2& td = Vec2(0, 1)); 106 | 107 | void drawCross(const Vec3& pos, float size, const ColorRGBA8& color = ColorRGBA8::White()); 108 | void drawBox(const Box3& box, const ColorRGBA8& color = ColorRGBA8::White()); 109 | 110 | BatchVertex* drawVertices(GfxPrimitive primType, u32 vertexCount); 111 | 112 | void flush(); 113 | 114 | inline u32 getMaxBatchVertices() const { return m_maxBatchVertices; } 115 | 116 | private: 117 | GfxTechnique getNextTechnique(); 118 | 119 | GfxContext* m_context; 120 | 121 | u32 m_maxBatchVertices; 122 | BatchMode m_mode; 123 | 124 | ColorRGBA m_currColor; 125 | 126 | GfxPrimitive m_currPrim; 127 | 128 | GfxTexture m_currTexture; 129 | GfxSampler m_currSampler; 130 | 131 | GfxOwn m_samplerLiner; 132 | GfxOwn m_samplerPoint; 133 | 134 | GfxOwn m_vertexBuffer; 135 | LinearAllocator m_vertices; 136 | 137 | GfxOwn m_vertexFormat2D; 138 | GfxOwn m_vertexFormat3D; 139 | 140 | struct Constants 141 | { 142 | Mat4 viewProjMatrix; 143 | Vec4 transform2D; // xy: scale, zw: bias 144 | Vec4 color; 145 | }; 146 | Constants m_constants; 147 | GfxOwn m_constantBuffer; 148 | bool m_constantBufferDirty; 149 | 150 | GfxOwn m_vertexShader2D; 151 | GfxOwn m_vertexShader3D; 152 | 153 | GfxOwn m_pixelShaderPlain; 154 | GfxOwn m_pixelShaderTextured; 155 | 156 | enum TechniqueID 157 | { 158 | TechniqueID_Plain2D, 159 | TechniqueID_Plain3D, 160 | TechniqueID_Textured2D, 161 | TechniqueID_Textured3D, 162 | TechniqueID_COUNT 163 | }; 164 | 165 | GfxOwn m_techniques[TechniqueID_COUNT]; 166 | 167 | float m_depth; 168 | }; 169 | } 170 | -------------------------------------------------------------------------------- /Rush/MathCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rush.h" 4 | 5 | #include 6 | #include 7 | 8 | #ifdef _MSC_VER 9 | #include 10 | #endif 11 | 12 | namespace Rush 13 | { 14 | static const float Pi = 3.14159265358979323846f; 15 | static const float TwoPi = 2 * 3.14159265358979323846f; 16 | 17 | inline float toRadians(float degrees) { return degrees * 0.0174532925f; } 18 | inline float toDegrees(float radians) { return radians * 57.2957795f; } 19 | 20 | template inline T min(const T& a, const T& b) { return (a < b) ? a : b; } 21 | template inline T max(const T& a, const T& b) { return (a < b) ? b : a; } 22 | template inline T min3(const T& a, const T& b, const T& c) { return min(a, min(b, c)); } 23 | template inline T max3(const T& a, const T& b, const T& c) { return max(a, max(b, c)); } 24 | template inline T sqr(T x) { return x * x; } 25 | template inline T abs(T i) { return (i < 0) ? -i : i; } 26 | template inline T lerp(const T& a, const T& b, float alpha) { return a * (1.0f - alpha) + b * alpha; } 27 | template inline T getSign(T v) { return v < T(0) ? T(-1) : T(1); } 28 | template inline T clamp(const T& val, const T& minVal, const T& maxVal) 29 | { 30 | return min(max(val, minVal), maxVal); 31 | } 32 | inline float saturate(float val) { return clamp(val, 0.0f, 1.0f); } 33 | inline float quantize(float val, float step) { return float(int(val / step)) * step; } 34 | inline constexpr u32 alignCeiling(u32 x, u32 boundary) { return x + (~(x - 1) % boundary); } 35 | inline constexpr u32 alignFloor(u32 x, u32 boundary) { return x - (x % boundary); } 36 | inline constexpr u64 alignCeiling(u64 x, u64 boundary) { return x + (~(x - 1) % boundary); } 37 | inline constexpr u64 alignFloor(u64 x, u64 boundary) { return x - (x % boundary); } 38 | 39 | inline u32 nextPow2(u32 n) 40 | { 41 | n--; 42 | n |= n >> 1; 43 | n |= n >> 2; 44 | n |= n >> 4; 45 | n |= n >> 8; 46 | n |= n >> 16; 47 | n++; 48 | return n; 49 | }; 50 | 51 | inline u32 divUp(u32 n, u32 d) { return (n + d - 1) / d; } 52 | 53 | inline u32 bitScanForward(u32 mask) 54 | { 55 | #ifdef _MSC_VER 56 | unsigned long count; 57 | _BitScanForward(&count, mask); 58 | return count; 59 | #else 60 | return __builtin_ctz(mask); 61 | #endif 62 | } 63 | 64 | inline u32 bitScanReverse(u32 mask) 65 | { 66 | #ifdef _MSC_VER 67 | unsigned long count; 68 | _BitScanReverse(&count, mask); 69 | return 31 - count; 70 | #else 71 | return __builtin_clz(mask); 72 | #endif 73 | } 74 | 75 | inline u32 bitCount(u32 mask) 76 | { 77 | #ifdef _MSC_VER 78 | return __popcnt(mask); 79 | #else 80 | return __builtin_popcount(mask); 81 | #endif 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Rush/Platform.cpp: -------------------------------------------------------------------------------- 1 | #include "Platform.h" 2 | #include "GfxDevice.h" 3 | #include "UtilLog.h" 4 | #include "Window.h" 5 | 6 | namespace Rush 7 | { 8 | 9 | Window* g_mainWindow = nullptr; 10 | GfxDevice* g_mainGfxDevice = nullptr; 11 | GfxContext* g_mainGfxContext = nullptr; 12 | 13 | void Platform_Startup(const AppConfig& cfg) 14 | { 15 | RUSH_ASSERT(g_mainWindow == nullptr); 16 | RUSH_ASSERT(g_mainGfxDevice == nullptr); 17 | RUSH_ASSERT(g_mainGfxContext == nullptr); 18 | 19 | WindowDesc windowDesc; 20 | windowDesc.width = cfg.width; 21 | windowDesc.height = cfg.height; 22 | windowDesc.resizable = cfg.resizable; 23 | windowDesc.caption = cfg.name; 24 | windowDesc.fullScreen = cfg.fullScreen; 25 | windowDesc.maximized = cfg.maximized; 26 | 27 | Window* window = Platform_CreateWindow(windowDesc); 28 | 29 | g_mainWindow = window; 30 | 31 | GfxConfig gfxConfig; 32 | if (cfg.gfxConfig) 33 | { 34 | gfxConfig = *cfg.gfxConfig; 35 | } 36 | else 37 | { 38 | gfxConfig = GfxConfig(cfg); 39 | } 40 | g_mainGfxDevice = Gfx_CreateDevice(window, gfxConfig); 41 | g_mainGfxContext = Gfx_AcquireContext(); 42 | } 43 | 44 | void Platform_Shutdown() 45 | { 46 | RUSH_ASSERT(g_mainWindow != nullptr); 47 | RUSH_ASSERT(g_mainGfxDevice != nullptr); 48 | RUSH_ASSERT(g_mainGfxContext != nullptr); 49 | 50 | Gfx_Release(g_mainGfxContext); 51 | Gfx_Release(g_mainGfxDevice); 52 | 53 | g_mainWindow->release(); 54 | } 55 | 56 | int Platform_Main(const AppConfig& cfg) 57 | { 58 | Platform_Startup(cfg); 59 | 60 | if (cfg.onStartup) 61 | { 62 | cfg.onStartup(cfg.userData); 63 | } 64 | 65 | Platform_Run(cfg.onUpdate, cfg.userData); 66 | 67 | if (cfg.onShutdown) 68 | { 69 | cfg.onShutdown(cfg.userData); 70 | } 71 | 72 | Platform_Shutdown(); 73 | 74 | return 0; 75 | } 76 | 77 | #ifndef RUSH_PLATFORM_WINDOWS 78 | bool Platform_IsDebuggerPresent() 79 | { 80 | return false; 81 | } 82 | #endif // RUSH_PLATFORM_WINDOWS 83 | 84 | } 85 | -------------------------------------------------------------------------------- /Rush/Platform.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rush.h" 4 | 5 | namespace Rush 6 | { 7 | 8 | class GfxContext; 9 | class GfxDevice; 10 | class KeyboardState; 11 | class MouseState; 12 | class Window; 13 | struct GfxConfig; 14 | struct WindowDesc; 15 | 16 | typedef void (*PlatformCallback_Startup)(void* userData); 17 | typedef void (*PlatformCallback_Update)(void* userData); 18 | typedef void (*PlatformCallback_Shutdown)(void* userData); 19 | 20 | struct AppConfig 21 | { 22 | const char* name = "RushApp"; 23 | 24 | int vsync = 1; 25 | 26 | int width = 640; 27 | int height = 480; 28 | 29 | int maxWidth = 0; 30 | int maxHeight = 0; 31 | 32 | bool fullScreen = false; 33 | bool maximized = false; 34 | bool resizable = false; 35 | bool debug = false; 36 | bool warp = false; 37 | bool minimizeLatency = false; 38 | 39 | int argc = 0; 40 | char** argv = nullptr; 41 | 42 | const GfxConfig* gfxConfig = nullptr; 43 | 44 | void* userData = nullptr; 45 | 46 | PlatformCallback_Startup onStartup = nullptr; 47 | PlatformCallback_Update onUpdate = nullptr; 48 | PlatformCallback_Shutdown onShutdown = nullptr; 49 | }; 50 | 51 | void Platform_Startup(const AppConfig& cfg); 52 | void Platform_Run(PlatformCallback_Update frameFn, void* userData); 53 | void Platform_Shutdown(); 54 | 55 | class Application 56 | { 57 | public: 58 | virtual ~Application() = default; 59 | virtual void update() = 0; 60 | }; 61 | 62 | // Convenience wrappers over explicit startup/run/shutdown API 63 | int Platform_Main(const AppConfig& cfg); 64 | 65 | template inline int Platform_Main(AppConfig cfg) 66 | { 67 | struct Context 68 | { 69 | Application* app = nullptr; 70 | } context; 71 | 72 | AppConfig wrappedCfg = cfg; 73 | 74 | wrappedCfg.userData = &context; 75 | wrappedCfg.onStartup = [](void* context) { reinterpret_cast(context)->app = new T; }; 76 | wrappedCfg.onShutdown = [](void* context) { delete reinterpret_cast(context)->app; }; 77 | wrappedCfg.onUpdate = [](void* context) { reinterpret_cast(context)->app->update(); }; 78 | 79 | return Platform_Main(wrappedCfg); 80 | } 81 | 82 | const char* Platform_GetExecutableDirectory(); 83 | void Platform_TerminateProcess(int status); 84 | 85 | GfxDevice* Platform_GetGfxDevice(); 86 | GfxContext* Platform_GetGfxContext(); 87 | Window* Platform_GetWindow(); 88 | Window* Platform_CreateWindow(const WindowDesc& desc); 89 | 90 | bool Platform_IsDebuggerPresent(); 91 | 92 | } 93 | -------------------------------------------------------------------------------- /Rush/PlatformLinux.cpp: -------------------------------------------------------------------------------- 1 | #include "Platform.h" 2 | 3 | #ifdef RUSH_PLATFORM_LINUX 4 | 5 | #include "GfxCommon.h" 6 | #include "GfxDevice.h" 7 | #include "WindowXCB.h" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace Rush 16 | { 17 | 18 | extern Window* g_mainWindow; 19 | extern GfxDevice* g_mainGfxDevice; 20 | extern GfxContext* g_mainGfxContext; 21 | 22 | Window* Platform_CreateWindow(const WindowDesc& desc) { return new WindowXCB(desc); } 23 | 24 | void Platform_TerminateProcess(int status) { exit(status); } 25 | GfxDevice* Platform_GetGfxDevice() { return g_mainGfxDevice; } 26 | GfxContext* Platform_GetGfxContext() { return g_mainGfxContext; } 27 | Window* Platform_GetWindow() { return g_mainWindow; } 28 | 29 | const char* Platform_GetExecutableDirectory() 30 | { 31 | static bool isInitialized = false; 32 | static char path[4096] = {}; 33 | 34 | if (!isInitialized) 35 | { 36 | ssize_t writtenBytes = readlink("/proc/self/exe", path, sizeof(path)); 37 | 38 | if (writtenBytes < 0) 39 | { 40 | RUSH_LOG_ERROR("readlink(\"/proc/self/exe\") failed: %s (%d)", strerror(errno), errno); 41 | strncpy(path, ".", 2); 42 | } 43 | else if (writtenBytes == sizeof(path)) 44 | { 45 | RUSH_LOG_ERROR("readlink(\"/proc/self/exe\") failed because output buffer is too small"); 46 | strncpy(path, ".", 2); 47 | } 48 | else 49 | { 50 | size_t lastSlash = 0; 51 | for (size_t i = 0; i < sizeof(path) && path[i]; ++i) 52 | { 53 | if (path[i] == '/') 54 | lastSlash = i; 55 | } 56 | 57 | if (lastSlash != 0) 58 | { 59 | path[lastSlash] = 0; 60 | } 61 | } 62 | 63 | isInitialized = true; 64 | } 65 | 66 | return path; 67 | } 68 | 69 | void Platform_Run(PlatformCallback_Update onUpdate, void* userData) 70 | { 71 | while (g_mainWindow->isClosed() == false) 72 | { 73 | g_mainWindow->pollEvents(); 74 | 75 | Gfx_BeginFrame(); 76 | 77 | if (onUpdate) 78 | { 79 | onUpdate(userData); 80 | } 81 | 82 | Gfx_EndFrame(); 83 | Gfx_Present(); 84 | } 85 | } 86 | 87 | } 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /Rush/PlatformMac.mm: -------------------------------------------------------------------------------- 1 | #include "Platform.h" 2 | #include "WindowMac.h" 3 | #include "UtilLog.h" 4 | #include "GfxDevice.h" 5 | 6 | #if defined(RUSH_PLATFORM_MAC) 7 | 8 | #import 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace Rush; 15 | 16 | @interface AppDelegate : NSObject 17 | { 18 | bool terminated; 19 | } 20 | 21 | + (AppDelegate *)sharedDelegate; 22 | - (id)init; 23 | - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; 24 | - (bool)applicationHasTerminated; 25 | 26 | @end 27 | 28 | @implementation AppDelegate 29 | 30 | + (AppDelegate *)sharedDelegate 31 | { 32 | static id delegate = [AppDelegate new]; 33 | return delegate; 34 | } 35 | 36 | - (id)init 37 | { 38 | self = [super init]; 39 | 40 | if (nil == self) 41 | { 42 | return nil; 43 | } 44 | 45 | self->terminated = false; 46 | return self; 47 | } 48 | 49 | - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender 50 | { 51 | RUSH_UNUSED(sender); 52 | self->terminated = true; 53 | return NSTerminateCancel; 54 | } 55 | 56 | - (bool)applicationHasTerminated 57 | { 58 | return self->terminated; 59 | } 60 | 61 | @end 62 | 63 | namespace Rush 64 | { 65 | 66 | extern Window* g_mainWindow; 67 | extern GfxDevice* g_mainGfxDevice; 68 | extern GfxContext* g_mainGfxContext; 69 | 70 | Window* Platform_CreateWindow(const WindowDesc& desc) { return new WindowMac(desc); } 71 | void Platform_TerminateProcess(int status) { exit(status); } 72 | GfxDevice* Platform_GetGfxDevice() { return g_mainGfxDevice; } 73 | GfxContext* Platform_GetGfxContext() { return g_mainGfxContext; } 74 | Window* Platform_GetWindow() { return g_mainWindow; } 75 | 76 | const char* Platform_GetExecutableDirectory() 77 | { 78 | constexpr u32 maxLength = PATH_MAX + 1; 79 | static char result[maxLength]; 80 | if (result[0] == 0) 81 | { 82 | u32 resultLength = maxLength; 83 | _NSGetExecutablePath(result, &resultLength); 84 | size_t lastSlash = std::string_view(result, resultLength).find_last_of("/"); 85 | if (lastSlash != std::string::npos) 86 | { 87 | result[lastSlash] = 0; 88 | } 89 | } 90 | return result; 91 | } 92 | 93 | void Platform_Run(PlatformCallback_Update onUpdate, void* userData) 94 | { 95 | @autoreleasepool 96 | { 97 | [NSApplication sharedApplication]; 98 | 99 | id dg = [AppDelegate sharedDelegate]; 100 | [NSApp setDelegate:dg]; 101 | [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; 102 | [NSApp activateIgnoringOtherApps:YES]; 103 | [NSApp finishLaunching]; 104 | 105 | [[NSNotificationCenter defaultCenter] 106 | postNotificationName:NSApplicationWillFinishLaunchingNotification 107 | object:NSApp]; 108 | 109 | [[NSNotificationCenter defaultCenter] 110 | postNotificationName:NSApplicationDidFinishLaunchingNotification 111 | object:NSApp]; 112 | 113 | id quitMenuItem = [[NSMenuItem new] 114 | initWithTitle:@"Quit" 115 | action:@selector(terminate:) 116 | keyEquivalent:@"q"]; 117 | 118 | id appMenu = [[NSMenu new] autorelease]; 119 | [appMenu addItem:quitMenuItem]; 120 | 121 | id appMenuItem = [[NSMenuItem new] autorelease]; 122 | [appMenuItem setSubmenu:appMenu]; 123 | 124 | id menubar = [[NSMenu new] autorelease]; 125 | [menubar addItem:appMenuItem]; 126 | [NSApp setMainMenu:menubar]; 127 | 128 | while (![dg applicationHasTerminated]) 129 | { 130 | @autoreleasepool 131 | { 132 | while (NSEvent* event = [NSApp 133 | nextEventMatchingMask:NSEventMaskAny 134 | untilDate:[NSDate distantPast] 135 | inMode:NSDefaultRunLoopMode 136 | dequeue:YES]) 137 | { 138 | WindowMac* window = reinterpret_cast(g_mainWindow); 139 | window->processEvent(event); 140 | [NSApp sendEvent:event]; 141 | [NSApp updateWindows]; 142 | } 143 | 144 | Gfx_BeginFrame(); 145 | if (onUpdate) 146 | { 147 | onUpdate(userData); 148 | } 149 | Gfx_EndFrame(); 150 | Gfx_Present(); 151 | } 152 | } 153 | } 154 | } 155 | 156 | } 157 | #endif 158 | -------------------------------------------------------------------------------- /Rush/PlatformWin32.cpp: -------------------------------------------------------------------------------- 1 | #include "Platform.h" 2 | 3 | #ifdef RUSH_PLATFORM_WINDOWS 4 | 5 | #include "GfxCommon.h" 6 | #include "GfxDevice.h" 7 | #include "WindowWin32.h" 8 | 9 | #include 10 | #include 11 | 12 | namespace Rush 13 | { 14 | 15 | extern Window* g_mainWindow; 16 | extern GfxDevice* g_mainGfxDevice; 17 | extern GfxContext* g_mainGfxContext; 18 | 19 | Window* Platform_CreateWindow(const WindowDesc& desc) { return new WindowWin32(desc); } 20 | 21 | void Platform_TerminateProcess(int status) { exit(status); } 22 | GfxDevice* Platform_GetGfxDevice() { return g_mainGfxDevice; } 23 | GfxContext* Platform_GetGfxContext() { return g_mainGfxContext; } 24 | Window* Platform_GetWindow() { return g_mainWindow; } 25 | 26 | const char* Platform_GetExecutableDirectory() 27 | { 28 | static char path[1024] = {}; 29 | 30 | if (!path[0]) 31 | { 32 | GetModuleFileNameA(nullptr, path, sizeof(path)); 33 | 34 | size_t pathLen = strlen(path); 35 | size_t slashIdx = (size_t)-1; 36 | for (size_t i = pathLen - 1; i > 0; --i) 37 | { 38 | if (path[i] == '/' || path[i] == '\\') 39 | { 40 | slashIdx = i; 41 | break; 42 | } 43 | } 44 | 45 | if (slashIdx != size_t(-1)) 46 | { 47 | path[slashIdx] = 0; 48 | } 49 | } 50 | 51 | return path; 52 | } 53 | 54 | void Platform_Run(PlatformCallback_Update onUpdate, void* userData) 55 | { 56 | while (g_mainWindow->isClosed() == false) 57 | { 58 | Gfx_BeginFrame(); 59 | 60 | MSG msg; 61 | while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) 62 | { 63 | TranslateMessage(&msg); 64 | DispatchMessage(&msg); 65 | } 66 | 67 | if (onUpdate) 68 | { 69 | onUpdate(userData); 70 | } 71 | 72 | Gfx_EndFrame(); 73 | Gfx_Present(); 74 | } 75 | } 76 | 77 | bool Platform_IsDebuggerPresent() 78 | { 79 | return IsDebuggerPresent(); 80 | } 81 | 82 | } 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /Rush/Rush.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | // clang-format off 7 | 8 | // Auto-detect platform 9 | 10 | #if !defined(RUSH_PLATFORM_WINDOWS) \ 11 | && !defined(RUSH_PLATFORM_LINUX) \ 12 | && !defined(RUSH_PLATFORM_MAC) \ 13 | && !defined(RUSH_PLATFORM_IOS) \ 14 | && !defined(RUSH_PLATFORM_RPI) \ 15 | && !defined(RUSH_PLATFORM_EMSCRIPTEN) \ 16 | && !defined(RUSH_PLATFORM_EXTERNAL) 17 | # if defined(_WIN32) 18 | # define RUSH_PLATFORM_WINDOWS 19 | # endif 20 | # if defined(__linux__) 21 | # define RUSH_PLATFORM_LINUX 22 | # endif 23 | # if defined(__APPLE__) 24 | # if defined(__MACH__) 25 | # define RUSH_PLATFORM_MAC 26 | # else 27 | # define RUSH_PLATFORM_IOS 28 | # endif 29 | # endif 30 | #endif 31 | 32 | // Common macros 33 | 34 | #if !defined(NDEBUG) && !defined(RUSH_DEBUG) 35 | # define RUSH_DEBUG 36 | #endif 37 | 38 | #define RUSH_RESTRICT __restrict 39 | #define RUSH_COUNTOF(x) (sizeof(x)/sizeof(x[0])) 40 | #define RUSH_UNUSED( v ) { (void)sizeof(v); } 41 | #define RUSH_DISALLOW_COPY_AND_ASSIGN(T) T(const T&) = delete; void operator=(const T&) = delete; 42 | #define RUSH_IMPLEMENT_FLAG_OPERATORS(T, S) \ 43 | inline T operator^(T a, T b) { return (T)(static_cast(a) ^ static_cast(b)); } \ 44 | inline T operator&(T a, T b) { return (T)(static_cast(a) & static_cast(b)); } \ 45 | inline T operator|(T a, T b) { return (T)(static_cast(a) | static_cast(b)); } \ 46 | inline bool operator!(T a) { return !static_cast(a); } 47 | 48 | #if defined(_MSC_VER) 49 | # define RUSH_ASSUME(x) __assume(x) 50 | # define RUSH_BREAK {__debugbreak();} 51 | # define RUSH_DISABLE_OPTIMIZATION __pragma(optimize("", off)) 52 | # define RUSH_ENABLE_OPTIMIZATION __pragma(optimize("", on)) 53 | # define RUSH_FORCEINLINE __forceinline 54 | # define RUSH_FUNCTION __func__ 55 | # define RUSH_NOINLINE __declspec(noinline) 56 | #elif defined(__GNUC__) 57 | # define RUSH_ASSUME(x) __builtin_assume(x) 58 | # define RUSH_BREAK {__builtin_trap();} 59 | # define RUSH_DISABLE_OPTIMIZATION _Pragma("clang optimize off") 60 | # define RUSH_ENABLE_OPTIMIZATION _Pragma("clang optimize on") 61 | # define RUSH_FORCEINLINE __attribute__((always_inline)) inline 62 | # define RUSH_FUNCTION __func__ 63 | # define RUSH_NOINLINE __attribute__((noinline)) 64 | #endif 65 | 66 | // Common types 67 | 68 | namespace Rush 69 | { 70 | 71 | typedef uint8_t u8; 72 | typedef uint16_t u16; 73 | typedef uint32_t u32; 74 | typedef uint64_t u64; 75 | 76 | typedef int8_t s8; 77 | typedef int16_t s16; 78 | typedef int32_t s32; 79 | typedef int64_t s64; 80 | 81 | } 82 | 83 | #ifdef RUSH_PLATFORM_EXTERNAL 84 | #include 85 | #endif //RUSH_PLATFORM_EXTERNAL 86 | 87 | #ifdef RUSH_USING_NAMESPACE 88 | using namespace Rush; 89 | #endif //RUSH_USING_NAMESPACE 90 | -------------------------------------------------------------------------------- /Rush/Rush.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{x={x} y={y} z={z} w={w}}} 5 | 6 | 7 | {{x={x} y={y} z={z} w={w}}} 8 | 9 | 10 | {{size={m_buffer.m_size} capacity={m_buffer.m_capacity} data={(const void*)m_buffer.m_data}}} 11 | 12 | 13 | m_buffer.m_size 14 | m_buffer.m_data 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Rush/UtilArray.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rush.h" 4 | #include "UtilBuffer.h" 5 | #include 6 | 7 | namespace Rush 8 | { 9 | 10 | template 11 | class DynamicArray 12 | { 13 | public: 14 | 15 | DynamicArray() = default; 16 | 17 | DynamicArray(size_t size) 18 | : DynamicArray() 19 | { 20 | resize(size); 21 | } 22 | 23 | DynamicArray(size_t size, const T& defaultValue) 24 | : DynamicArray() 25 | { 26 | static_assert(std::is_copy_constructible::value, "Type must be copy-constructible"); 27 | resize(size, defaultValue); 28 | } 29 | 30 | DynamicArray(const DynamicArray& other) 31 | : DynamicArray() 32 | { 33 | Buffer::reserve(m_buffer, other.m_buffer.m_size); 34 | Buffer::constructCopyRange(begin(), other.begin(), other.end()); 35 | m_buffer.m_size = other.m_buffer.m_size; 36 | } 37 | 38 | DynamicArray(DynamicArray&& other) noexcept 39 | : DynamicArray() 40 | { 41 | if (&other != this) 42 | { 43 | m_buffer = other.m_buffer; 44 | other.m_buffer = Buffer(); 45 | } 46 | } 47 | 48 | DynamicArray& operator = (const DynamicArray& other) 49 | { 50 | if (&other != this) 51 | { 52 | clear(); 53 | Buffer::reserve(m_buffer, other.m_buffer.m_size); 54 | Buffer::constructCopyRange(begin(), other.begin(), other.end()); 55 | m_buffer.m_size = other.m_buffer.m_size; 56 | } 57 | return *this; 58 | } 59 | 60 | DynamicArray& operator = (DynamicArray&& other) 61 | { 62 | if (&other != this) 63 | { 64 | m_buffer = other.m_buffer; 65 | other.m_buffer = Buffer(); 66 | } 67 | return *this; 68 | } 69 | 70 | 71 | ~DynamicArray() 72 | { 73 | Buffer::destroy(m_buffer); 74 | } 75 | 76 | T& operator[](size_t i) { return m_buffer.m_data[i]; } 77 | const T& operator[](size_t i) const { return m_buffer.m_data[i]; } 78 | 79 | T* data() { return m_buffer.m_data; } 80 | const T* data() const { return m_buffer.m_data; } 81 | 82 | T* begin() { return m_buffer.m_data; } 83 | T* end() { return m_buffer.m_data + m_buffer.m_size; } 84 | 85 | const T* begin() const { return m_buffer.m_data; } 86 | const T* end() const { return m_buffer.m_data + m_buffer.m_size; } 87 | 88 | T& front() { return m_buffer.m_data[0]; } 89 | const T& front() const { return m_buffer.m_data[0]; } 90 | 91 | T& back() { return m_buffer.m_data[m_buffer.m_size-1]; } 92 | const T& back() const { return m_buffer.m_data[m_buffer.m_size - 1]; } 93 | 94 | size_t size() const { return m_buffer.m_size; } 95 | 96 | RUSH_FORCEINLINE void resize(size_t desiredSize) 97 | { 98 | Buffer::resize(m_buffer, desiredSize); 99 | } 100 | 101 | RUSH_FORCEINLINE void resize(size_t desiredSize, const T& defaultValue) 102 | { 103 | static_assert(std::is_copy_constructible::value, "Type must be copy-constructible"); 104 | Buffer::resize(m_buffer, desiredSize, defaultValue); 105 | } 106 | 107 | RUSH_FORCEINLINE void reserve(size_t desiredCapacity) 108 | { 109 | Buffer::reserve(m_buffer, desiredCapacity); 110 | } 111 | 112 | RUSH_FORCEINLINE void push(const T& val) 113 | { 114 | static_assert(std::is_copy_constructible::value, "Type must be copy-constructible"); 115 | Buffer::push(m_buffer, val); 116 | } 117 | 118 | RUSH_FORCEINLINE void pop() 119 | { 120 | Buffer::pop(m_buffer); 121 | } 122 | 123 | RUSH_FORCEINLINE void clear() 124 | { 125 | Buffer::destructRange(begin(), end()); 126 | m_buffer.m_size = 0; 127 | } 128 | 129 | bool empty() const 130 | { 131 | return m_buffer.m_size == 0; 132 | } 133 | 134 | // Aliases for STL compatibility 135 | 136 | RUSH_FORCEINLINE void push_back(const T& val) 137 | { 138 | static_assert(std::is_copy_constructible::value, "Type must be copy-constructible"); 139 | Buffer::push(m_buffer, val); 140 | } 141 | 142 | RUSH_FORCEINLINE void push_back(T&& val) 143 | { 144 | Buffer::push(m_buffer, std::move(val)); 145 | } 146 | 147 | RUSH_FORCEINLINE void pop_back() 148 | { 149 | Buffer::pop(m_buffer); 150 | } 151 | 152 | private: 153 | 154 | Buffer m_buffer; 155 | }; 156 | 157 | template 158 | struct StaticArray 159 | { 160 | StaticArray() : currentSize(0) {} 161 | 162 | T& operator[](size_t i) { return data[i]; } 163 | const T& operator[](size_t i) const { return data[i]; } 164 | const T& back() const { return data[size() - 1]; } 165 | T& back() { return data[size() - 1]; } 166 | 167 | bool pushBack(const T& val) 168 | { 169 | if (currentSize < CAPACITY) 170 | { 171 | data[currentSize] = val; 172 | ++currentSize; 173 | return true; 174 | } 175 | else 176 | { 177 | return false; 178 | } 179 | } 180 | 181 | bool popBack() 182 | { 183 | if (currentSize > 0) 184 | { 185 | --currentSize; 186 | return true; 187 | } 188 | else 189 | { 190 | return false; 191 | } 192 | } 193 | 194 | void pushBackUnsafe(const T& val) 195 | { 196 | data[currentSize] = val; 197 | ++currentSize; 198 | } 199 | 200 | void popBackUnsafe(const T& val) { --currentSize; } 201 | 202 | void clear() { currentSize = 0; } 203 | 204 | size_t capacity() const { return CAPACITY; } 205 | size_t size() const { return currentSize; } 206 | static size_t elementSize() { return sizeof(T); } 207 | 208 | T* begin() { return data; } 209 | T* end() { return data + currentSize; } 210 | const T* begin() const { return data; } 211 | const T* end() const { return data + currentSize; } 212 | 213 | T data[CAPACITY]; 214 | size_t currentSize; 215 | }; 216 | 217 | template 218 | struct alignas(alignof(T)) InlineDynamicArray 219 | { 220 | RUSH_DISALLOW_COPY_AND_ASSIGN(InlineDynamicArray) 221 | 222 | u8 m_inlineData[sizeof(T) * N]; 223 | T * m_data = nullptr; 224 | u32 m_count = 0; 225 | 226 | InlineDynamicArray(u32 count) 227 | : m_data(reinterpret_cast(m_inlineData)) 228 | , m_count(count) 229 | { 230 | if (m_count > N) 231 | { 232 | m_data = new T[m_count]; 233 | } 234 | else 235 | { 236 | Buffer::constructRange(m_data, m_data + m_count); 237 | } 238 | } 239 | 240 | ~InlineDynamicArray() 241 | { 242 | if ((void*)m_data == (void*)m_inlineData) 243 | { 244 | Buffer::destructRange(m_data, m_data + m_count); 245 | } 246 | else 247 | { 248 | delete[] m_data; 249 | } 250 | } 251 | 252 | T& operator[](size_t i) { return m_data[i]; } 253 | const T& operator[](size_t i) const { return m_data[i]; } 254 | }; 255 | 256 | } 257 | -------------------------------------------------------------------------------- /Rush/UtilBuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rush.h" 4 | #include "UtilMemory.h" 5 | 6 | #include 7 | 8 | namespace Rush 9 | { 10 | 11 | // Generic buffer similar to tinystl::buffer 12 | template 13 | struct Buffer 14 | { 15 | T* m_data = nullptr; 16 | size_t m_size = 0; 17 | size_t m_capacity = 0; 18 | 19 | T* begin() { return m_data; } 20 | T* end() { return m_data + m_size; } 21 | 22 | static void destructRange(T* begin, T* end) 23 | { 24 | for (; begin < end; ++begin) 25 | { 26 | begin->~T(); 27 | } 28 | } 29 | 30 | static void push(Buffer& buf, const T& val) 31 | { 32 | if (buf.m_size < buf.m_capacity) 33 | { 34 | new(&buf.m_data[buf.m_size++]) T(val); 35 | } 36 | else 37 | { 38 | size_t newCapacity = (buf.m_capacity > 0) ? (2 * buf.m_capacity) : 1; 39 | reserve(buf, newCapacity); 40 | new(&buf.m_data[buf.m_size++]) T(val); 41 | } 42 | } 43 | 44 | static void push(Buffer& buf, T&& val) 45 | { 46 | if (buf.m_size < buf.m_capacity) 47 | { 48 | new(&buf.m_data[buf.m_size++]) T(std::move(val)); 49 | } 50 | else 51 | { 52 | size_t newCapacity = (buf.m_capacity > 0) ? (2 * buf.m_capacity) : 1; 53 | reserve(buf, newCapacity); 54 | new(&buf.m_data[buf.m_size++]) T(std::move(val)); 55 | } 56 | } 57 | 58 | static void pop(Buffer& buf) 59 | { 60 | --buf.m_size; 61 | buf.m_data[buf.m_size].~T(); 62 | } 63 | 64 | static void constructCopyRange(T* where, const T* begin, const T* end) 65 | { 66 | for (; begin < end; ++begin, ++where) 67 | { 68 | new(where) T(*begin); 69 | } 70 | } 71 | 72 | static void constructMoveRange(T* where, T* begin, T* end) 73 | { 74 | for (; begin < end; ++begin, ++where) 75 | { 76 | new(where) T(std::move(*begin)); 77 | } 78 | } 79 | 80 | static void constructRange(T* begin, T* end) 81 | { 82 | for (; begin < end; ++begin) 83 | { 84 | new(begin) T(); 85 | } 86 | } 87 | 88 | static void constructRange(T* begin, T* end, const T& val) 89 | { 90 | for (; begin < end; ++begin) 91 | { 92 | new(begin) T(val); 93 | } 94 | } 95 | 96 | static void reserve(Buffer& buf, size_t newCapacity) 97 | { 98 | if (newCapacity <= buf.m_capacity) return; 99 | 100 | T* newData = (T*)allocateBytes(newCapacity * sizeof(T)); 101 | 102 | constructMoveRange(newData, buf.begin(), buf.end()); 103 | destructRange(buf.begin(), buf.end()); 104 | deallocateBytes(buf.m_data); 105 | 106 | buf.m_data = newData; 107 | buf.m_capacity = newCapacity; 108 | } 109 | 110 | static void resize(Buffer& buf, size_t newSize) 111 | { 112 | reserve(buf, newSize); 113 | 114 | constructRange(buf.m_data + buf.m_size, buf.m_data + newSize); 115 | destructRange(buf.m_data + newSize, buf.m_data + buf.m_size); 116 | 117 | buf.m_size = newSize; 118 | } 119 | 120 | static void resize(Buffer& buf, size_t newSize, const T& defaultValue) 121 | { 122 | reserve(buf, newSize); 123 | 124 | constructRange(buf.m_data + buf.m_size, buf.m_data + newSize, defaultValue); 125 | destructRange(buf.m_data + newSize, buf.m_data + buf.m_size); 126 | 127 | buf.m_size = newSize; 128 | } 129 | 130 | static void destroy(Buffer& buf) 131 | { 132 | destructRange(buf.m_data, buf.m_data + buf.m_size); 133 | deallocateBytes(buf.m_data); 134 | } 135 | }; 136 | 137 | template 138 | struct BufferView 139 | { 140 | BufferView() = default; 141 | BufferView(T* inBegin, T* inEnd) 142 | : m_data(inBegin) 143 | , m_size(inEnd-inBegin) 144 | { 145 | } 146 | 147 | BufferView(T* inBegin, size_t inSize) 148 | : m_data(inBegin) 149 | , m_size(inSize) 150 | { 151 | } 152 | 153 | T* m_data = nullptr; 154 | size_t m_size = 0; 155 | 156 | T* begin() { return m_data; } 157 | T* end() { return m_data + m_size; } 158 | size_t size() const { return m_size; } 159 | }; 160 | 161 | } 162 | -------------------------------------------------------------------------------- /Rush/UtilCamera.cpp: -------------------------------------------------------------------------------- 1 | #include "UtilCamera.h" 2 | #include "UtilLog.h" 3 | #include "Window.h" 4 | 5 | namespace Rush 6 | { 7 | 8 | Camera::Camera(CoordinateSystem coordSystem) : Camera(1.0f, Pi * 0.25f, 1.0f, INFINITY, coordSystem) {} 9 | Camera::Camera(float aspect, float fov, float clipNear, CoordinateSystem coordSystem) 10 | : Camera(aspect, fov, clipNear, INFINITY, coordSystem) 11 | { 12 | } 13 | Camera::Camera(float aspect, float fov, float clipNear, float clipFar, CoordinateSystem coordSystem) 14 | : m_position(0, 0, 0) 15 | , m_axisX(1, 0, 0) 16 | , m_axisY(0, 1, 0) 17 | , m_axisZ(0, 0, 1) 18 | , m_aspect(aspect) 19 | , m_fov(fov) 20 | , m_clipNear(clipNear) 21 | , m_clipFar(clipFar) 22 | , m_coordSystem(coordSystem) 23 | { 24 | } 25 | 26 | Mat4 Camera::buildViewMatrix() const 27 | { 28 | Vec3 axisX = m_axisX; 29 | Vec3 axisY = m_axisY; 30 | Vec3 axisZ = m_axisZ; 31 | 32 | float x = -axisX.dot(m_position); 33 | float y = -axisY.dot(m_position); 34 | float z = -axisZ.dot(m_position); 35 | 36 | Mat4 res(axisX.x, axisY.x, axisZ.x, 0, axisX.y, axisY.y, axisZ.y, 0, axisX.z, axisY.z, axisZ.z, 0, x, y, z, 1); 37 | 38 | return res; 39 | } 40 | 41 | Mat4 Camera::buildProjMatrix(bool reverseZ) const 42 | { 43 | Mat4 res = Mat4::perspective(m_aspect, m_fov, m_clipNear, m_clipFar, reverseZ); 44 | if (m_coordSystem == RightHanded) 45 | { 46 | res.rows[2].z = -res.rows[2].z; 47 | res.rows[2].w = -res.rows[2].w; 48 | } 49 | return res; 50 | } 51 | 52 | void Camera::blendTo(const Camera& other, float positionAlpha, float orientationAlpha, float parameterAlpha) 53 | { 54 | m_position = lerp(m_position, other.m_position, positionAlpha); 55 | 56 | m_aspect = lerp(m_aspect, other.m_aspect, parameterAlpha); 57 | m_fov = lerp(m_fov, other.m_fov, parameterAlpha); 58 | m_clipNear = lerp(m_clipNear, other.m_clipNear, parameterAlpha); 59 | 60 | if (m_clipFar == INFINITY || other.m_clipFar == INFINITY) 61 | { 62 | m_clipFar = INFINITY; 63 | } 64 | else 65 | { 66 | m_clipFar = lerp(m_clipFar, other.m_clipFar, parameterAlpha); 67 | } 68 | 69 | Mat3 orientationA{{Vec3{m_axisX.x, m_axisY.x, m_axisZ.x}, Vec3{m_axisX.y, m_axisY.y, m_axisZ.y}, 70 | Vec3{m_axisX.z, m_axisY.z, m_axisZ.z}}}; 71 | 72 | Mat3 orientationB{{Vec3{other.m_axisX.x, other.m_axisY.x, other.m_axisZ.x}, 73 | Vec3{other.m_axisX.y, other.m_axisY.y, other.m_axisZ.y}, 74 | Vec3{other.m_axisX.z, other.m_axisY.z, other.m_axisZ.z}}}; 75 | 76 | Quat quatA = makeQuat(orientationA); 77 | Quat quatB = makeQuat(orientationB); 78 | 79 | Quat quat = normalize(slerp(quatA, quatB, orientationAlpha)); 80 | 81 | Mat3 orientation = transpose(makeMat3(quat)); 82 | 83 | m_axisX = orientation.rows[0]; 84 | m_axisY = orientation.rows[1]; 85 | m_axisZ = orientation.rows[2]; 86 | } 87 | 88 | void Camera::move(const Vec3& delta) 89 | { 90 | m_position += getRight() * delta.x; 91 | m_position += getUp() * delta.y; 92 | m_position += getForward() * delta.z; 93 | } 94 | 95 | void Camera::moveOnAxis(float delta, const Vec3& axis) { m_position += axis * delta; } 96 | 97 | void Camera::rotate(const Vec3& _delta) 98 | { 99 | Vec3 delta = _delta; 100 | if (m_coordSystem == RightHanded) 101 | { 102 | delta = -delta; 103 | } 104 | 105 | Mat4 mx = Mat4::rotationAxis(m_axisX, delta.x); 106 | Mat4 my = Mat4::rotationAxis(m_axisY, delta.y); 107 | Mat4 mz = Mat4::rotationAxis(m_axisZ, delta.z); 108 | 109 | Mat4 mat(mx * my * mz); 110 | 111 | m_axisX = mat * m_axisX; 112 | m_axisY = mat * m_axisY; 113 | m_axisZ = mat * m_axisZ; 114 | 115 | m_axisX.normalize(); 116 | m_axisY.normalize(); 117 | m_axisZ.normalize(); 118 | } 119 | 120 | void Camera::rotateOnAxis(float delta, const Vec3& axis) 121 | { 122 | if (m_coordSystem == RightHanded) 123 | { 124 | delta = -delta; 125 | } 126 | 127 | Mat4 mat = Mat4::rotationAxis(axis, delta); 128 | 129 | m_axisX = mat * m_axisX; 130 | m_axisY = mat * m_axisY; 131 | m_axisZ = mat * m_axisZ; 132 | 133 | m_axisX.normalize(); 134 | m_axisY.normalize(); 135 | m_axisZ.normalize(); 136 | } 137 | 138 | void Camera::lookAt(const Vec3& position, const Vec3& target, const Vec3& up) 139 | { 140 | m_position = position; 141 | 142 | m_axisZ = target - position; 143 | m_axisZ.normalize(); 144 | 145 | m_axisX = normalize(up).cross(m_axisZ); 146 | m_axisY = m_axisZ.cross(m_axisX); 147 | m_axisX = m_axisY.cross(m_axisZ); 148 | 149 | if (m_coordSystem == RightHanded) 150 | { 151 | m_axisX = -m_axisX; 152 | m_axisZ = -m_axisZ; 153 | } 154 | 155 | m_axisX.normalize(); 156 | m_axisY.normalize(); 157 | m_axisZ.normalize(); 158 | } 159 | 160 | void Camera::setClip(float near_dist, float far_dist) 161 | { 162 | m_clipNear = near_dist; 163 | m_clipFar = far_dist; 164 | } 165 | 166 | CameraManipulator::CameraManipulator() : CameraManipulator(KeyboardState{}, MouseState{}) {} 167 | 168 | CameraManipulator::CameraManipulator(const KeyboardState& ks, const MouseState& ms) 169 | : m_oldMousePos(0, 0), m_oldMouseWheel(0), m_moveSpeed(20.0f), m_turnSpeed(2.0f), m_mode(Mode_FirstPerson) 170 | { 171 | init(ks, ms); 172 | setDefaultKeys(); 173 | } 174 | 175 | void CameraManipulator::setKey(KeyFunction fun, u8 key) { m_keys[fun] = key; } 176 | 177 | u8 CameraManipulator::getKey(KeyFunction fun) { return m_keys[fun]; } 178 | 179 | void CameraManipulator::setDefaultKeys() 180 | { 181 | setKey(KeyFunction_MoveX_Pos, 'D'); 182 | setKey(KeyFunction_MoveX_Neg, 'A'); 183 | setKey(KeyFunction_MoveY_Pos, 'E'); 184 | setKey(KeyFunction_MoveY_Neg, 'Q'); 185 | setKey(KeyFunction_MoveZ_Pos, 'W'); 186 | setKey(KeyFunction_MoveZ_Neg, 'S'); 187 | 188 | setKey(KeyFunction_RotateX_Pos, Key_Up); 189 | setKey(KeyFunction_RotateX_Neg, Key_Down); 190 | setKey(KeyFunction_RotateY_Pos, Key_Right); 191 | setKey(KeyFunction_RotateY_Neg, Key_Left); 192 | 193 | setKey(KeyFunction_Faster, Key_LeftShift); 194 | setKey(KeyFunction_Slower, Key_LeftControl); 195 | } 196 | 197 | void CameraManipulator::init(const KeyboardState& ks, const MouseState& ms) 198 | { 199 | m_oldMousePos = ms.pos; 200 | m_oldMouseWheel = ms.wheelV; 201 | } 202 | 203 | void CameraManipulator::update(Camera* camera, float dt, const KeyboardState& ks, const MouseState& ms) 204 | { 205 | RUSH_ASSERT(camera); 206 | 207 | Vec2 mousePos = ms.pos; 208 | Vec2 mouseDelta = mousePos - m_oldMousePos; 209 | m_oldMousePos = mousePos; 210 | 211 | int mouseWheel = ms.wheelV; 212 | int wheelDelta = mouseWheel - m_oldMouseWheel; 213 | m_oldMouseWheel = mouseWheel; 214 | 215 | switch (m_mode) 216 | { 217 | case Mode_FirstPerson: 218 | { 219 | Vec3 camMove(0, 0, 0); 220 | Vec3 camRotate(0, 0, 0); 221 | 222 | if (ks.isKeyDown(getKey(KeyFunction_MoveX_Pos))) 223 | camMove.x = 1; 224 | if (ks.isKeyDown(getKey(KeyFunction_MoveX_Neg))) 225 | camMove.x = -1; 226 | 227 | if (ks.isKeyDown(getKey(KeyFunction_MoveY_Pos))) 228 | camMove.y = 1; 229 | if (ks.isKeyDown(getKey(KeyFunction_MoveY_Neg))) 230 | camMove.y = -1; 231 | 232 | if (ks.isKeyDown(getKey(KeyFunction_MoveZ_Pos))) 233 | camMove.z = 1; 234 | if (ks.isKeyDown(getKey(KeyFunction_MoveZ_Neg))) 235 | camMove.z = -1; 236 | 237 | if (ks.isKeyDown(getKey(KeyFunction_RotateY_Pos))) 238 | camRotate.y = dt * m_turnSpeed; 239 | if (ks.isKeyDown(getKey(KeyFunction_RotateY_Neg))) 240 | camRotate.y = -dt * m_turnSpeed; 241 | 242 | if (ks.isKeyDown(getKey(KeyFunction_RotateX_Pos))) 243 | camRotate.x = -dt * m_turnSpeed; 244 | if (ks.isKeyDown(getKey(KeyFunction_RotateX_Neg))) 245 | camRotate.x = dt * m_turnSpeed; 246 | 247 | if ((ms.buttons[0]) != 0) 248 | { 249 | camRotate.y = mouseDelta.x * 0.005f; 250 | camRotate.x = mouseDelta.y * 0.005f; 251 | } 252 | 253 | if (camMove != Vec3(0, 0, 0)) 254 | { 255 | camMove.normalize(); 256 | if (ks.isKeyDown(getKey(KeyFunction_Faster))) 257 | camMove *= 10.0f; 258 | if (ks.isKeyDown(getKey(KeyFunction_Slower))) 259 | camMove *= 0.1f; 260 | camera->move(camMove * dt * m_moveSpeed); 261 | } 262 | 263 | float rot_len = camRotate.length(); 264 | if (rot_len > 0) 265 | { 266 | camera->rotateOnAxis(camRotate.y, m_upDirection); 267 | camera->rotateOnAxis(camRotate.x, camera->getRight()); 268 | } 269 | 270 | break; 271 | } 272 | case Mode_Orbit: 273 | { 274 | Vec3 camMove(0, 0, 0); 275 | 276 | if (ks.isKeyDown(getKey(KeyFunction_MoveX_Pos))) 277 | camMove.x = 1; 278 | if (ks.isKeyDown(getKey(KeyFunction_MoveX_Neg))) 279 | camMove.x = -1; 280 | 281 | if (ks.isKeyDown(getKey(KeyFunction_MoveY_Pos))) 282 | camMove.y = 1; 283 | if (ks.isKeyDown(getKey(KeyFunction_MoveX_Neg))) 284 | camMove.y = -1; 285 | 286 | if (ks.isKeyDown(getKey(KeyFunction_MoveZ_Pos))) 287 | camMove.z = 1; 288 | if (ks.isKeyDown(getKey(KeyFunction_MoveZ_Neg))) 289 | camMove.z = -1; 290 | 291 | if (ms.buttons[0] != 0) 292 | { 293 | Vec3 old_cam_pos = camera->getPosition(); 294 | Vec3 old_cam_dir = camera->getForward(); 295 | Vec3 old_cam_up = camera->getUp(); 296 | 297 | float orbitRadius = 1.0f; 298 | Vec3 orbitCenter = old_cam_pos + old_cam_dir * orbitRadius; 299 | 300 | Camera tmp(1, 1, 1, 1); 301 | tmp.lookAt(-old_cam_dir, Vec3(0, 0, 0), old_cam_up); 302 | tmp.rotateOnAxis(mouseDelta.x * 0.01f, Vec3(0, 1, 0)); 303 | tmp.rotateOnAxis(mouseDelta.y * 0.01f, tmp.getRight()); 304 | 305 | camera->lookAt(-tmp.getForward() * orbitRadius + orbitCenter, orbitCenter, tmp.getUp()); 306 | } 307 | else if (ms.buttons[1] != 0) 308 | { 309 | // move 310 | Vec2 mp = mouseDelta * 5.0f; 311 | camMove.x = mp.x * -1; 312 | camMove.y = mp.y; 313 | } 314 | 315 | if (wheelDelta) 316 | { 317 | camMove.z += float(wheelDelta) * 3.0f; 318 | } 319 | 320 | if (camMove != Vec3(0, 0, 0)) 321 | { 322 | if (ks.isKeyDown(getKey(KeyFunction_Faster))) 323 | camMove *= 10.0f; 324 | if (ks.isKeyDown(getKey(KeyFunction_Slower))) 325 | camMove *= 0.1f; 326 | camera->move(camMove * dt * m_moveSpeed); 327 | } 328 | break; 329 | } 330 | } 331 | } 332 | 333 | } // namespace Rush 334 | -------------------------------------------------------------------------------- /Rush/UtilCamera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MathTypes.h" 4 | 5 | namespace Rush 6 | { 7 | 8 | class KeyboardState; 9 | class MouseState; 10 | 11 | class Camera 12 | { 13 | 14 | public: 15 | 16 | enum CoordinateSystem { 17 | LeftHanded, 18 | RightHanded, 19 | }; 20 | 21 | Camera(CoordinateSystem coordSys = LeftHanded); 22 | Camera(float aspect, float fov, float clipNear, CoordinateSystem coordSys = LeftHanded); 23 | Camera(float aspect, float fov, float clipNear, float clipFar, CoordinateSystem coordSys = LeftHanded); 24 | 25 | void setAspect(float aspect) { m_aspect = aspect; } 26 | void setFov(float fov) { m_fov = fov; } 27 | void setClip(float near, float far); 28 | 29 | void move(const Vec3& delta); 30 | void moveOnAxis(float delta, const Vec3& axis); 31 | void rotate(const Vec3& delta); 32 | void rotateOnAxis(float delta, const Vec3& axis); 33 | 34 | void lookAt(const Vec3& position, const Vec3& target, const Vec3& up = Vec3(0, 1, 0)); 35 | 36 | float getNearPlane() const { return m_clipNear; } 37 | float getFarPlane() const { return m_clipFar; } 38 | 39 | float getAspect() const { return m_aspect; } 40 | float getFov() const { return m_fov; } 41 | 42 | const Vec3& getPosition() const { return m_position; } 43 | Vec3& getPosition() { return m_position; } 44 | 45 | Mat4 buildViewMatrix() const; 46 | Mat4 buildProjMatrix(bool reverseZ=false) const; 47 | 48 | const Vec3 getRight() const { return m_axisX; } 49 | const Vec3 getUp() const { return m_axisY; } 50 | const Vec3 getForward() const { return m_coordSystem==LeftHanded ? m_axisZ : -m_axisZ; } 51 | 52 | void blendTo(const Camera& other, float positionAlpha, float orientationAlpha, float parameterAlpha = 1.0f); 53 | 54 | private: 55 | Vec3 m_position; 56 | 57 | Vec3 m_axisX; // right 58 | Vec3 m_axisY; // up 59 | Vec3 m_axisZ; // front 60 | 61 | float m_aspect; 62 | float m_fov; 63 | float m_clipNear; 64 | float m_clipFar; 65 | 66 | CoordinateSystem m_coordSystem; 67 | }; 68 | 69 | class CameraManipulator 70 | { 71 | public: 72 | enum KeyFunction 73 | { 74 | KeyFunction_MoveX_Pos, 75 | KeyFunction_MoveX_Neg, 76 | KeyFunction_MoveY_Pos, 77 | KeyFunction_MoveY_Neg, 78 | KeyFunction_MoveZ_Pos, 79 | KeyFunction_MoveZ_Neg, 80 | 81 | KeyFunction_RotateX_Pos, 82 | KeyFunction_RotateX_Neg, 83 | KeyFunction_RotateY_Pos, 84 | KeyFunction_RotateY_Neg, 85 | 86 | KeyFunction_Faster, 87 | KeyFunction_Slower, 88 | 89 | KeyFunction_COUNT 90 | }; 91 | 92 | enum Mode 93 | { 94 | Mode_FirstPerson, 95 | Mode_Orbit 96 | }; 97 | 98 | CameraManipulator(); 99 | CameraManipulator(const KeyboardState& ks, const MouseState& ms); 100 | 101 | void init(const KeyboardState& ks, const MouseState& ms); 102 | 103 | void update(Camera* camera, float dt, const KeyboardState& ks, const MouseState& ms); 104 | 105 | void setMoveSpeed(float speed) { m_moveSpeed = speed; } 106 | void setTurnSpeed(float speed) { m_turnSpeed = speed; } 107 | 108 | void setMode(Mode mode) { m_mode = mode; } 109 | Mode getMode() const { return m_mode; } 110 | 111 | void setDefaultKeys(); 112 | void setKey(KeyFunction fun, u8 key); 113 | u8 getKey(KeyFunction fun); 114 | 115 | void setUpDirection(const Vec3& v) { m_upDirection = v; } 116 | 117 | private: 118 | 119 | Vec2 m_oldMousePos; 120 | int m_oldMouseWheel; 121 | 122 | float m_moveSpeed; 123 | float m_turnSpeed; 124 | 125 | Mode m_mode; 126 | u8 m_keys[KeyFunction_COUNT]; 127 | 128 | Vec3 m_upDirection = Vec3(0, 1, 0); 129 | }; 130 | 131 | } 132 | -------------------------------------------------------------------------------- /Rush/UtilColor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MathTypes.h" 4 | 5 | namespace Rush 6 | { 7 | struct ColorRGBA; 8 | struct ColorRGBA8; 9 | 10 | // high-precision (32 bit floating point) color 11 | struct ColorRGBA 12 | { 13 | float r, g, b, a; 14 | 15 | ColorRGBA() = default; 16 | 17 | ColorRGBA(float _r, float _g, float _b, float _a = 1.0f) : r(_r), g(_g), b(_b), a(_a) {} 18 | 19 | ColorRGBA(const Vec3& vec, float _a = 1.0f) : r(vec.x), g(vec.y), b(vec.z), a(_a) {} 20 | 21 | ColorRGBA(const Vec4& vec) : r(vec.x), g(vec.y), b(vec.z), a(vec.w) {} 22 | 23 | operator Vec4() const { return rgba(); } 24 | 25 | Vec3 rgb() const { return Vec3(r, g, b); } 26 | Vec4 rgba() const { return Vec4(r, g, b, a); } 27 | 28 | operator ColorRGBA8() const; 29 | 30 | static ColorRGBA Black(float a = 1.0f) { return ColorRGBA(0.0f, 0.0f, 0.0f, a); } 31 | static ColorRGBA White(float a = 1.0f) { return ColorRGBA(1.0f, 1.0f, 1.0f, a); } 32 | static ColorRGBA Red(float a = 1.0f) { return ColorRGBA(1.0f, 0.0f, 0.0f, a); } 33 | static ColorRGBA Green(float a = 1.0f) { return ColorRGBA(0.0f, 1.0f, 0.0f, a); } 34 | static ColorRGBA Blue(float a = 1.0f) { return ColorRGBA(0.0f, 0.0f, 1.0f, a); } 35 | static ColorRGBA Cyan(float a = 1.0f) { return ColorRGBA(0.0f, 1.0f, 1.0f, a); } 36 | static ColorRGBA Magenta(float a = 1.0f) { return ColorRGBA(1.0f, 0.0f, 1.0f, a); } 37 | static ColorRGBA Yellow(float a = 1.0f) { return ColorRGBA(1.0f, 1.0f, 0.0f, a); } 38 | static ColorRGBA Orange(float a = 1.0f) { return ColorRGBA(1.0f, 0.5f, 0.0f, a); } 39 | static ColorRGBA Purple(float a = 1.0f) { return ColorRGBA(0.5f, 0.0f, 0.5f, a); } 40 | }; 41 | 42 | template <> ColorRGBA lerp(const ColorRGBA& x, const ColorRGBA& y, float t); 43 | 44 | // low-precision (8 bit unsigned integer) color 45 | struct ColorRGBA8 46 | { 47 | u8 r, g, b, a; 48 | 49 | ColorRGBA8() = default; 50 | 51 | explicit ColorRGBA8(u32 col) { memcpy(this, &col, 4); } 52 | 53 | ColorRGBA8(u8 _r, u8 _g, u8 _b, u8 _a = 255) : r(_r), g(_g), b(_b), a(_a) {} 54 | 55 | operator ColorRGBA() const 56 | { 57 | float rf = float(r) / 255.0f; 58 | float gf = float(g) / 255.0f; 59 | float bf = float(b) / 255.0f; 60 | float af = float(a) / 255.0f; 61 | 62 | return ColorRGBA(rf, gf, bf, af); 63 | } 64 | 65 | operator u32() const { return *reinterpret_cast(this); } 66 | 67 | static ColorRGBA8 Black(u8 a = 0xFF) { return ColorRGBA8(0x00, 0x00, 0x00, a); } 68 | static ColorRGBA8 White(u8 a = 0xFF) { return ColorRGBA8(0xFF, 0xFF, 0xFF, a); } 69 | static ColorRGBA8 Red(u8 a = 0xFF) { return ColorRGBA8(0xFF, 0x00, 0x00, a); } 70 | static ColorRGBA8 Green(u8 a = 0xFF) { return ColorRGBA8(0x00, 0xFF, 0x00, a); } 71 | static ColorRGBA8 Blue(u8 a = 0xFF) { return ColorRGBA8(0x00, 0x00, 0xFF, a); } 72 | }; 73 | 74 | inline float linearToSRGB(float v) 75 | { 76 | v = min(1.0f, v); 77 | return v <= 0.0031308f ? v * 12.92f : 1.055f * powf(v, 1.0f / 2.4f) - 0.055f; 78 | } 79 | 80 | inline float SRGBToLinear(float sRGB) 81 | { 82 | float linearLo = sRGB / 12.92f; 83 | float linearHi = powf((sRGB + 0.055f) / 1.055f, 2.4f); 84 | float linear = (sRGB <= 0.04045f) ? linearLo : linearHi; 85 | return linear; 86 | } 87 | 88 | inline ColorRGBA linearToSRGB(ColorRGBA col) 89 | { 90 | col.r = linearToSRGB(col.r); 91 | col.g = linearToSRGB(col.g); 92 | col.b = linearToSRGB(col.b); 93 | 94 | return col; 95 | } 96 | inline Vec3 linearToSRGB(Vec3 col) 97 | { 98 | col.x = linearToSRGB(col.x); 99 | col.y = linearToSRGB(col.y); 100 | col.z = linearToSRGB(col.z); 101 | 102 | return col; 103 | } 104 | 105 | inline ColorRGBA::operator ColorRGBA8() const 106 | { 107 | u8 r8 = u8(saturate(r) * 255.0f); 108 | u8 g8 = u8(saturate(g) * 255.0f); 109 | u8 b8 = u8(saturate(b) * 255.0f); 110 | u8 a8 = u8(saturate(a) * 255.0f); 111 | return ColorRGBA8(r8, g8, b8, a8); 112 | } 113 | 114 | template <> inline ColorRGBA lerp(const ColorRGBA& x, const ColorRGBA& y, float t) 115 | { 116 | ColorRGBA res; 117 | 118 | res.r = lerp(x.r, y.r, t); 119 | res.g = lerp(x.g, y.g, t); 120 | res.b = lerp(x.b, y.b, t); 121 | res.a = lerp(x.a, y.a, t); 122 | 123 | return res; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /Rush/UtilDataStream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MathCommon.h" 4 | #include "Rush.h" 5 | 6 | #include 7 | 8 | namespace Rush 9 | { 10 | 11 | class DataStream 12 | { 13 | 14 | public: 15 | virtual ~DataStream() {} 16 | 17 | virtual u64 write(const void* buf, u64 size) = 0; 18 | template u64 writeT(const T& val) { return write(&val, sizeof(val)); } 19 | 20 | virtual u64 read(void* buf, u64 size) = 0; 21 | 22 | template u64 readT(T& val) { return read(&val, sizeof(val)); } 23 | 24 | virtual u64 tell() = 0; 25 | virtual void seek(u64 pos) = 0; 26 | virtual void skip(int distance) = 0; 27 | virtual void rewind() = 0; 28 | 29 | virtual bool valid() = 0; 30 | 31 | virtual u64 length() = 0; 32 | }; 33 | 34 | class MemDataStream : public DataStream 35 | { 36 | public: 37 | MemDataStream(void* data, u64 size) : m_dataRW((u8*)data), m_dataRO((const u8*)data), m_pos(0), m_size(size){}; 38 | MemDataStream(const void* data, u64 size) : m_dataRW(nullptr), m_dataRO((const u8*)data), m_pos(0), m_size(size){}; 39 | 40 | virtual u64 write(const void* buf, u64 size) 41 | { 42 | u64 pos2 = m_pos + size; 43 | pos2 = min(pos2, m_size); 44 | size = pos2 - m_pos; 45 | 46 | memcpy(&m_dataRW[m_pos], buf, size); 47 | m_pos = pos2; 48 | 49 | return size; 50 | } 51 | virtual u64 read(void* buf, u64 size) 52 | { 53 | u64 pos2 = m_pos + size; 54 | pos2 = min(pos2, m_size); 55 | size = pos2 - m_pos; 56 | 57 | memcpy(buf, &m_dataRO[m_pos], size); 58 | m_pos = pos2; 59 | 60 | return size; 61 | } 62 | 63 | virtual u64 tell() { return m_pos; }; 64 | virtual void seek(u64 pos) { m_pos = min(pos, m_size); }; 65 | virtual void skip(int distance) 66 | { 67 | u64 pos2 = m_pos + distance; 68 | pos2 = min(pos2, m_size); 69 | m_pos = pos2; 70 | }; 71 | virtual void rewind() { m_pos = 0; }; 72 | 73 | virtual bool valid() { return m_dataRO != nullptr; } 74 | 75 | virtual u64 length() { return m_size; } 76 | 77 | private: 78 | u8* m_dataRW; 79 | const u8* m_dataRO; 80 | 81 | u64 m_pos; 82 | u64 m_size; 83 | }; 84 | 85 | class NullDataStream : public DataStream 86 | { 87 | public: 88 | NullDataStream() : m_pos(0), m_size(0) {} 89 | 90 | virtual u64 write(const void*, u64 size) 91 | { 92 | m_pos += size; 93 | return m_pos; 94 | } 95 | virtual u64 read(void*, u64 size) 96 | { 97 | m_pos += size; 98 | return m_pos; 99 | } 100 | 101 | virtual u64 tell() { return m_pos; } 102 | virtual void seek(u64 pos) { m_pos = pos; } 103 | virtual void skip(int distance) { m_pos += distance; } 104 | virtual void rewind() { m_pos = 0; } 105 | 106 | virtual bool valid() { return true; } 107 | 108 | virtual u64 length() { return m_size; } 109 | 110 | private: 111 | u64 m_pos; 112 | u64 m_size; 113 | }; 114 | } 115 | -------------------------------------------------------------------------------- /Rush/UtilFile.cpp: -------------------------------------------------------------------------------- 1 | #include "UtilFile.h" 2 | #include "MathCommon.h" 3 | 4 | #ifdef _MSC_VER 5 | #pragma warning(push) 6 | #pragma warning(disable : 4996) // 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. 7 | #endif //_MSC_VER 8 | 9 | namespace Rush 10 | { 11 | u64 FileIn::read(void* buf, u64 size) 12 | { 13 | u64 br = (u64)fread(buf, 1, size, m_file); 14 | return br; 15 | } 16 | 17 | FileIn::FileIn(const char* filename) { m_file = fopen(filename, "rb"); } 18 | 19 | FileIn::~FileIn() 20 | { 21 | if (m_file) 22 | { 23 | fclose(m_file); 24 | m_file = nullptr; 25 | } 26 | } 27 | 28 | u64 FileIn::length() 29 | { 30 | u64 currPos = tell(); 31 | 32 | fseek(m_file, 0, SEEK_END); 33 | 34 | u64 endPos = tell(); 35 | 36 | fseek(m_file, long(currPos), SEEK_SET); 37 | 38 | return endPos; 39 | } 40 | 41 | u64 FileOut::write(const void* buf, u64 size) 42 | { 43 | u64 inBufPos = 0; 44 | u64 inBytesLeft = size; 45 | 46 | while (inBytesLeft != 0) 47 | { 48 | u64 outBytesLeft = m_bufferSize - m_bufferPos; 49 | 50 | u64 bytesToCopy = min(inBytesLeft, outBytesLeft); 51 | 52 | memcpy(&m_buffer[m_bufferPos], &((char*)buf)[inBufPos], bytesToCopy); 53 | 54 | m_bufferPos += bytesToCopy; 55 | inBufPos += bytesToCopy; 56 | 57 | inBytesLeft -= bytesToCopy; 58 | 59 | if (inBytesLeft != 0 || outBytesLeft == 0) 60 | { 61 | flush(); 62 | } 63 | } 64 | return size; 65 | } 66 | 67 | FileOut::FileOut(const char* filename, u64 buffer_size) : m_buffer(nullptr), m_bufferSize(buffer_size), m_bufferPos(0) 68 | { 69 | m_file = fopen(filename, "wb"); 70 | m_buffer = new char[m_bufferSize]; 71 | } 72 | 73 | FileOut::~FileOut() 74 | { 75 | if (m_file) 76 | { 77 | close(); 78 | } 79 | } 80 | 81 | void FileOut::flush() 82 | { 83 | fwrite(m_buffer, 1, m_bufferPos, m_file); 84 | m_bufferPos = 0; 85 | } 86 | 87 | void FileOut::close() 88 | { 89 | flush(); 90 | 91 | fclose(m_file); 92 | m_file = nullptr; 93 | 94 | delete m_buffer; 95 | m_buffer = nullptr; 96 | } 97 | 98 | u64 FileBase::tell() 99 | { 100 | long fileSize = ftell(m_file); 101 | if (fileSize == long(-1)) 102 | { 103 | return 0; 104 | } 105 | else 106 | { 107 | return u64(fileSize); 108 | } 109 | } 110 | 111 | void FileBase::seek(u64 pos) { fseek(m_file, long(pos), SEEK_SET); } 112 | 113 | void FileBase::skip(int distance) { fseek(m_file, distance, SEEK_CUR); } 114 | 115 | void FileBase::rewind() { fseek(m_file, 0, SEEK_SET); } 116 | 117 | bool FileBase::valid() { return m_file != nullptr; } 118 | } 119 | 120 | #ifdef _MSC_VER 121 | #pragma warning(pop) 122 | #endif //_MSC_VER 123 | -------------------------------------------------------------------------------- /Rush/UtilFile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rush.h" 4 | 5 | #include "UtilDataStream.h" 6 | #include "UtilString.h" 7 | #include "UtilArray.h" 8 | 9 | #include 10 | 11 | namespace Rush 12 | { 13 | class FileBase : public DataStream 14 | { 15 | 16 | public: 17 | FileBase() : m_file(nullptr){}; 18 | virtual ~FileBase() override{}; 19 | 20 | virtual u64 tell() override; 21 | virtual void seek(u64 pos) override; 22 | virtual void skip(int distance) override; 23 | virtual void rewind() override; 24 | 25 | virtual bool valid() override; 26 | 27 | protected: 28 | FILE* m_file; 29 | 30 | private: 31 | }; 32 | 33 | ////////////////////////////////////////////////////////////////////////// 34 | 35 | class FileIn : public FileBase 36 | { 37 | 38 | public: 39 | FileIn(const char* filename); 40 | virtual ~FileIn() override; 41 | 42 | virtual u64 read(void* buf, u64 size) override; 43 | virtual u64 write(const void*, u64) override { return 0; } 44 | 45 | virtual u64 length() override; 46 | }; 47 | 48 | ////////////////////////////////////////////////////////////////////////// 49 | 50 | class FileOut : public FileBase 51 | { 52 | 53 | public: 54 | FileOut(const char* filename, u64 buffer_size = (1 << 20)); 55 | virtual ~FileOut(); 56 | 57 | virtual u64 read(void*, u64) override { return 0; } 58 | virtual u64 write(const void* buf, u64 size) override; 59 | 60 | virtual u64 length() override { return 0; } 61 | 62 | void close(); 63 | 64 | protected: 65 | void flush(); 66 | 67 | private: 68 | FileOut& operator=(const FileOut&) = delete; 69 | 70 | char* m_buffer; 71 | const u64 m_bufferSize; 72 | u64 m_bufferPos; 73 | }; 74 | } 75 | -------------------------------------------------------------------------------- /Rush/UtilHash.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rush.h" 4 | 5 | namespace Rush 6 | { 7 | // as per http://www.isthe.com/chongo/tech/comp/fnv/index.html 8 | 9 | inline u32 hashFnv1(const void* _message, size_t length, u32 state = 0x811c9dc5) 10 | { 11 | const u8* message = (const u8*)_message; 12 | for (size_t i = 0; i < length; ++i) 13 | { 14 | state *= 0x01000193; 15 | state ^= message[i]; 16 | } 17 | return state; 18 | } 19 | 20 | inline u32 hashStrFnv1(const char* message, u32 state = 0x811c9dc5) 21 | { 22 | while (*message) 23 | { 24 | state *= 0x01000193; 25 | state ^= *(message++); 26 | } 27 | return state; 28 | } 29 | 30 | inline u32 hashFnv1a(const void* _message, size_t length, u32 state = 0x811c9dc5) 31 | { 32 | const u8* message = (const u8*)_message; 33 | for (size_t i = 0; i < length; ++i) 34 | { 35 | state ^= message[i]; 36 | state *= 0x01000193; 37 | } 38 | return state; 39 | } 40 | 41 | inline u32 hashStrFnv1a(const char* message, u32 state = 0x811c9dc5) 42 | { 43 | while (*message) 44 | { 45 | state ^= *(message++); 46 | state *= 0x01000193; 47 | } 48 | return state; 49 | } 50 | 51 | inline u64 hashFnv1a64(const void* _message, size_t length, u64 state = 0xcbf29ce484222325) 52 | { 53 | const u8* message = (const u8*)_message; 54 | for (size_t i = 0; i < length; ++i) 55 | { 56 | state ^= message[i]; 57 | state *= 0x100000001b3; 58 | } 59 | return state; 60 | } 61 | 62 | inline u64 hashStrFnv1a64(const char* message, u64 state = 0xcbf29ce484222325) 63 | { 64 | while (*message) 65 | { 66 | state ^= *(message++); 67 | state *= 0x100000001b3; 68 | } 69 | return state; 70 | } 71 | 72 | inline constexpr u32 hashFnv1CE(const void* _message, size_t length, u32 state = 0x811c9dc5) 73 | { 74 | return (length == 0) 75 | ? state 76 | : hashFnv1CE(((const u8*)_message) + 1, length - 1, u32((u64)state * 0x01000193) ^ (*((const u8*)_message))); 77 | } 78 | 79 | inline constexpr u32 hashFnv1aCE(const void* _message, size_t length, u32 state = 0x811c9dc5) 80 | { 81 | return (length == 0) 82 | ? state 83 | : hashFnv1aCE(((const u8*)_message) + 1, length - 1, u32((u64)state * (*((const u8*)_message))) ^ 0x01000193); 84 | } 85 | 86 | inline constexpr u32 hashStrFnv1CE(const char* message, u32 state = 0x811c9dc5) 87 | { 88 | return (*message == 0) 89 | ? state 90 | : hashStrFnv1CE(message + 1, u32((u64)state * 0x01000193) ^ u32(*message)); 91 | } 92 | 93 | inline constexpr u32 hashStrFnv1aCE(const char* message, u32 state = 0x811c9dc5) 94 | { 95 | return (*message == 0) 96 | ? state 97 | : hashStrFnv1aCE(message + 1, u32((u64)state * u32(*message)) ^ 0x01000193); 98 | } 99 | } 100 | 101 | -------------------------------------------------------------------------------- /Rush/UtilLinearAllocator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Rush 4 | { 5 | template class LinearAllocator 6 | { 7 | public: 8 | LinearAllocator() : m_data(nullptr), m_size(0), m_capacity(0) {} 9 | LinearAllocator(T* data, size_t capacity) : m_data(data), m_size(0), m_capacity(capacity){}; 10 | 11 | bool canAllocate(size_t count) const { return (m_size + count) <= m_capacity; } 12 | 13 | T* allocate(size_t count) 14 | { 15 | size_t newSize = m_size + count; 16 | if (newSize <= m_capacity) 17 | { 18 | T* res = &m_data[m_size]; 19 | m_size = newSize; 20 | return res; 21 | } 22 | else 23 | { 24 | return nullptr; 25 | } 26 | } 27 | 28 | T* allocateUnsafe(size_t count) 29 | { 30 | T* res = &m_data[m_size]; 31 | m_size += count; 32 | return res; 33 | } 34 | 35 | size_t capacity() const { return m_capacity; } 36 | void clear() { m_size = 0; } 37 | size_t size() const { return m_size; } 38 | size_t sizeInBytes() const { return m_size * sizeof(T); } 39 | 40 | T* data() { return m_data; } 41 | 42 | T* m_data; 43 | size_t m_size; 44 | size_t m_capacity; 45 | }; 46 | } 47 | -------------------------------------------------------------------------------- /Rush/UtilLog.cpp: -------------------------------------------------------------------------------- 1 | #include "UtilLog.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #ifdef RUSH_PLATFORM_WINDOWS 8 | #include 9 | #endif // RUSH_PLATFORM_WINDOWS 10 | 11 | #ifdef _MSC_VER 12 | #pragma warning(push) 13 | #pragma warning( \ 14 | disable : 4996) // 'vsnprintf': This function or variable may be unsafe. Consider using vsnprintf_s instead. 15 | #endif //_MSC_VER 16 | 17 | #ifdef __EMSCRIPTEN__ 18 | #undef stderr 19 | #define stderr stdout 20 | #endif 21 | 22 | namespace Rush 23 | { 24 | bool Log::breakOnError = IsDebuggerPresent(); 25 | bool Log::breakOnWarning = false; 26 | 27 | Log::LogMessageCallback Log::callbackDebug = nullptr; 28 | Log::LogMessageCallback Log::callbackMessage = nullptr; 29 | Log::LogMessageCallback Log::callbackWarning = nullptr; 30 | Log::LogMessageCallback Log::callbackError = nullptr; 31 | Log::LogMessageCallback Log::callbackFatal = nullptr; 32 | 33 | const char* Log::prefixMessage = ""; 34 | const char* Log::prefixWarning = "Warning: "; 35 | const char* Log::prefixError = "Error: "; 36 | const char* Log::prefixFatal = "Fatal: "; 37 | 38 | void Log::debug(const char* msg, ...) 39 | { 40 | if (callbackDebug) 41 | { 42 | char str[1024]; 43 | va_list varargs; 44 | va_start(varargs, msg); 45 | vsnprintf(str, sizeof(str), msg, varargs); 46 | va_end(varargs); 47 | callbackDebug(str); 48 | } 49 | else 50 | { 51 | va_list varargs; 52 | va_start(varargs, msg); 53 | 54 | #if defined(_MSC_VER) 55 | char str[1024]; 56 | vsprintf_s(str, msg, varargs); 57 | OutputDebugStringA(str); 58 | #else //_MSC_VER 59 | vfprintf(stdout, msg, varargs); 60 | fflush(stdout); 61 | #endif //_MSC_VER 62 | 63 | va_end(varargs); 64 | } 65 | } 66 | 67 | void Log::message(const char* msg, ...) 68 | { 69 | if (callbackMessage) 70 | { 71 | char str[1024]; 72 | va_list varargs; 73 | va_start(varargs, msg); 74 | vsnprintf(str, sizeof(str), msg, varargs); 75 | va_end(varargs); 76 | callbackMessage(str); 77 | } 78 | else 79 | { 80 | va_list varargs; 81 | va_start(varargs, msg); 82 | fputs(prefixMessage, stdout); 83 | vfprintf(stdout, msg, varargs); 84 | fprintf(stdout, "\n"); 85 | va_end(varargs); 86 | fflush(stdout); 87 | } 88 | } 89 | 90 | void Log::warning(const char* msg, ...) 91 | { 92 | if (callbackWarning) 93 | { 94 | char str[1024]; 95 | va_list varargs; 96 | va_start(varargs, msg); 97 | vsnprintf(str, sizeof(str), msg, varargs); 98 | va_end(varargs); 99 | callbackWarning(str); 100 | } 101 | else 102 | { 103 | #ifdef RUSH_PLATFORM_WINDOWS 104 | auto h = GetStdHandle(STD_OUTPUT_HANDLE); 105 | CONSOLE_SCREEN_BUFFER_INFO csbi; 106 | GetConsoleScreenBufferInfo(h, &csbi); 107 | SetConsoleTextAttribute(h, 0x06); 108 | #endif 109 | 110 | va_list varargs; 111 | va_start(varargs, msg); 112 | fputs(prefixWarning, stderr); 113 | vfprintf(stderr, msg, varargs); 114 | fprintf(stderr, "\n"); 115 | va_end(varargs); 116 | fflush(stderr); 117 | 118 | #ifdef RUSH_PLATFORM_WINDOWS 119 | SetConsoleTextAttribute(h, csbi.wAttributes); 120 | #endif 121 | } 122 | } 123 | 124 | void Log::error(const char* msg, ...) 125 | { 126 | if (callbackError) 127 | { 128 | char str[1024]; 129 | va_list varargs; 130 | va_start(varargs, msg); 131 | vsnprintf(str, sizeof(str), msg, varargs); 132 | va_end(varargs); 133 | callbackError(str); 134 | } 135 | else 136 | { 137 | #ifdef RUSH_PLATFORM_WINDOWS 138 | auto h = GetStdHandle(STD_OUTPUT_HANDLE); 139 | CONSOLE_SCREEN_BUFFER_INFO csbi; 140 | GetConsoleScreenBufferInfo(h, &csbi); 141 | SetConsoleTextAttribute(h, 0x0C); 142 | #endif 143 | 144 | va_list varargs; 145 | va_start(varargs, msg); 146 | fputs(prefixError, stderr); 147 | vfprintf(stderr, msg, varargs); 148 | fprintf(stderr, "\n"); 149 | va_end(varargs); 150 | fflush(stderr); 151 | 152 | #ifdef RUSH_PLATFORM_WINDOWS 153 | SetConsoleTextAttribute(h, csbi.wAttributes); 154 | #endif 155 | } 156 | } 157 | 158 | void Log::fatal(const char* msg, ...) 159 | { 160 | if (callbackFatal) 161 | { 162 | char str[1024]; 163 | va_list varargs; 164 | va_start(varargs, msg); 165 | vsnprintf(str, sizeof(str), msg, varargs); 166 | va_end(varargs); 167 | callbackFatal(str); 168 | } 169 | else 170 | { 171 | #ifdef RUSH_PLATFORM_WINDOWS 172 | auto h = GetStdHandle(STD_OUTPUT_HANDLE); 173 | CONSOLE_SCREEN_BUFFER_INFO csbi; 174 | GetConsoleScreenBufferInfo(h, &csbi); 175 | SetConsoleTextAttribute(h, 0x04); 176 | #endif 177 | 178 | va_list varargs; 179 | va_start(varargs, msg); 180 | fputs(prefixFatal, stderr); 181 | vfprintf(stderr, msg, varargs); 182 | fprintf(stderr, "\n"); 183 | va_end(varargs); 184 | fflush(stderr); 185 | 186 | #ifdef RUSH_PLATFORM_WINDOWS 187 | SetConsoleTextAttribute(h, csbi.wAttributes); 188 | #endif 189 | } 190 | } 191 | } 192 | 193 | #ifdef _MSC_VER 194 | #pragma warning(pop) 195 | #endif //_MSC_VER 196 | -------------------------------------------------------------------------------- /Rush/UtilLog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rush.h" 4 | 5 | #include "Platform.h" 6 | 7 | namespace Rush 8 | { 9 | struct Log 10 | { 11 | typedef void (*LogMessageCallback)(const char* msg); 12 | 13 | static void debug(const char* msg, ...); 14 | static void message(const char* msg, ...); 15 | static void warning(const char* msg, ...); 16 | static void error(const char* msg, ...); 17 | static void fatal(const char* msg, ...); 18 | 19 | static bool breakOnWarning; 20 | static bool breakOnError; 21 | 22 | static LogMessageCallback callbackDebug; 23 | static LogMessageCallback callbackMessage; 24 | static LogMessageCallback callbackWarning; 25 | static LogMessageCallback callbackError; 26 | static LogMessageCallback callbackFatal; 27 | 28 | static const char* prefixMessage; 29 | static const char* prefixWarning; 30 | static const char* prefixError; 31 | static const char* prefixFatal; 32 | }; 33 | 34 | #ifdef __GNUC__ 35 | #define RUSH_LOG(text, ...) {Rush::Log::message(text, ##__VA_ARGS__);} 36 | #define RUSH_LOG_WARNING(text, ...) {Rush::Log::warning(text, ##__VA_ARGS__); if(Rush::Log::breakOnWarning) RUSH_BREAK;} 37 | #define RUSH_LOG_ERROR(text, ...) {Rush::Log::error(text, ##__VA_ARGS__); if(Rush::Log::breakOnError) RUSH_BREAK;} 38 | #define RUSH_LOG_FATAL(text, ...) {Rush::Log::fatal(text, ##__VA_ARGS__); RUSH_BREAK;} 39 | #else 40 | #define RUSH_LOG(text, ...) {Rush::Log::message(text, __VA_ARGS__);} 41 | #define RUSH_LOG_WARNING(text, ...) {Rush::Log::warning(text, __VA_ARGS__); if(Rush::Log::breakOnWarning) RUSH_BREAK;} 42 | #define RUSH_LOG_ERROR(text, ...) {Rush::Log::error(text, __VA_ARGS__); if(Rush::Log::breakOnError) RUSH_BREAK;} 43 | #define RUSH_LOG_FATAL(text, ...) {Rush::Log::fatal(text, __VA_ARGS__); RUSH_BREAK;} 44 | #endif 45 | 46 | #if (defined(RUSH_DEBUG) || defined(FORCE_ASSERTS) || defined(RUSH_FORCE_ASSERTS)) 47 | #define RUSH_ASSERT(v) { if (!(v)){RUSH_LOG_FATAL("Assert '" #v "' failed in '%s'.", RUSH_FUNCTION);} } 48 | #ifdef __GNUC__ 49 | #define RUSH_ASSERT_MSG(v, msg, ...) { if (!(v)){RUSH_LOG_FATAL("Assert '" #v "' failed in '%s'. " msg, RUSH_FUNCTION, ##__VA_ARGS__);} } 50 | #else 51 | #define RUSH_ASSERT_MSG(v, msg, ...) { if (!(v)){RUSH_LOG_FATAL("Assert '" #v "' failed in '%s'. " ## msg, RUSH_FUNCTION, __VA_ARGS__);} } 52 | #endif 53 | #else 54 | #define RUSH_ASSERT(v) RUSH_UNUSED(v) 55 | #define RUSH_ASSERT_MSG(v, msg, ...) RUSH_UNUSED(v) 56 | #endif 57 | 58 | } 59 | -------------------------------------------------------------------------------- /Rush/UtilMemory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Rush 4 | { 5 | 6 | inline void* allocateBytes(size_t sizeBytes) 7 | { 8 | return new char[sizeBytes]; 9 | } 10 | 11 | inline void deallocateBytes(void* ptr) 12 | { 13 | delete [] (char*)ptr; 14 | } 15 | 16 | template class UniquePtr 17 | { 18 | public: 19 | UniquePtr() = default; 20 | explicit UniquePtr(T* in_p) : p(in_p) {} 21 | UniquePtr(nullptr_t*) : p(nullptr) {} 22 | UniquePtr(const UniquePtr&) = delete; 23 | UniquePtr(UniquePtr&& other) : p(other.p) 24 | { 25 | other.p = nullptr; 26 | } 27 | UniquePtr& operator=(const UniquePtr&) = delete; 28 | UniquePtr& operator=(UniquePtr&& other) 29 | { 30 | if (p != other.p) 31 | { 32 | delete p; 33 | p = other.p; 34 | other.p = nullptr; 35 | } 36 | return *this; 37 | } 38 | ~UniquePtr() { delete p; } 39 | 40 | T* operator->() { return p; } 41 | const T* operator->() const { return p; } 42 | T* get() { return p; } 43 | const T* get() const { return p; } 44 | 45 | private: 46 | T* p = nullptr; 47 | }; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Rush/UtilRandom.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rush.h" 4 | 5 | namespace Rush 6 | { 7 | class Rand 8 | { 9 | public: 10 | Rand(u32 seed = 0) : m_seed(seed) {} 11 | u32 rand() 12 | { 13 | m_seed = 214013 * m_seed + 2531011; 14 | return (m_seed ^ m_seed >> 16); 15 | } 16 | u32 getSeed() const { return m_seed; } 17 | float getFloat(float min, float max) 18 | { 19 | m_seed = 214013 * m_seed + 2531011; 20 | return min + float(m_seed >> 16) * (1.0f / 65535.0f) * (max - min); 21 | } 22 | int getInt(int min, int max) { return min + rand() % (max - min + 1); } 23 | u32 getUint(u32 min, u32 max) { return min + rand() % (max - min + 1); } 24 | u8 getChar(u8 min, u8 max) { return u8(min + u8(rand() % (max - min + 1))); } 25 | 26 | private: 27 | u32 m_seed; 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /Rush/UtilResourcePool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rush.h" 4 | 5 | #include "UtilLog.h" 6 | #include "UtilArray.h" 7 | 8 | #include 9 | #include 10 | 11 | namespace Rush 12 | { 13 | struct InvalidResourceHandle 14 | { 15 | }; 16 | 17 | struct UntypedResourceHandle 18 | { 19 | typedef u16 IndexType; 20 | UntypedResourceHandle(IndexType _index) : m_index(_index) {} 21 | 22 | bool valid() const { return m_index != 0; } 23 | IndexType index() const { return m_index; } 24 | 25 | IndexType m_index; 26 | }; 27 | 28 | template class ResourceHandle 29 | { 30 | public: 31 | typedef u16 IndexType; 32 | 33 | ResourceHandle() : m_index(0) {} 34 | ResourceHandle(InvalidResourceHandle) : m_index(0) {} 35 | explicit ResourceHandle(UntypedResourceHandle h) : m_index(h.index()) {} 36 | 37 | bool valid() const { return m_index != 0; } 38 | IndexType index() const { return m_index; } 39 | 40 | bool operator==(const ResourceHandle& rhs) const { return m_index == rhs.m_index; } 41 | bool operator!=(const ResourceHandle& rhs) const { return m_index != rhs.m_index; } 42 | 43 | operator UntypedResourceHandle() const { return UntypedResourceHandle(m_index); } 44 | 45 | private: 46 | ResourceHandle(IndexType idx) : m_index(idx) {} 47 | IndexType m_index; 48 | }; 49 | 50 | template class ResourcePool 51 | { 52 | public: 53 | typedef HANDLE_TYPE HandleType; 54 | 55 | ResourcePool() 56 | { 57 | push(T {}); 58 | } 59 | 60 | template 61 | HANDLE_TYPE push(DeducedT&& val) noexcept 62 | { 63 | size_t idx; 64 | if (empty.empty()) 65 | { 66 | idx = data.size(); 67 | data.push_back(std::forward(val)); 68 | } 69 | else 70 | { 71 | idx = empty.back(); 72 | empty.pop_back(); 73 | data[idx] = std::forward(val); 74 | } 75 | RUSH_ASSERT(idx < std::numeric_limits::max()) 76 | return HANDLE_TYPE(UntypedResourceHandle((UntypedResourceHandle::IndexType)idx)); 77 | } 78 | 79 | void remove(HANDLE_TYPE h) 80 | { 81 | if (h.valid()) 82 | { 83 | empty.push_back(h.index()); 84 | } 85 | } 86 | 87 | void reset() 88 | { 89 | data.clear(); 90 | empty.clear(); 91 | } 92 | 93 | u32 allocatedCount() const 94 | { 95 | return u32(data.size() - empty.size()); 96 | } 97 | 98 | const T& operator[](HANDLE_TYPE h) const { return data[h.index()]; } 99 | T& operator[](HANDLE_TYPE h) { return data[h.index()]; } 100 | 101 | DynamicArray data; 102 | DynamicArray empty; 103 | }; 104 | } 105 | -------------------------------------------------------------------------------- /Rush/UtilString.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rush.h" 4 | #include 5 | 6 | namespace Rush 7 | { 8 | 9 | class String 10 | { 11 | public: 12 | 13 | String() = default; 14 | 15 | String(const String& other) 16 | { 17 | copyFrom(other); 18 | } 19 | 20 | String(const char* data, size_t length=0) 21 | { 22 | copyFrom(data, data ? strlen(data) : 0); 23 | } 24 | 25 | String(String&& other) noexcept 26 | { 27 | moveFrom((String&&)other); 28 | } 29 | 30 | String& operator=(const char* data) 31 | { 32 | copyFrom(data, data ? strlen(data) : 0); 33 | return *this; 34 | } 35 | 36 | String& operator=(String& other) 37 | { 38 | copyFrom(other); 39 | return *this; 40 | } 41 | 42 | String& operator=(String&& other) noexcept 43 | { 44 | moveFrom((String&&)other); 45 | return *this; 46 | } 47 | 48 | ~String() 49 | { 50 | delete m_data; 51 | } 52 | 53 | const char* c_str() const 54 | { 55 | return m_data ? m_data : getEmptyString(); 56 | } 57 | 58 | size_t length() const { return m_length; } 59 | 60 | char& operator [] (size_t idx) 61 | { 62 | return m_data[idx]; 63 | } 64 | 65 | const char& operator [] (size_t idx) const 66 | { 67 | return m_data[idx]; 68 | } 69 | 70 | static const char* getEmptyString() { static const char* emptyString = ""; return emptyString; } 71 | 72 | private: 73 | 74 | void copyFrom(const char* inData, size_t inLength) 75 | { 76 | delete m_data; 77 | if (inData) 78 | { 79 | m_length = inLength; 80 | m_data = new char[inLength + 1]; 81 | memcpy(m_data, inData, inLength + 1); 82 | } 83 | else 84 | { 85 | m_length = 0; 86 | m_data = nullptr; 87 | } 88 | } 89 | 90 | void copyFrom(const String& other) 91 | { 92 | copyFrom(other.c_str(), other.length()); 93 | } 94 | 95 | void moveFrom(String&& other) 96 | { 97 | m_data = other.m_data; 98 | m_length = other.m_length; 99 | 100 | other.m_data = nullptr; 101 | other.m_length = 0; 102 | } 103 | 104 | char* m_data = nullptr; 105 | size_t m_length = 0; 106 | }; 107 | 108 | class StringView 109 | { 110 | public: 111 | 112 | StringView(const char* inData, size_t inLength) 113 | : m_data(inData) 114 | , m_length(inLength) 115 | { 116 | } 117 | 118 | size_t length() const { return m_length; } 119 | 120 | char operator [] (size_t idx) const 121 | { 122 | return m_data[idx]; 123 | } 124 | 125 | const char* data() const 126 | { 127 | return m_data ? m_data : String::getEmptyString(); 128 | } 129 | 130 | bool operator == (const char* other) const 131 | { 132 | return strncmp(m_data, other, m_length) == 0; 133 | } 134 | 135 | bool operator != (const char* other) const 136 | { 137 | return strncmp(m_data, other, m_length) != 0; 138 | } 139 | 140 | bool operator == (const StringView& other) const 141 | { 142 | return m_length == other.m_length && memcmp(m_data, other.m_data, m_length) == 0; 143 | } 144 | 145 | bool operator != (const StringView& other) const 146 | { 147 | return m_length != other.m_length || memcmp(m_data, other.m_data, m_length) != 0; 148 | } 149 | 150 | private: 151 | 152 | const char* m_data = nullptr; 153 | size_t m_length = 0; 154 | }; 155 | 156 | 157 | } -------------------------------------------------------------------------------- /Rush/UtilTimer.cpp: -------------------------------------------------------------------------------- 1 | #include "UtilTimer.h" 2 | 3 | #if defined(RUSH_PLATFORM_WINDOWS) 4 | #include 5 | #else 6 | #include 7 | #include 8 | #include 9 | #endif 10 | 11 | namespace Rush 12 | { 13 | 14 | const Timer Timer::global; 15 | 16 | Timer::Timer(void) 17 | { 18 | #if defined(RUSH_PLATFORM_WINDOWS) 19 | m_numer = 1000000; 20 | QueryPerformanceFrequency((LARGE_INTEGER*)&m_denom); 21 | #else 22 | m_numer = 1; 23 | m_denom = 1; 24 | #endif 25 | 26 | reset(); 27 | } 28 | 29 | Timer::~Timer(void) {} 30 | 31 | void Timer::reset() 32 | { 33 | #if defined(RUSH_PLATFORM_WINDOWS) 34 | QueryPerformanceCounter((LARGE_INTEGER*)&m_start); 35 | #else 36 | timeval t; 37 | gettimeofday(&t, nullptr); 38 | m_start = u64(t.tv_sec) * 1000000ULL + u64(t.tv_usec); 39 | #endif 40 | } 41 | 42 | u64 Timer::microTime() const 43 | { 44 | #if defined(RUSH_PLATFORM_WINDOWS) 45 | return ticks() * m_numer / m_denom; 46 | #else 47 | return ticks(); 48 | #endif 49 | } 50 | 51 | double Timer::time() const { return double(microTime()) / 1e6; } 52 | 53 | u64 Timer::ticks() const 54 | { 55 | #if defined(RUSH_PLATFORM_WINDOWS) 56 | u64 curtime; 57 | QueryPerformanceCounter((LARGE_INTEGER*)&curtime); 58 | return curtime - m_start; 59 | #else 60 | timeval curtime; 61 | gettimeofday(&curtime, nullptr); 62 | u64 elapsed = (u64(curtime.tv_sec) * 1000000ULL + u64(curtime.tv_usec)) - m_start; 63 | return elapsed; 64 | #endif 65 | } 66 | 67 | u64 Timer::ticksPerSecond() const 68 | { 69 | return m_denom; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /Rush/UtilTimer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rush.h" 4 | 5 | namespace Rush 6 | { 7 | class Timer 8 | { 9 | public: 10 | Timer(void); 11 | ~Timer(void); 12 | 13 | void reset(); 14 | 15 | u64 microTime() const; // elapsed time in microseconds 16 | double time() const; // elapsed time in seconds 17 | 18 | u64 ticks() const; 19 | u64 ticksPerSecond() const; 20 | 21 | static const Timer global; 22 | 23 | private: 24 | u64 m_start; 25 | u64 m_numer; 26 | u64 m_denom; 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /Rush/UtilTuple.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Rush 4 | { 5 | template struct Tuple2 6 | { 7 | T x, y; 8 | 9 | T* begin() { return &x; } 10 | T* end() { return &y + 1; } 11 | const T* begin() const { return &x; } 12 | const T* end() const { return &y + 1; } 13 | static size_t size() { return 2; } 14 | 15 | bool operator==(const Tuple2& rhs) const { return x == rhs.x && y == rhs.y; } 16 | bool operator!=(const Tuple2& rhs) const { return x != rhs.x || y != rhs.y; } 17 | }; 18 | 19 | template struct Tuple3 20 | { 21 | T x, y, z; 22 | 23 | T* begin() { return &x; } 24 | T* end() { return &z + 1; } 25 | const T* begin() const { return &x; } 26 | const T* end() const { return &z + 1; } 27 | static size_t size() { return 3; } 28 | 29 | bool operator==(const Tuple3& rhs) const { return x == rhs.x && y == rhs.y && z == rhs.z; } 30 | bool operator!=(const Tuple3& rhs) const { return x != rhs.x || y != rhs.y || z != rhs.z; } 31 | }; 32 | 33 | template struct Tuple4 34 | { 35 | T x, y, z, w; 36 | 37 | T* begin() { return &x; } 38 | T* end() { return &w + 1; } 39 | const T* begin() const { return &x; } 40 | const T* end() const { return &w + 1; } 41 | static size_t size() { return 4; } 42 | 43 | bool operator==(const Tuple4& rhs) const { return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w; } 44 | bool operator!=(const Tuple4& rhs) const { return x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w; } 45 | }; 46 | 47 | typedef Tuple2 Tuple2f; 48 | typedef Tuple3 Tuple3f; 49 | typedef Tuple4 Tuple4f; 50 | 51 | typedef Tuple2 Tuple2i; 52 | typedef Tuple3 Tuple3i; 53 | typedef Tuple4 Tuple4i; 54 | 55 | typedef Tuple2 Tuple2u; 56 | typedef Tuple3 Tuple3u; 57 | typedef Tuple4 Tuple4u; 58 | 59 | typedef Tuple2 Tuple2b; 60 | typedef Tuple3 Tuple3b; 61 | typedef Tuple4 Tuple4b; 62 | } 63 | -------------------------------------------------------------------------------- /Rush/Window.cpp: -------------------------------------------------------------------------------- 1 | #include "Window.h" 2 | 3 | namespace Rush 4 | { 5 | Window::Window(const WindowDesc& desc) 6 | : m_desc(desc) 7 | , m_refs(1) 8 | , m_size({desc.width, desc.height}) 9 | , m_pos({0, 0}) 10 | , m_resolutionScale(1, 1) 11 | , m_closed(false) 12 | , m_focused(true) 13 | , m_fullScreen(desc.fullScreen) 14 | , m_interceptor(nullptr) 15 | { 16 | } 17 | 18 | Window::~Window() 19 | { 20 | // RUSH_ASSERT(m_refs == 0); 21 | } 22 | 23 | void Window::addListener(WindowEventListener* listener) { m_listeners.push_back(listener); } 24 | 25 | void Window::removeListener(WindowEventListener* listener) 26 | { 27 | for (size_t i = 0; i < m_listeners.size(); ++i) 28 | { 29 | if (m_listeners[i] == listener) 30 | { 31 | m_listeners[i] = m_listeners.back(); 32 | m_listeners.pop_back(); 33 | break; 34 | } 35 | } 36 | } 37 | 38 | void Window::broadcast(const WindowEvent& e) 39 | { 40 | if (m_interceptor && m_interceptor->processEvent(e)) 41 | { 42 | return; 43 | } 44 | 45 | for (size_t i = 0; i < m_listeners.size(); ++i) 46 | { 47 | WindowEventListener* listener = m_listeners[i]; 48 | if (listener->mask & (1 << e.type)) 49 | { 50 | listener->push_back(e); 51 | } 52 | } 53 | } 54 | 55 | void Window::retain() { m_refs++; } 56 | 57 | u32 Window::release() 58 | { 59 | u32 prevRefCount = m_refs--; 60 | if (prevRefCount == 1) 61 | { 62 | delete this; 63 | } 64 | return prevRefCount; 65 | } 66 | 67 | const char* toString(Key key) 68 | { 69 | switch(key) 70 | { 71 | default: 72 | case Key_Unknown: return "Key_Unknown"; 73 | case Key_Space: return "Key_Space"; 74 | case Key_Apostrophe: return "Key_Apostrophe"; 75 | case Key_Comma: return "Key_Comma"; 76 | case Key_Minus: return "Key_Minus"; 77 | case Key_Period: return "Key_Period"; 78 | case Key_Slash: return "Key_Slash"; 79 | case Key_0: return "Key_0"; 80 | case Key_1: return "Key_1"; 81 | case Key_2: return "Key_2"; 82 | case Key_3: return "Key_3"; 83 | case Key_4: return "Key_4"; 84 | case Key_5: return "Key_5"; 85 | case Key_6: return "Key_6"; 86 | case Key_7: return "Key_7"; 87 | case Key_8: return "Key_8"; 88 | case Key_9: return "Key_9"; 89 | case Key_Semicolon: return "Key_Semicolon"; 90 | case Key_Equal: return "Key_Equal"; 91 | case Key_A: return "Key_A"; 92 | case Key_B: return "Key_B"; 93 | case Key_C: return "Key_C"; 94 | case Key_D: return "Key_D"; 95 | case Key_E: return "Key_E"; 96 | case Key_F: return "Key_F"; 97 | case Key_G: return "Key_G"; 98 | case Key_H: return "Key_H"; 99 | case Key_I: return "Key_I"; 100 | case Key_J: return "Key_J"; 101 | case Key_K: return "Key_K"; 102 | case Key_L: return "Key_L"; 103 | case Key_M: return "Key_M"; 104 | case Key_N: return "Key_N"; 105 | case Key_O: return "Key_O"; 106 | case Key_P: return "Key_P"; 107 | case Key_Q: return "Key_Q"; 108 | case Key_R: return "Key_R"; 109 | case Key_S: return "Key_S"; 110 | case Key_T: return "Key_T"; 111 | case Key_U: return "Key_U"; 112 | case Key_V: return "Key_V"; 113 | case Key_W: return "Key_W"; 114 | case Key_X: return "Key_X"; 115 | case Key_Y: return "Key_Y"; 116 | case Key_Z: return "Key_Z"; 117 | case Key_LeftBracket: return "Key_LeftBracket"; 118 | case Key_Backslash: return "Key_Backslash"; 119 | case Key_RightBracket: return "Key_RightBracket"; 120 | case Key_Backquote: return "Key_Backquote"; 121 | case Key_Escape: return "Key_Escape"; 122 | case Key_Enter: return "Key_Enter"; 123 | case Key_Tab: return "Key_Tab"; 124 | case Key_Backspace: return "Key_Backspace"; 125 | case Key_Insert: return "Key_Insert"; 126 | case Key_Delete: return "Key_Delete"; 127 | case Key_Right: return "Key_Right"; 128 | case Key_Left: return "Key_Left"; 129 | case Key_Down: return "Key_Down"; 130 | case Key_Up: return "Key_Up"; 131 | case Key_PageUp: return "Key_PageUp"; 132 | case Key_PageDown: return "Key_PageDown"; 133 | case Key_Home: return "Key_Home"; 134 | case Key_End: return "Key_End"; 135 | case Key_CapsLock: return "Key_CapsLock"; 136 | case Key_ScrollLock: return "Key_ScrollLock"; 137 | case Key_NumLock: return "Key_NumLock"; 138 | case Key_PrintScreen: return "Key_PrintScreen"; 139 | case Key_Pause: return "Key_Pause"; 140 | case Key_F1: return "Key_F1"; 141 | case Key_F2: return "Key_F2"; 142 | case Key_F3: return "Key_F3"; 143 | case Key_F4: return "Key_F4"; 144 | case Key_F5: return "Key_F5"; 145 | case Key_F6: return "Key_F6"; 146 | case Key_F7: return "Key_F7"; 147 | case Key_F8: return "Key_F8"; 148 | case Key_F9: return "Key_F9"; 149 | case Key_F10: return "Key_F10"; 150 | case Key_F11: return "Key_F11"; 151 | case Key_F12: return "Key_F12"; 152 | case Key_F13: return "Key_F13"; 153 | case Key_F14: return "Key_F14"; 154 | case Key_F15: return "Key_F15"; 155 | case Key_F16: return "Key_F16"; 156 | case Key_F17: return "Key_F17"; 157 | case Key_F18: return "Key_F18"; 158 | case Key_F19: return "Key_F19"; 159 | case Key_F20: return "Key_F20"; 160 | case Key_F21: return "Key_F21"; 161 | case Key_F22: return "Key_F22"; 162 | case Key_F23: return "Key_F23"; 163 | case Key_F24: return "Key_F24"; 164 | case Key_F25: return "Key_F25"; 165 | case Key_KP0: return "Key_KP0"; 166 | case Key_KP1: return "Key_KP1"; 167 | case Key_KP2: return "Key_KP2"; 168 | case Key_KP3: return "Key_KP3"; 169 | case Key_KP4: return "Key_KP4"; 170 | case Key_KP5: return "Key_KP5"; 171 | case Key_KP6: return "Key_KP6"; 172 | case Key_KP7: return "Key_KP7"; 173 | case Key_KP8: return "Key_KP8"; 174 | case Key_KP9: return "Key_KP9"; 175 | case Key_KPDecimal: return "Key_KPDecimal"; 176 | case Key_KPDivide: return "Key_KPDivide"; 177 | case Key_KPMultiply: return "Key_KPMultiply"; 178 | case Key_KPSubtract: return "Key_KPSubtract"; 179 | case Key_KPAdd: return "Key_KPAdd"; 180 | case Key_KPEnter: return "Key_KPEnter"; 181 | case Key_KPEqual: return "Key_KPEqual"; 182 | case Key_LeftShift: return "Key_LeftShift"; 183 | case Key_LeftControl: return "Key_LeftControl"; 184 | case Key_LeftAlt: return "Key_LeftAlt"; 185 | case Key_RightShift: return "Key_RightShift"; 186 | case Key_RightControl: return "Key_RightControl"; 187 | case Key_RightAlt: return "Key_RightAlt"; 188 | } 189 | } 190 | 191 | const char* toStringShort(Key key) 192 | { 193 | const char* result = toString(key); 194 | return result + 4; 195 | } 196 | 197 | } 198 | -------------------------------------------------------------------------------- /Rush/WindowMac.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Window.h" 4 | 5 | #if defined(RUSH_PLATFORM_MAC) 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | @class CAMetalLayer; 10 | #else 11 | typedef void CAMetalLayer; 12 | typedef void NSWindow; 13 | typedef void NSEvent; 14 | #endif 15 | 16 | namespace Rush 17 | { 18 | 19 | class WindowMac : public Window 20 | { 21 | 22 | public: 23 | 24 | WindowMac(const WindowDesc& desc); 25 | virtual ~WindowMac(); 26 | 27 | virtual void* nativeHandle() override; 28 | virtual void setCaption(const char* str) override; 29 | virtual void setSize(const Tuple2i& size) override; 30 | virtual void setPosition(const Tuple2i& position) override; 31 | 32 | bool processEvent(NSEvent* event); 33 | void processResize(float newWidth, float newHeight); 34 | 35 | CAMetalLayer* getMetalLayer() const { return m_metalLayer; } 36 | 37 | private: 38 | 39 | NSWindow* m_nativeWindow = nullptr; 40 | CAMetalLayer* m_metalLayer = nullptr; 41 | }; 42 | 43 | } 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /Rush/WindowMac.mm: -------------------------------------------------------------------------------- 1 | #include "WindowMac.h" 2 | #include "UtilLog.h" 3 | 4 | #if defined(RUSH_PLATFORM_MAC) 5 | 6 | #import 7 | 8 | using namespace Rush; 9 | 10 | @interface RushWindow: NSWindow 11 | { 12 | @public WindowMac* parent; 13 | } 14 | @end 15 | 16 | @implementation RushWindow 17 | @end 18 | 19 | @interface WindowMacInternal : NSObject 20 | { 21 | uint32_t windowCount; 22 | } 23 | 24 | + (WindowMacInternal*)sharedDelegate; 25 | - (id)init; 26 | - (void)windowCreated:(NSWindow*)window; 27 | - (void)windowWillClose:(NSNotification*)notification; 28 | - (BOOL)windowShouldClose:(NSWindow*)window; 29 | - (void)windowDidResize:(NSNotification*)notification; 30 | - (void)windowDidEndLiveResize:(NSNotification*)notification; 31 | - (void)windowDidBecomeKey:(NSNotification *)notification; 32 | - (void)windowDidResignKey:(NSNotification *)notification; 33 | 34 | @end 35 | 36 | @implementation WindowMacInternal 37 | 38 | + (WindowMacInternal*)sharedDelegate 39 | { 40 | static id windowDelegate = [WindowMacInternal new]; 41 | return windowDelegate; 42 | } 43 | 44 | - (id)init 45 | { 46 | self = [super init]; 47 | if (nil == self) 48 | { 49 | return nil; 50 | } 51 | 52 | self->windowCount = 0; 53 | return self; 54 | } 55 | 56 | - (void)windowCreated:(NSWindow*)window 57 | { 58 | RUSH_ASSERT(window); 59 | 60 | [window setDelegate:self]; 61 | 62 | RUSH_ASSERT(self->windowCount < ~0u); 63 | self->windowCount += 1; 64 | } 65 | 66 | - (void)windowWillClose:(NSNotification*)notification 67 | { 68 | RUSH_UNUSED(notification); 69 | } 70 | 71 | - (BOOL)windowShouldClose:(NSWindow*)window 72 | { 73 | RUSH_ASSERT(window); 74 | 75 | [window setDelegate:nil]; 76 | 77 | RUSH_ASSERT(self->windowCount); 78 | self->windowCount -= 1; 79 | 80 | if (self->windowCount == 0) 81 | { 82 | [NSApp terminate:self]; 83 | return false; 84 | } 85 | 86 | return true; 87 | } 88 | 89 | - (void)windowDidResize:(NSNotification*)notification 90 | { 91 | RUSH_UNUSED(notification); 92 | } 93 | 94 | - (void)windowDidEndLiveResize:(NSNotification*)notification 95 | { 96 | RushWindow* window = notification.object; 97 | NSView* contentView = [notification.object contentView]; 98 | CALayer* layer = [contentView layer]; 99 | CGSize frame = [layer frame].size; 100 | window->parent->processResize(frame.width, frame.height); 101 | } 102 | 103 | - (void)windowDidBecomeKey:(NSNotification*)notification 104 | { 105 | RUSH_UNUSED(notification); 106 | } 107 | 108 | - (void)windowDidResignKey:(NSNotification*)notification 109 | { 110 | RUSH_UNUSED(notification); 111 | } 112 | 113 | @end 114 | 115 | @interface RushView: NSView 116 | @end 117 | 118 | @implementation RushView 119 | - (void)keyDown:(NSEvent *)event 120 | { 121 | RUSH_UNUSED(event); 122 | } 123 | @end 124 | 125 | namespace Rush 126 | { 127 | 128 | WindowMac::WindowMac(const WindowDesc& desc) 129 | : Window(desc) 130 | { 131 | u32 styleMask = NSWindowStyleMaskTitled 132 | | NSWindowStyleMaskClosable 133 | | NSWindowStyleMaskMiniaturizable; 134 | 135 | if (desc.resizable) 136 | { 137 | styleMask |= NSWindowStyleMaskResizable; 138 | } 139 | 140 | NSScreen* mainScreen = [NSScreen mainScreen]; 141 | 142 | NSRect screenRect = [mainScreen frame]; 143 | const float centerX = (screenRect.size.width - (float)desc.width)*0.5f; 144 | const float centerY = (screenRect.size.height - (float)desc.height)*0.5f; 145 | NSRect rect = NSMakeRect(centerX, centerY, desc.width, desc.height); 146 | 147 | RushWindow* window = [[RushWindow alloc] 148 | initWithContentRect:rect 149 | styleMask:styleMask 150 | backing:NSBackingStoreBuffered 151 | defer:YES 152 | ]; 153 | m_nativeWindow = window; 154 | window->parent = this; 155 | 156 | [window.contentView setWantsLayer:YES]; 157 | 158 | NSString* appName = [[NSProcessInfo processInfo] processName]; 159 | [window setTitle:appName]; 160 | [window makeKeyAndOrderFront:window]; 161 | [window setAcceptsMouseMovedEvents:YES]; 162 | [window setBackgroundColor:[NSColor blackColor]]; 163 | [[WindowMacInternal sharedDelegate] windowCreated:window]; 164 | 165 | RushView* view = [[RushView alloc] init]; 166 | [window setContentView:view]; 167 | [window makeFirstResponder:view]; 168 | [view release]; 169 | 170 | m_metalLayer = [CAMetalLayer layer]; 171 | [window.contentView setLayer:m_metalLayer]; 172 | } 173 | 174 | WindowMac::~WindowMac() 175 | { 176 | [m_nativeWindow close]; 177 | } 178 | 179 | void* WindowMac::nativeHandle() 180 | { 181 | return m_nativeWindow; 182 | } 183 | 184 | void WindowMac::setCaption(const char* str) 185 | { 186 | // TODO 187 | } 188 | 189 | void WindowMac::setSize(const Tuple2i& size) 190 | { 191 | // TODO 192 | } 193 | 194 | void WindowMac::setPosition(const Tuple2i& position) 195 | { 196 | // TODO 197 | } 198 | 199 | static Key translateKeyMac(const NSEvent* event) 200 | { 201 | NSString* key = [event charactersIgnoringModifiers]; 202 | if ([key length] == 0) 203 | { 204 | return Key_Unknown; 205 | } 206 | 207 | unichar firstChar = [key characterAtIndex:0]; 208 | switch(firstChar) 209 | { 210 | case ' ': return Key_Space; 211 | case '\'': return Key_Apostrophe; 212 | case ',': return Key_Comma; 213 | case '-': return Key_Minus; 214 | case '.': return Key_Period; 215 | case '/': return Key_Slash; 216 | case '0': return Key_0; 217 | case '1': return Key_1; 218 | case '2': return Key_2; 219 | case '3': return Key_3; 220 | case '4': return Key_4; 221 | case '5': return Key_5; 222 | case '6': return Key_6; 223 | case '7': return Key_7; 224 | case '8': return Key_8; 225 | case '9': return Key_9; 226 | case ';': return Key_Semicolon; 227 | case '=': return Key_Equal; 228 | case 'A': 229 | case 'a': return Key_A; 230 | case 'B': 231 | case 'b': return Key_B; 232 | case 'C': 233 | case 'c': return Key_C; 234 | case 'D': 235 | case 'd': return Key_D; 236 | case 'E': 237 | case 'e': return Key_E; 238 | case 'F': 239 | case 'f': return Key_F; 240 | case 'G': 241 | case 'g': return Key_G; 242 | case 'H': 243 | case 'h': return Key_H; 244 | case 'I': 245 | case 'i': return Key_I; 246 | case 'J': 247 | case 'j': return Key_J; 248 | case 'K': 249 | case 'k': return Key_K; 250 | case 'L': 251 | case 'l': return Key_L; 252 | case 'M': 253 | case 'm': return Key_M; 254 | case 'N': 255 | case 'n': return Key_N; 256 | case 'O': 257 | case 'o': return Key_O; 258 | case 'P': 259 | case 'p': return Key_P; 260 | case 'Q': 261 | case 'q': return Key_Q; 262 | case 'R': 263 | case 'r': return Key_R; 264 | case 'S': 265 | case 's': return Key_S; 266 | case 'T': 267 | case 't': return Key_T; 268 | case 'U': 269 | case 'u': return Key_U; 270 | case 'V': 271 | case 'v': return Key_V; 272 | case 'W': 273 | case 'w': return Key_W; 274 | case 'X': 275 | case 'x': return Key_X; 276 | case 'Y': 277 | case 'y': return Key_Y; 278 | case 'Z': 279 | case 'z': return Key_Z; 280 | case '[': return Key_LeftBracket; 281 | case '\\': return Key_Backslash; 282 | case ']': return Key_RightBracket; 283 | case '\r': return Key_Enter; 284 | case NSRightArrowFunctionKey: return Key_Right; 285 | case NSLeftArrowFunctionKey: return Key_Left; 286 | case NSDownArrowFunctionKey: return Key_Down; 287 | case NSUpArrowFunctionKey: return Key_Up; 288 | case NSF1FunctionKey: return Key_F1; 289 | case NSF2FunctionKey: return Key_F2; 290 | case NSF3FunctionKey: return Key_F3; 291 | case NSF4FunctionKey: return Key_F4; 292 | case NSF5FunctionKey: return Key_F5; 293 | case NSF6FunctionKey: return Key_F6; 294 | case NSF7FunctionKey: return Key_F7; 295 | case NSF8FunctionKey: return Key_F8; 296 | case NSF9FunctionKey: return Key_F9; 297 | case NSF10FunctionKey: return Key_F10; 298 | case NSF11FunctionKey: return Key_F11; 299 | case NSF12FunctionKey: return Key_F12; 300 | default: return Key_Unknown; 301 | }; 302 | } 303 | 304 | void WindowMac::processResize(float newWidth, float newHeight) 305 | { 306 | Tuple2i pendingSize; 307 | pendingSize.x = int(newWidth); 308 | pendingSize.y = int(newHeight); 309 | 310 | if (m_size != pendingSize) 311 | { 312 | m_size = pendingSize; 313 | broadcast(WindowEvent::Resize(m_size.x, m_size.y)); 314 | } 315 | } 316 | 317 | bool WindowMac::processEvent(NSEvent* event) 318 | { 319 | NSEventType eventType = [event type]; 320 | switch (eventType) 321 | { 322 | case NSEventTypeLeftMouseDragged: 323 | case NSEventTypeRightMouseDragged: 324 | case NSEventTypeOtherMouseDragged: 325 | case NSEventTypeMouseMoved: 326 | { 327 | NSPoint mouseLocation = [event locationInWindow]; 328 | float xPos = mouseLocation.x; 329 | float yPos = getSize().y - mouseLocation.y; 330 | m_mouse.pos = Vec2(xPos, yPos); 331 | broadcast(WindowEvent::MouseMove(m_mouse.pos)); 332 | return true; 333 | } 334 | case NSEventTypeLeftMouseDown: 335 | { 336 | m_mouse.buttons[0] = true; 337 | broadcast(WindowEvent::MouseDown(m_mouse.pos, 0, false)); 338 | return true; 339 | } 340 | case NSEventTypeLeftMouseUp: 341 | { 342 | m_mouse.buttons[0] = false; 343 | broadcast(WindowEvent::MouseUp(m_mouse.pos, 0)); 344 | return false; 345 | } 346 | case NSEventTypeRightMouseDown: 347 | { 348 | m_mouse.buttons[1] = true; 349 | broadcast(WindowEvent::MouseDown(m_mouse.pos, 1, false)); 350 | return true; 351 | } 352 | case NSEventTypeRightMouseUp: 353 | { 354 | m_mouse.buttons[1] = false; 355 | broadcast(WindowEvent::MouseUp(m_mouse.pos, 1)); 356 | return true; 357 | } 358 | case NSEventTypeOtherMouseDown: 359 | //Log::message("NSOtherMouseDown"); 360 | return false; 361 | case NSEventTypeOtherMouseUp: 362 | //Log::message("NSOtherMouseUp"); 363 | return false; 364 | case NSEventTypeScrollWheel: 365 | { 366 | float deltaY = [event deltaY] * 0.25f; 367 | m_mouse.wheelV += deltaY; 368 | broadcast(WindowEvent::Scroll(0.0f, deltaY)); 369 | return true; 370 | } 371 | case NSEventTypeKeyDown: 372 | { 373 | Key key = translateKeyMac(event); 374 | m_keyboard.keys[key] = true; 375 | auto e = WindowEvent::KeyDown(key); 376 | broadcast(e); 377 | 378 | NSString* chars = [event charactersIgnoringModifiers]; 379 | if ([chars length] != 0) 380 | { 381 | broadcast(WindowEvent::Char([chars characterAtIndex:0])); 382 | } 383 | 384 | return true; 385 | } 386 | case NSEventTypeKeyUp: 387 | { 388 | Key key = translateKeyMac(event); 389 | m_keyboard.keys[key] = false; 390 | auto e = WindowEvent::KeyUp(key); 391 | broadcast(e); 392 | return true; 393 | } 394 | case NSEventTypeFlagsChanged: 395 | { 396 | u16 keyCode = [event keyCode]; 397 | 398 | Key key = Key_Unknown; 399 | switch(keyCode) 400 | { 401 | case 56: 402 | key = Key_LeftShift; 403 | break; 404 | case 60: 405 | key = Key_RightShift; 406 | break; 407 | case 59: 408 | key = Key_LeftControl; 409 | break; 410 | default: 411 | key = Key_Unknown; 412 | break; 413 | } 414 | 415 | if (key != Key_Unknown) 416 | { 417 | if (m_keyboard.keys[key]) 418 | { 419 | auto e = WindowEvent::KeyUp(key); 420 | broadcast(e); 421 | m_keyboard.keys[key] = false; 422 | } 423 | else 424 | { 425 | auto e = WindowEvent::KeyDown(key); 426 | broadcast(e); 427 | m_keyboard.keys[key] = true; 428 | } 429 | } 430 | 431 | return true; 432 | } 433 | default: 434 | //Log::message("Unhandled event type"); 435 | return false; 436 | } 437 | } 438 | 439 | } 440 | 441 | #endif 442 | -------------------------------------------------------------------------------- /Rush/WindowWin32.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef RUSH_PLATFORM_WINDOWS 4 | 5 | #include "Window.h" 6 | #include "UtilString.h" 7 | 8 | #include 9 | 10 | namespace Rush 11 | { 12 | 13 | class WindowWin32 : public Window 14 | { 15 | 16 | public: 17 | WindowWin32(const WindowDesc& desc); 18 | virtual ~WindowWin32(); 19 | 20 | virtual void* nativeHandle(); 21 | virtual void setCaption(const char* str); 22 | virtual void setSize(const Tuple2i& size); 23 | virtual bool setFullscreen(bool state); 24 | 25 | private: 26 | bool processMessage(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); 27 | 28 | void processMouseEvent(UINT message, WPARAM wparam, LPARAM lparam); 29 | bool processKeyEvent(UINT message, WPARAM wparam, LPARAM lparam); 30 | void processSizeEvent(WPARAM wparam, LPARAM lparam); 31 | 32 | static LRESULT APIENTRY windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); 33 | 34 | void finishResizing(); 35 | 36 | HWND m_hwnd; 37 | 38 | String m_caption; 39 | 40 | Tuple2i m_pendingSize; 41 | 42 | bool m_maximized = false; 43 | bool m_minimized = false; 44 | bool m_resizing = false; 45 | Tuple2i m_windowedSize; 46 | Tuple2i m_windowedPos; 47 | 48 | u32 m_windowStyle = 0; 49 | }; 50 | } 51 | 52 | #endif // RUSH_PLATFORM_WINDOWS 53 | -------------------------------------------------------------------------------- /Rush/WindowXCB.cpp: -------------------------------------------------------------------------------- 1 | #include "Rush.h" 2 | 3 | #ifdef RUSH_PLATFORM_LINUX 4 | 5 | #include "Platform.h" 6 | #include "WindowXCB.h" 7 | #include "UtilLog.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace Rush 14 | { 15 | 16 | namespace 17 | { 18 | xcb_connection_t* g_xcbConnection = nullptr; 19 | xcb_screen_t* g_xcbScreen = nullptr; 20 | u32 g_xcbConnectionRefCount = 0; 21 | u32 g_xcbKeyMap[256]; 22 | 23 | } 24 | 25 | WindowXCB::WindowXCB(const WindowDesc& desc) 26 | : Window(desc) 27 | , m_pendingSize(m_size) 28 | { 29 | if (g_xcbConnectionRefCount == 0) 30 | { 31 | int screen = 0; 32 | 33 | g_xcbConnection = xcb_connect(nullptr, &screen); 34 | if (!g_xcbConnection) 35 | { 36 | RUSH_LOG_FATAL("xcb_connect failed"); 37 | } 38 | 39 | if (xcb_connection_has_error(g_xcbConnection)) 40 | { 41 | RUSH_LOG_FATAL("xcb connection is invalid"); 42 | } 43 | 44 | const xcb_setup_t* setup = xcb_get_setup(g_xcbConnection); 45 | xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup); 46 | while (screen-- > 0) xcb_screen_next(&iter); 47 | 48 | g_xcbScreen = iter.data; 49 | 50 | RUSH_ASSERT(g_xcbScreen); 51 | 52 | xcb_key_symbols_t* symbols = xcb_key_symbols_alloc(g_xcbConnection); 53 | for (u32 i=0; i<256; ++i) 54 | { 55 | g_xcbKeyMap[i] = xcb_key_symbols_get_keysym(symbols, i, 0); 56 | } 57 | xcb_key_symbols_free(symbols); 58 | } 59 | 60 | g_xcbConnectionRefCount++; 61 | 62 | m_nativeHandle = xcb_generate_id(g_xcbConnection); 63 | 64 | uint32_t valueMask, valueList[32]; 65 | valueMask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; 66 | valueList[0] = g_xcbScreen->black_pixel; 67 | valueList[1] = 68 | XCB_EVENT_MASK_KEY_PRESS | 69 | XCB_EVENT_MASK_KEY_RELEASE | 70 | XCB_EVENT_MASK_BUTTON_PRESS | 71 | XCB_EVENT_MASK_BUTTON_RELEASE | 72 | XCB_EVENT_MASK_ENTER_WINDOW | 73 | XCB_EVENT_MASK_LEAVE_WINDOW | 74 | XCB_EVENT_MASK_POINTER_MOTION | 75 | //XCB_EVENT_MASK_POINTER_MOTION_HINT | 76 | XCB_EVENT_MASK_BUTTON_1_MOTION | 77 | XCB_EVENT_MASK_BUTTON_2_MOTION | 78 | XCB_EVENT_MASK_BUTTON_3_MOTION | 79 | XCB_EVENT_MASK_BUTTON_4_MOTION | 80 | XCB_EVENT_MASK_BUTTON_5_MOTION | 81 | XCB_EVENT_MASK_BUTTON_MOTION | 82 | XCB_EVENT_MASK_KEYMAP_STATE | 83 | XCB_EVENT_MASK_EXPOSURE | 84 | XCB_EVENT_MASK_VISIBILITY_CHANGE | 85 | XCB_EVENT_MASK_STRUCTURE_NOTIFY | 86 | //XCB_EVENT_MASK_RESIZE_REDIRECT | 87 | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | 88 | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | 89 | XCB_EVENT_MASK_FOCUS_CHANGE | 90 | XCB_EVENT_MASK_PROPERTY_CHANGE | 91 | XCB_EVENT_MASK_COLOR_MAP_CHANGE | 92 | XCB_EVENT_MASK_OWNER_GRAB_BUTTON; 93 | 94 | xcb_create_window(g_xcbConnection, XCB_COPY_FROM_PARENT, m_nativeHandle, g_xcbScreen->root, 0, 0, u16(desc.width), u16(desc.height), 95 | 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, g_xcbScreen->root_visual, valueMask, valueList); 96 | 97 | { 98 | xcb_intern_atom_cookie_t protocolCookie = xcb_intern_atom_unchecked(g_xcbConnection, 1, 12, "WM_PROTOCOLS"); 99 | xcb_intern_atom_reply_t* protocolReply = xcb_intern_atom_reply(g_xcbConnection, protocolCookie, 0); 100 | xcb_intern_atom_cookie_t closeCookie = xcb_intern_atom_unchecked(g_xcbConnection, 0, 16, "WM_DELETE_WINDOW"); 101 | 102 | m_closeReply = xcb_intern_atom_reply(g_xcbConnection, closeCookie, 0); 103 | xcb_change_property( 104 | g_xcbConnection, 105 | XCB_PROP_MODE_REPLACE, 106 | m_nativeHandle, 107 | protocolReply->atom, 108 | 4, 32, 1, &(m_closeReply->atom)); 109 | free(protocolReply); 110 | } 111 | 112 | xcb_map_window(g_xcbConnection, m_nativeHandle); 113 | 114 | //const uint32_t coords[] = {100, 100}; // TODO: place in the center of the screen 115 | //xcb_configure_window(g_xcbConnection, m_nativeHandle, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, coords); 116 | 117 | xcb_flush(g_xcbConnection); 118 | 119 | setCaption(desc.caption); 120 | } 121 | 122 | WindowXCB::~WindowXCB() 123 | { 124 | xcb_destroy_window(g_xcbConnection, m_nativeHandle); 125 | free(m_closeReply); 126 | 127 | RUSH_ASSERT(g_xcbConnectionRefCount != 0); 128 | if (--g_xcbConnectionRefCount == 0) 129 | { 130 | xcb_disconnect(g_xcbConnection); 131 | } 132 | } 133 | 134 | void* WindowXCB::nativeConnection() 135 | { 136 | return g_xcbConnection; 137 | } 138 | 139 | void WindowXCB::setCaption(const char* str) 140 | { 141 | if (str == nullptr) 142 | { 143 | str = ""; 144 | } 145 | 146 | m_caption = str; 147 | 148 | xcb_change_property( 149 | g_xcbConnection, 150 | XCB_PROP_MODE_REPLACE, 151 | m_nativeHandle, 152 | XCB_ATOM_WM_NAME, 153 | XCB_ATOM_STRING, 154 | 8, // format 155 | strlen(m_caption.c_str()), 156 | m_caption.c_str()); 157 | } 158 | 159 | void WindowXCB::setSize(const Tuple2i& size) 160 | { 161 | RUSH_LOG_FATAL("%s is not implemented", __PRETTY_FUNCTION__); // TODO 162 | } 163 | 164 | bool WindowXCB::setFullscreen(bool wantFullScreen) 165 | { 166 | RUSH_LOG_FATAL("%s is not implemented", __PRETTY_FUNCTION__); // TODO 167 | 168 | return false; 169 | } 170 | 171 | Key translateKeyXCB(xcb_keycode_t code) 172 | { 173 | xcb_keysym_t sym = g_xcbKeyMap[code]; 174 | switch (sym) 175 | { 176 | case XK_space: return Key_Space; 177 | case XK_comma: return Key_Comma; 178 | case XK_minus: return Key_Minus; 179 | case XK_period: return Key_Period; 180 | case XK_slash: return Key_Slash; 181 | case '0': return Key_0; 182 | case '1': return Key_1; 183 | case '2': return Key_2; 184 | case '3': return Key_3; 185 | case '4': return Key_4; 186 | case '5': return Key_5; 187 | case '6': return Key_6; 188 | case '7': return Key_7; 189 | case '8': return Key_8; 190 | case '9': return Key_9; 191 | case XK_semicolon: return Key_Semicolon; 192 | case XK_equal: return Key_Equal; 193 | case 'a': return Key_A; 194 | case 'b': return Key_B; 195 | case 'c': return Key_C; 196 | case 'd': return Key_D; 197 | case 'e': return Key_E; 198 | case 'f': return Key_F; 199 | case 'g': return Key_G; 200 | case 'h': return Key_H; 201 | case 'i': return Key_I; 202 | case 'j': return Key_J; 203 | case 'k': return Key_K; 204 | case 'l': return Key_L; 205 | case 'm': return Key_M; 206 | case 'n': return Key_N; 207 | case 'o': return Key_O; 208 | case 'p': return Key_P; 209 | case 'q': return Key_Q; 210 | case 'r': return Key_R; 211 | case 's': return Key_S; 212 | case 't': return Key_T; 213 | case 'u': return Key_U; 214 | case 'v': return Key_V; 215 | case 'w': return Key_W; 216 | case 'x': return Key_X; 217 | case 'y': return Key_Y; 218 | case 'z': return Key_Z; 219 | case XK_bracketleft: return Key_LeftBracket; 220 | case XK_backslash: return Key_Backslash; 221 | case XK_bracketright: return Key_RightBracket; 222 | case XK_Escape: return Key_Escape; 223 | case XK_Return: return Key_Enter; 224 | case XK_Tab: return Key_Tab; 225 | case XK_BackSpace: return Key_Backspace; 226 | case XK_Insert: return Key_Insert; 227 | case XK_Delete: return Key_Delete; 228 | case XK_Right: return Key_Right; 229 | case XK_Left: return Key_Left; 230 | case XK_Down: return Key_Down; 231 | case XK_Up: return Key_Up; 232 | case XK_Page_Up: return Key_PageUp; 233 | case XK_Page_Down: return Key_PageDown; 234 | case XK_Home: return Key_Home; 235 | case XK_End: return Key_End; 236 | case XK_Caps_Lock: return Key_CapsLock; 237 | case XK_Scroll_Lock: return Key_ScrollLock; 238 | case XK_Num_Lock: return Key_NumLock; 239 | case XK_Print: return Key_PrintScreen; 240 | case XK_Pause: return Key_Pause; 241 | case XK_F1: return Key_F1; 242 | case XK_F2: return Key_F2; 243 | case XK_F3: return Key_F3; 244 | case XK_F4: return Key_F4; 245 | case XK_F5: return Key_F5; 246 | case XK_F6: return Key_F6; 247 | case XK_F7: return Key_F7; 248 | case XK_F8: return Key_F8; 249 | case XK_F9: return Key_F9; 250 | case XK_F10: return Key_F10; 251 | case XK_F11: return Key_F11; 252 | case XK_F12: return Key_F12; 253 | case XK_F13: return Key_F13; 254 | case XK_F14: return Key_F14; 255 | case XK_F15: return Key_F15; 256 | case XK_F16: return Key_F16; 257 | case XK_F17: return Key_F17; 258 | case XK_F18: return Key_F18; 259 | case XK_F19: return Key_F19; 260 | case XK_F20: return Key_F20; 261 | case XK_F21: return Key_F21; 262 | case XK_F22: return Key_F22; 263 | case XK_F23: return Key_F23; 264 | case XK_F24: return Key_F24; 265 | case XK_Shift_L: return Key_LeftShift; 266 | case XK_Control_L: return Key_LeftControl; 267 | case XK_Alt_L: return Key_LeftAlt; 268 | 269 | default: return Key_Unknown; 270 | } 271 | } 272 | 273 | void WindowXCB::pollEvents() 274 | { 275 | for(;;) 276 | { 277 | xcb_generic_event_t* xcbEvent = xcb_poll_for_event(g_xcbConnection); 278 | if (!xcbEvent) break; 279 | 280 | u32 mouseButtonRemap[4] = {0, 0, 2, 1}; 281 | 282 | const u8 eventCode = xcbEvent->response_type & 0x7f; 283 | switch (eventCode) 284 | { 285 | case XCB_EXPOSE: 286 | { 287 | break; 288 | } 289 | case XCB_CLIENT_MESSAGE: 290 | { 291 | if( (*(xcb_client_message_event_t*)xcbEvent).data.data32[0] == (*m_closeReply).atom ) 292 | { 293 | close(); 294 | } 295 | break; 296 | } 297 | case XCB_CONFIGURE_NOTIFY: 298 | { 299 | const xcb_configure_notify_event_t* event = (const xcb_configure_notify_event_t *)xcbEvent; 300 | if (event->width > 0 && event->height > 0) 301 | { 302 | m_pendingSize.x = event->width; 303 | m_pendingSize.y = event->height; 304 | if (m_size != m_pendingSize) 305 | { 306 | m_size = m_pendingSize; 307 | broadcast(WindowEvent::Resize(m_size.x, m_size.y)); 308 | } 309 | } 310 | break; 311 | } 312 | case XCB_MOTION_NOTIFY: 313 | { 314 | const xcb_motion_notify_event_t* event = (const xcb_motion_notify_event_t *)xcbEvent; 315 | m_mouse.pos.x = event->event_x; 316 | m_mouse.pos.y = event->event_y; 317 | broadcast(WindowEvent::MouseMove(Vec2(m_mouse.pos))); 318 | break; 319 | } 320 | case XCB_BUTTON_PRESS: 321 | { 322 | const xcb_button_press_event_t* event = (const xcb_button_press_event_t *)xcbEvent; 323 | if (event->detail > 0 && event->detail < 4) 324 | { 325 | u32 idx = mouseButtonRemap[event->detail]; 326 | m_mouse.buttons[idx] = true; 327 | m_mouse.pos.x = event->event_x; 328 | m_mouse.pos.y = event->event_y; 329 | broadcast(WindowEvent::MouseDown(m_mouse.pos, idx, false)); 330 | } 331 | else if(event->detail == 4) broadcast(WindowEvent::Scroll(0.0, 1.0)); 332 | else if(event->detail == 5) broadcast(WindowEvent::Scroll(0.0, -1.0)); 333 | else if(event->detail == 6) broadcast(WindowEvent::Scroll(1.0, 0.0)); 334 | else if(event->detail == 7) broadcast(WindowEvent::Scroll(-1.0, 0.0)); 335 | 336 | break; 337 | } 338 | case XCB_BUTTON_RELEASE: 339 | { 340 | const xcb_button_release_event_t* event = (const xcb_button_release_event_t *)xcbEvent; 341 | if (event->detail > 0 && event->detail <= 3) 342 | { 343 | u32 idx = mouseButtonRemap[event->detail]; 344 | m_mouse.buttons[idx] = false; 345 | m_mouse.pos.x = event->event_x; 346 | m_mouse.pos.y = event->event_y; 347 | broadcast(WindowEvent::MouseUp(m_mouse.pos, idx)); 348 | } 349 | break; 350 | } 351 | case XCB_KEY_PRESS: 352 | { 353 | const xcb_key_press_event_t* event = (const xcb_key_press_event_t *)xcbEvent; 354 | Key key = translateKeyXCB(event->detail); 355 | m_keyboard.keys[key] = true; 356 | broadcast(WindowEvent::KeyDown(key)); 357 | } break; 358 | case XCB_KEY_RELEASE: 359 | { 360 | const xcb_key_release_event_t* event = (const xcb_key_release_event_t *)xcbEvent; 361 | Key key = translateKeyXCB(event->detail); 362 | m_keyboard.keys[key] = false; 363 | broadcast(WindowEvent::KeyUp(key)); 364 | } break; 365 | default: 366 | break; 367 | } 368 | 369 | free(xcbEvent); 370 | } 371 | } 372 | 373 | } 374 | 375 | #else // RUSH_PLATFORM_LINUX 376 | 377 | char WindowXCB_cpp_dummy; // suppress linker warning 378 | 379 | #endif // RUSH_PLATFORM_LINUX 380 | -------------------------------------------------------------------------------- /Rush/WindowXCB.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef RUSH_PLATFORM_LINUX 4 | 5 | #include "Window.h" 6 | #include "UtilString.h" 7 | 8 | #include 9 | 10 | namespace Rush 11 | { 12 | 13 | class WindowXCB final : public Window 14 | { 15 | 16 | public: 17 | WindowXCB(const WindowDesc& desc); 18 | virtual ~WindowXCB(); 19 | 20 | virtual void* nativeConnection() override; 21 | virtual void* nativeHandle() override { return (void*)uintptr_t(m_nativeHandle); }; 22 | virtual void setCaption(const char* str) override; 23 | virtual void setSize(const Tuple2i& size) override; 24 | virtual bool setFullscreen(bool state) override; 25 | virtual void pollEvents() override; 26 | 27 | private: 28 | 29 | void setCaptionInternal(const char* str); 30 | 31 | xcb_window_t m_nativeHandle = 0; 32 | String m_caption; 33 | Tuple2i m_pendingSize; 34 | xcb_intern_atom_reply_t* m_closeReply = nullptr; 35 | }; 36 | } 37 | 38 | #endif // RUSH_PLATFORM_LINUX 39 | -------------------------------------------------------------------------------- /Scripts/cmake-vs2017-vk.cmd: -------------------------------------------------------------------------------- 1 | cmake -G "Visual Studio 15 2017 Win64" -DRUSH_RENDER_API=VK -B..\Build\vs2017-vk -H.. 2 | -------------------------------------------------------------------------------- /Scripts/cmake-vs2019-vk.cmd: -------------------------------------------------------------------------------- 1 | cmake -G "Visual Studio 16 2019" -DRUSH_RENDER_API=VK -B..\Build\vs2019-vk -H.. 2 | -------------------------------------------------------------------------------- /Scripts/embed_shaders.py: -------------------------------------------------------------------------------- 1 | import codecs 2 | from collections import namedtuple 3 | import os 4 | import subprocess 5 | import sys 6 | import textwrap 7 | 8 | BinText = namedtuple('BinText', 'declaration, definition') 9 | 10 | def bin2cpp(filename, variableName): 11 | s = open(filename, 'rb').read() 12 | s = codecs.encode(s, "hex").decode().upper() 13 | 14 | t=",".join(["0x"+x+y for (x,y) in zip(s[0::2], s[1::2])]) 15 | 16 | declarationText = "extern const unsigned char " + variableName + "data[];" 17 | declarationText += "\n"; 18 | declarationText += "extern const size_t " + variableName + "size;" 19 | 20 | definitionText = "const unsigned char " + variableName + "data[] = {\n\t%s\n};"%" \n\t".join(textwrap.wrap(t,80)) 21 | definitionText += "\n"; 22 | definitionText += "const size_t " + variableName + "size = sizeof(" + variableName + "data);" 23 | 24 | return BinText( 25 | declaration = declarationText, 26 | definition = definitionText 27 | ) 28 | 29 | # Compile shaders and generate .h / .cpp code 30 | 31 | header = '#pragma once\n// clang-format off\nnamespace Rush\n{\n' 32 | source = '#include "GfxEmbeddedShaders.h"\n// clang-format off\nnamespace Rush\n{\n' 33 | 34 | Shader = namedtuple('Shader', 'filename, entry, target') 35 | 36 | hlslShaders = [ 37 | Shader( 38 | filename = "..\\Shaders\\Primitive.hlsl", 39 | entry = "psMain", 40 | target = "ps_5_0", 41 | ), 42 | Shader( 43 | filename = "..\\Shaders\\Primitive.hlsl", 44 | entry = "psMainTextured", 45 | target = "ps_5_0", 46 | ), 47 | Shader( 48 | filename = "..\\Shaders\\Primitive.hlsl", 49 | entry = "vsMain3D", 50 | target = "vs_5_0", 51 | ), 52 | Shader( 53 | filename = "..\\Shaders\\Primitive.hlsl", 54 | entry = "vsMain2D", 55 | target = "vs_5_0", 56 | ), 57 | ] 58 | 59 | # SPIR-V shaders 60 | 61 | for shader in hlslShaders: 62 | # TODO: find glslc.exe and report error if not found 63 | hlslCompiler = "glslc.exe" 64 | inputFilename = os.path.normpath(shader.filename) 65 | shaderDirectory = os.path.dirname(shader.filename) 66 | outputFilename = os.path.join(shaderDirectory, shader.entry+".spv") 67 | stageMap = dict( 68 | vs_5_0="vertex", 69 | ps_5_0="fragment" 70 | ) 71 | command = [ 72 | hlslCompiler, 73 | "-x", "hlsl", 74 | "-o", outputFilename, 75 | "-fentry-point=" + shader.entry, 76 | "-fshader-stage=" + stageMap[shader.target], 77 | #"-DVULKAN=1", 78 | inputFilename 79 | ] 80 | print(" ".join(command)) 81 | compileResult = subprocess.call(command, stdout=subprocess.DEVNULL) 82 | if compileResult != 0: 83 | exit(1) 84 | variableNamePrefix = "SPV_" + shader.entry + "_" 85 | text = bin2cpp(outputFilename, variableNamePrefix) 86 | header += text.declaration + "\n"; 87 | source += text.definition + "\n"; 88 | os.remove(outputFilename) 89 | 90 | # DXBC shaders 91 | 92 | for shader in hlslShaders: 93 | # TODO: find fxc.exe and report error if not found 94 | hlslCompiler = "C:\\Program Files (x86)\\Windows Kits\\10\\bin\\x64\\fxc.exe" 95 | inputFilename = os.path.normpath(shader.filename) 96 | shaderDirectory = os.path.dirname(shader.filename) 97 | outputFilename = os.path.join(shaderDirectory, shader.entry+".dxbc") 98 | command = [ 99 | hlslCompiler, 100 | "/nologo", 101 | "/Fo", outputFilename, 102 | "/E", shader.entry, 103 | "/T", shader.target, 104 | inputFilename 105 | ] 106 | print(" ".join(command)) 107 | compileResult = subprocess.call(command, stdout=subprocess.DEVNULL) 108 | if compileResult != 0: 109 | exit(1) 110 | variableNamePrefix = "DXBC_" + shader.entry + "_" 111 | text = bin2cpp(outputFilename, variableNamePrefix) 112 | header += text.declaration + "\n"; 113 | source += text.definition + "\n"; 114 | os.remove(outputFilename) 115 | 116 | # Output results 117 | 118 | header += "}" 119 | source += "}" 120 | 121 | with open("..\\Rush\\GfxEmbeddedShaders.h", "w") as fileOut: 122 | fileOut.write(header) 123 | 124 | with open("..\\Rush\\GfxEmbeddedShaders.cpp", "w") as fileOut: 125 | fileOut.write(source) 126 | -------------------------------------------------------------------------------- /Shaders/Primitive.hlsl: -------------------------------------------------------------------------------- 1 | struct Constants 2 | { 3 | float4x4 matViewProj; 4 | float4 transform2D; 5 | float4 color; 6 | }; 7 | 8 | struct VSInput 9 | { 10 | float3 a_pos0 : POSITION0; 11 | float2 a_tex0 : TEXCOORD0; 12 | float4 a_col0 : COLOR0; 13 | }; 14 | 15 | struct VSOutput 16 | { 17 | float4 pos : SV_Position; 18 | float2 tex : TEXCOORD0; 19 | float4 col : COLOR0; 20 | }; 21 | 22 | cbuffer constantBuffer0 : register(b0) 23 | { 24 | Constants constantBuffer0; 25 | }; 26 | 27 | SamplerState sampler0 : register(s1); 28 | Texture2D texture0 : register(t2); 29 | 30 | VSOutput vsMain3D(VSInput v) 31 | { 32 | VSOutput res; 33 | res.pos = mul(float4(v.a_pos0, 1), constantBuffer0.matViewProj); 34 | res.col = v.a_col0; 35 | res.tex = v.a_tex0; 36 | return res; 37 | } 38 | 39 | VSOutput vsMain2D(VSInput v) 40 | { 41 | VSOutput res; 42 | res.pos.xy = v.a_pos0.xy * constantBuffer0.transform2D.xy + constantBuffer0.transform2D.zw; 43 | res.pos.zw = float2(v.a_pos0.z, 1); 44 | res.col = v.a_col0; 45 | res.tex = v.a_tex0; 46 | return res; 47 | } 48 | 49 | float4 psMain(VSOutput v) : SV_Target 50 | { 51 | return v.col * constantBuffer0.color; 52 | } 53 | 54 | float4 psMainTextured(VSOutput v) : SV_Target 55 | { 56 | return v.col * texture0.Sample(sampler0, v.tex) * constantBuffer0.color; 57 | } 58 | --------------------------------------------------------------------------------