├── LICENSE ├── README.md ├── example_fbo ├── CMakeLists.txt ├── main.c └── shaders │ ├── build_shaders.sh │ ├── build_shaders_yariv.sh │ ├── spv │ ├── buf.frag.spv │ ├── buf.vert.spv │ ├── main.frag.spv │ └── main.vert.spv │ ├── src │ ├── bin │ │ ├── buf.frag.hex │ │ ├── buf.frag.spv │ │ ├── buf.frag.yariv │ │ ├── buf.vert.hex │ │ ├── buf.vert.spv │ │ ├── buf.vert.yariv │ │ ├── main.frag.hex │ │ ├── main.frag.spv │ │ ├── main.frag.yariv │ │ ├── main.vert.hex │ │ ├── main.vert.spv │ │ └── main.vert.yariv │ ├── buf.frag │ ├── buf.vert │ ├── buf0.glsl │ ├── main.frag │ ├── main.vert │ └── main_image.glsl │ ├── yariv_pack │ └── yariv_to_hex.py ├── example_game ├── CMakeLists.txt ├── engine.h ├── main.c └── shaders │ ├── build_shaders.sh │ ├── build_shaders_yariv.sh │ ├── spv │ ├── main.frag.spv │ └── main.vert.spv │ ├── src │ ├── bin │ │ ├── main.frag.hex │ │ ├── main.frag.spv │ │ ├── main.frag.yariv │ │ ├── main.vert.hex │ │ ├── main.vert.spv │ │ └── main.vert.yariv │ ├── main.frag │ ├── main.vert │ └── main_image.glsl │ ├── yariv_pack │ └── yariv_to_hex.py ├── example_images ├── CMakeLists.txt ├── main.c ├── shaders │ ├── build_shaders.sh │ ├── spv │ │ ├── main.frag.spv │ │ └── main.vert.spv │ └── src │ │ ├── main.frag │ │ ├── main.vert │ │ └── main_image.glsl ├── stb_image.h └── textures │ ├── 1.jpg │ └── 2.png ├── example_minimal ├── CMakeLists.txt ├── debug.h ├── main.c └── shaders │ ├── build_shaders.sh │ ├── spv │ ├── main.frag.spv │ └── main.vert.spv │ └── src │ ├── main.frag │ ├── main.vert │ └── main_image.glsl ├── os_utils ├── os_win_utils.h ├── utils.h ├── wayland_utils.h └── xcb_x11_utils.h ├── use_validation_layer ├── VK_validation.cmd ├── VK_validation.sh └── vk_layer_settings.txt ├── vk_utils ├── vk_error_print.c ├── vk_error_print.h ├── vk_render_helper.c ├── vk_render_helper.h ├── vk_struct.h ├── vk_utils.c └── vk_utils.h ├── wayland_xdg ├── xdg-shell-client-protocol.c └── xdg-shell-client-protocol.h └── yariv ├── CMakeLists.txt ├── main.c └── yariv.h /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Danil 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 | # vulkan shader launcher 2 | 3 | **what is it** creating simple minimal and **Valid** "shader launcher" using Vulkan and C, for launch any shaders(from shadertoy or any else). Without validation errors and crossplatform. 4 | 5 | Used Vulkan 1.0 and only single extension [VK_KHR_swapchain](https://vulkan.gpuinfo.org/listextensions.php) `VK_KHR_SWAPCHAIN_EXTENSION_NAME` that on 100% devices with Vulkan. 6 | 7 | **Download** example build [**from Releases**](https://github.com/danilw/vulkan-shader-launcher/releases/tag/rel_1_1). 8 | 9 | ~~Minimal binary build size, after upx compression, \~30kb (without built-in shaders in *example_minimal*). Using [yari-v](https://github.com/sheredom/yari-v) to compress shaders, in *example_fbo* size of bin(exe) with shaders \~50Kb.~~ 10 | 11 | ***Do not use UPX*** - reason https://github.com/upx/upx/issues/337 12 | 13 | **Dependencies** - only vulkan library(sdk), and win32/X11/Wayland for window and keyboard/mouse control. 14 | 15 | **Source of code** - I made this code following cube-demo from VulkanSDK and [vktut](https://github.com/ShabbyX/vktut), this my code released under *The MIT License*. 16 | 17 | **Compiler/platform support** - VisualStudio, GCC/Clang, Mingw. OS Windows and Linux(X11/Wayland) 18 | 19 | **Wayland** - minimal setup with stable *xdg-shell*. Added hotkey *f* as example of resize event. 20 | 21 | ### Contact: [**Join discord server**](https://discord.gg/JKyqWgt) 22 | ___ 23 | **Example minimal** - single shader loader, shader from file. Control: Keyboard 1-debug, 2-vsynk 60fps, Space-pause. Binary build(exe) 30kb size. 24 | 25 | **Example game** - single shader game example, drawing many elements in vulkan-drawcall loop, using Blend to draw mix color. Also using *yari-v* to compress shaders, and shaders build in to binary file. This example on video [youtube link](https://youtu.be/5Wzj-GNAo6c). 26 | 27 | **Example FBO** - [base on this shader](https://www.shadertoy.com/view/3syXDD) game that on *screenshot*, game logic on GPU, using framebuffer to store/read data, also *yari-v* and build in shaders. 28 | 29 | **Example images** - imgages/textures loading. [Used shader](https://www.shadertoy.com/view/lsfGWn) to test mipmaps, mipmaps supported. Default image format is *SRGB*, to change edit line 125 [example_images/main.c](https://github.com/danilw/vulkan-shader-launcher/blob/master/example_images/main.c#L125). 30 | 31 | **use Validation layer** - use [VK_validation.sh](https://github.com/danilw/vulkan-shader-launcher/blob/master/use_validation_layer/VK_validation.sh) script for that. Requires VulkanSDK installed. This *shader launcher code* does not have validation errors. 32 | 33 | **[Shadertoy launcher](https://github.com/danilw/vulkan-shadertoy-launcher)** - proper launcher for shadertoy shaders, 4 framebuffers, texture support. Moved to its own repository [vulkan-shadertoy-launcher](https://github.com/danilw/vulkan-shadertoy-launcher). 34 | 35 | ___ 36 | # Building 37 | 38 | **Use cmake to build.** 39 | 40 | Using VS2019 in Windows (open links to see tutorial screenshot): 41 | 42 | 0. Download and install [Vulkan SDK](https://vulkan.lunarg.com/sdk/home#windows). 43 | 1. Launch VS press [Continue without code](https://danilw.github.io/GLSL-howto/vulkan_sh_launcher/vs_cmake_tut/1.png) and [File-Open-CMake](https://danilw.github.io/GLSL-howto/vulkan_sh_launcher/vs_cmake_tut/2.png) select [CMakeLists.txt file](https://danilw.github.io/GLSL-howto/vulkan_sh_launcher/vs_cmake_tut/3.png) from one of the *example_* folders. 44 | 2. Press [Manage Configureations](https://danilw.github.io/GLSL-howto/vulkan_sh_launcher/vs_cmake_tut/4.png) and [Add new configuration](https://danilw.github.io/GLSL-howto/vulkan_sh_launcher/vs_cmake_tut/5.png) select [x64 Release](https://danilw.github.io/GLSL-howto/vulkan_sh_launcher/vs_cmake_tut/6.png). 45 | 3. In General [Configuration type set MinSizeRel](https://danilw.github.io/GLSL-howto/vulkan_sh_launcher/vs_cmake_tut/7.png) and press Ctrl+S to save. 46 | 4. Then [select created configuration](https://danilw.github.io/GLSL-howto/vulkan_sh_launcher/vs_cmake_tut/8.png) and press [Build-Build All](https://danilw.github.io/GLSL-howto/vulkan_sh_launcher/vs_cmake_tut/9.png). 47 | 5. Compiled build location *example_\out\build\x64-Release\.exe*. 48 | 49 | 50 | In Linux use command: 51 | ``` 52 | cd example_minimal 53 | mkdir build 54 | cd build 55 | cmake .. 56 | make 57 | ``` 58 | To build with Wayland in *CMakeLists.txt* set `OPTION(USE_WAYLAND_LINUX "use Wayland for Linux" ON)` by default used X11. 59 | 60 | 61 | *Building without cmake:* 62 | 63 | Build with **gcc** (linux): (to build with *clang* change *gcc* to *clang*) 64 | 65 | X11: 66 | ``` 67 | gcc -DVK_USE_PLATFORM_XCB_KHR -O2 -s ../vk_utils/vk_utils.c ../vk_utils/vk_error_print.c ../vk_utils/vk_render_helper.c main.c -o VKexample -lm -lxcb -lvulkan 68 | ``` 69 | Wayland: 70 | ``` 71 | cp ../wayland_xdg/xdg-shell-client-protocol.c xdg-shell-client-protocol.c 72 | cp ../wayland_xdg/xdg-shell-client-protocol.h xdg-shell-client-protocol.h 73 | gcc -DVK_USE_PLATFORM_WAYLAND_KHR -O2 -s -I. -I/usr/include/wayland ../vk_utils/vk_utils.c ../vk_utils/vk_error_print.c ../vk_utils/vk_render_helper.c xdg-shell-client-protocol.c main.c -o VKexample -lm -lvulkan -lwayland-client 74 | ``` 75 | 76 | to generare Wayland xdg-shell headers (from wayland_xdg folder): 77 | ``` 78 | wayland_protocols_dir=$(pkg-config --variable=pkgdatadir wayland-protocols) 79 | wayland-scanner client-header $wayland_protocols_dir/stable/xdg-shell/xdg-shell.xml xdg-shell-client-protocol.h 80 | wayland-scanner private-code $wayland_protocols_dir/stable/xdg-shell/xdg-shell.xml xdg-shell-client-protocol.c 81 | ``` 82 | 83 | Build with **mingw64** (*vulkan-1.dll* from VulkanSDK, *vulkan.h* in system(cygwin or native) path): 84 | ``` 85 | x86_64-w64-mingw32-gcc -DVK_USE_PLATFORM_WIN32_KHR -O3 -s ../vk_utils/vk_utils.c ../vk_utils/vk_error_print.c ../vk_utils/vk_render_helper.c main.c -o VKexample.exe -lm -mwindows /vulkan-1.dll 86 | ``` 87 | (**in the *example game and fbo* add** `-DYARIV_SHADER` **to build command** to have yari-v shaders in the bin(exe), to compile yari-v shader use *shaders/build_shaders_yariv.sh*) 88 | 89 | **Images:** 90 | 91 | ![img](https://danilw.github.io/GLSL-howto/vulkan_sh_launcher/v2/scr1.jpg) 92 | 93 | **Video:** 94 | 95 | [![youtube](https://danilw.github.io/GLSL-howto/vulkan_sh_launcher/v1/v1yt.jpg)](https://youtu.be/5Wzj-GNAo6c) 96 | -------------------------------------------------------------------------------- /example_fbo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12) 2 | 3 | project("example_fbo") 4 | 5 | OPTION(USE_WAYLAND_LINUX "use Wayland for Linux" OFF) 6 | OPTION(GEN_WAYLAND_HEADERS "using wayland-scanner" OFF) 7 | 8 | find_package(Vulkan REQUIRED) 9 | if(NOT Vulkan_FOUND) 10 | MESSAGE(FATAL_ERROR "ERROR: Vulkan not found") 11 | endif(NOT Vulkan_FOUND) 12 | set(Vulkan_LIBRARY) 13 | 14 | set(Wayland_client "") 15 | IF (NOT WIN32) 16 | if(USE_WAYLAND_LINUX) 17 | set(WAYLAND_INCLUDE_DIR "/usr/include/wayland") 18 | MESSAGE(STATUS " Wayland include path ${WAYLAND_INCLUDE_DIR}") 19 | include_directories(${WAYLAND_INCLUDE_DIR}) 20 | if(GEN_WAYLAND_HEADERS) 21 | find_program(PKG_CONFIG pkg-config) 22 | if (NOT PKG_CONFIG) 23 | MESSAGE(FATAL_ERROR "pkg-config binary not found") 24 | endif () 25 | find_program(WAYLAND_SCANNER wayland-scanner) 26 | if (NOT WAYLAND_SCANNER) 27 | MESSAGE(FATAL_ERROR "wayland-scanner binary not found") 28 | endif () 29 | if(PKG_CONFIG AND WAYLAND_SCANNER) 30 | set(Wayland_client "${CMAKE_BINARY_DIR}/xdg-shell-client-protocol.c") 31 | execute_process(COMMAND ${PKG_CONFIG} --variable=pkgdatadir wayland-protocols OUTPUT_VARIABLE protocol_dir OUTPUT_STRIP_TRAILING_WHITESPACE) 32 | execute_process(COMMAND ${WAYLAND_SCANNER} client-header ${protocol_dir}/stable/xdg-shell/xdg-shell.xml xdg-shell-client-protocol.h 33 | COMMAND ${WAYLAND_SCANNER} private-code ${protocol_dir}/stable/xdg-shell/xdg-shell.xml xdg-shell-client-protocol.c) 34 | include_directories(${CMAKE_BINARY_DIR}) 35 | endif () 36 | else () 37 | MESSAGE(STATUS "using wayland headers from wayland_xdg folder") 38 | set(Wayland_client "../wayland_xdg/xdg-shell-client-protocol.c") 39 | include_directories("../wayland_xdg") 40 | endif () 41 | endif () 42 | endif () 43 | 44 | if (Vulkan_FOUND) 45 | MESSAGE(STATUS " [Found Vulkan library]") 46 | MESSAGE(STATUS " Vulkan include directory:" ${Vulkan_INCLUDE_DIR}) 47 | FOREACH(item ${Vulkan_LIBRARIES}) 48 | MESSAGE(STATUS " using lib: " ${item}) 49 | ENDFOREACH() 50 | include_directories(${Vulkan_INCLUDE_DIR}) 51 | endif() 52 | 53 | set(SOURCES 54 | "main.c" 55 | "../vk_utils/vk_utils.c" 56 | "../vk_utils/vk_error_print.c" 57 | "../vk_utils/vk_render_helper.c" 58 | ${Wayland_client} 59 | ) 60 | 61 | add_executable( 62 | Vkexample_fbo 63 | ${SOURCES} 64 | ) 65 | 66 | if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") 67 | 68 | add_definitions(-DVK_USE_PLATFORM_WIN32_KHR -DYARIV_SHADER ) 69 | target_link_libraries(Vkexample_fbo ${Vulkan_LIBRARY}) 70 | elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") 71 | if(USE_WAYLAND_LINUX) 72 | add_definitions(-DVK_USE_PLATFORM_WAYLAND_KHR -DYARIV_SHADER -O2 -s -fdata-sections -ffunction-sections -Wl,--gc-sections) 73 | target_link_libraries(Vkexample_fbo m wayland-client ${Vulkan_LIBRARY}) 74 | else() 75 | add_definitions(-DVK_USE_PLATFORM_XCB_KHR -DYARIV_SHADER -O2 -s -fdata-sections -ffunction-sections -Wl,--gc-sections) 76 | target_link_libraries(Vkexample_fbo m xcb ${Vulkan_LIBRARY}) 77 | endif() 78 | else() 79 | message(WARNING "Unknown compiler '${CMAKE_C_COMPILER_ID}'!") 80 | endif() 81 | -------------------------------------------------------------------------------- /example_fbo/shaders/build_shaders.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | glslangValidator -V100 src/main.vert -o spv/main.vert.spv 4 | glslangValidator -V100 src/main.frag -o spv/main.frag.spv 5 | glslangValidator -V100 src/buf.vert -o spv/buf.vert.spv 6 | glslangValidator -V100 src/buf.frag -o spv/buf.frag.spv 7 | -------------------------------------------------------------------------------- /example_fbo/shaders/build_shaders_yariv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #build yariv first and put yariv_pack binary to this folder 4 | 5 | python yariv_to_hex.py src/main.vert 6 | python yariv_to_hex.py src/main.frag 7 | 8 | python yariv_to_hex.py src/buf.vert 9 | python yariv_to_hex.py src/buf.frag 10 | -------------------------------------------------------------------------------- /example_fbo/shaders/spv/buf.frag.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_fbo/shaders/spv/buf.frag.spv -------------------------------------------------------------------------------- /example_fbo/shaders/spv/buf.vert.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_fbo/shaders/spv/buf.vert.spv -------------------------------------------------------------------------------- /example_fbo/shaders/spv/main.frag.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_fbo/shaders/spv/main.frag.spv -------------------------------------------------------------------------------- /example_fbo/shaders/spv/main.vert.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_fbo/shaders/spv/main.vert.spv -------------------------------------------------------------------------------- /example_fbo/shaders/src/bin/buf.frag.hex: -------------------------------------------------------------------------------- 1 | 0x1,0x0,0x8a,0x80,0x20,0xca,0x7,0xfd,0x3,0x1,0xf8,0x3,0x3,0x0,0x47,0x4c,0x53,0x4c,0x2e,0x73, 2 | 0x74,0x64,0x2e,0x34,0x35,0x30,0x0,0x0,0x0,0x0,0xf9,0x3,0x0,0x1,0xf,0x4,0x4,0x4,0xed,0xc2, 3 | 0xa5,0xf3,0x6,0x0,0xbd,0x7,0xc6,0x7,0xc9,0x7,0xfc,0x3,0x0,0x6,0x7,0x6c,0x80,0x1,0x0,0x0, 4 | 0x6c,0x0,0x1,0x10,0x6c,0x0,0x2,0x20,0x6c,0x0,0x3,0x28,0x6c,0x0,0x4,0x30,0x6c,0x0,0x5,0x34, 5 | 0x6c,0x0,0x6,0x38,0x6c,0x0,0x7,0x3c,0x6c,0x0,0x8,0x40,0x8,0x0,0x2,0xa,0x76,0x22,0x0,0xa, 6 | 0x0,0x21,0x0,0xa,0xfc,0xc,0xb,0xf,0x7d,0x12,0x0,0x7d,0x6,0x0,0xfe,0x3,0x2,0x21,0x0,0x3, 7 | 0x2,0x15,0x6,0x20,0x1,0x17,0x7,0x6,0x2,0x20,0x8,0x7,0x7,0x16,0x9,0x20,0x17,0xa,0x9,0x4, 8 | 0x21,0x1,0xb,0xa,0x8,0x14,0xf,0x21,0x0,0x10,0xf,0x21,0x1,0x13,0xf,0x8,0x17,0x17,0x9,0x2, 9 | 0x20,0x18,0x7,0x17,0x21,0x1,0x19,0xa,0x18,0x21,0x1,0x1d,0x7,0x18,0x21,0x1,0x21,0x9,0x18,0x20, 10 | 0x25,0x7,0x6,0x21,0x1,0x26,0x6,0x25,0x21,0x0,0x2a,0x6,0x21,0x0,0x30,0xa,0x20,0x39,0x7,0xa, 11 | 0x21,0x2,0x3a,0x2,0x39,0x18,0x17,0x3f,0x9,0x3,0x20,0x40,0x6,0x3f,0x3b,0x3f,0x8f,0xe,0x6,0x15, 12 | 0x42,0x20,0x0,0x17,0x43,0x42,0x2,0x1e,0x9,0x44,0xa,0xa,0x43,0x17,0x42,0x6,0x9,0x9,0x6,0x20, 13 | 0x45,0x9,0x44,0x3b,0x44,0xa,0x9,0x2b,0x5,0x2,0x3,0x20,0x48,0x9,0x17,0x27,0x8,0x8,0x0,0x0, 14 | 0x80,0x3f,0x20,0x4f,0x6,0x9,0x3b,0x4e,0xa,0x6,0x2b,0x5,0x2,0x6,0x20,0x52,0x9,0x9,0x3b,0x4e, 15 | 0x8,0x6,0x2b,0x5,0x2,0x7,0x20,0x59,0x6,0x6,0x3b,0x58,0x8,0x6,0x2b,0x5,0x2,0x8,0x20,0x5c, 16 | 0x9,0x6,0x20,0x5f,0x6,0xa,0x3b,0x5e,0xa,0x6,0x2b,0x5,0x2,0x0,0x20,0x62,0x9,0xa,0x3b,0x5e, 17 | 0x8,0x6,0x2b,0x5,0x2,0x1,0x20,0x69,0x6,0xf,0x3b,0x68,0x8,0x6,0x2b,0x5,0x2,0x4,0x20,0x6c, 18 | 0x9,0x42,0x2b,0x41,0x8,0x0,0x3b,0x68,0x4,0x6,0x2b,0x5,0x2,0x5,0x2b,0x5,0xa,0xa,0x19,0x8, 19 | 0x7c,0x9,0x1,0x0,0x0,0x0,0x1,0x0,0x1b,0x7d,0x7c,0x20,0x7e,0x0,0x7d,0x3b,0x7d,0x10,0x0,0x2b, 20 | 0x5,0xe,0x2,0x2c,0x2,0x6,0x2,0x0,0x3f,0x2b,0x8,0x8,0x0,0x20,0x93,0x1,0x7,0x9,0x2b,0x41, 21 | 0x1c,0x1,0x27,0x8,0x16,0x0,0x0,0x40,0x40,0x27,0x8,0x6,0x71,0x3d,0xc6,0x40,0x27,0x8,0x2,0x0, 22 | 0x0,0xc0,0x40,0x2c,0x2,0x16,0x2,0x1,0x0,0x27,0x8,0xa,0x0,0x0,0x0,0x3f,0x27,0x8,0x10,0x8f, 23 | 0xc2,0xf5,0xbc,0x27,0x8,0xa,0x9a,0x99,0x19,0xbe,0x27,0x8,0x12,0x0,0x0,0x80,0x40,0x2c,0x2,0x16, 24 | 0x2,0x0,0x37,0x27,0x8,0x4,0x0,0x0,0x0,0x40,0x2c,0x2,0x16,0x4,0x0,0x45,0x27,0x8,0x46,0x0, 25 | 0x0,0x40,0xbf,0x27,0x8,0xa,0xcd,0xcc,0xcc,0x3d,0x27,0x8,0x18,0x39,0x8e,0xe3,0x3f,0x27,0x8,0x12, 26 | 0x66,0x66,0x46,0x40,0x2c,0x2,0x6,0x18,0xbf,0x2,0xbf,0x2,0x2c,0x2,0x6,0x4,0xe1,0x2,0xe1,0x2, 27 | 0x2c,0x2,0x6,0x2,0xb9,0x2,0x99,0x3,0x27,0x8,0xa,0x39,0xd6,0x4f,0x41,0x27,0x8,0x2,0x4c,0x77, 28 | 0x9c,0x42,0x2c,0x2,0x16,0x2,0x1,0x0,0x27,0x8,0x6,0x8c,0xee,0x2a,0x47,0x27,0x8,0xa,0x0,0x0, 29 | 0xa0,0x41,0x2b,0x5,0x16,0x3c,0x27,0x8,0xc,0x0,0x0,0x80,0xbf,0x2c,0x4,0x9,0x2,0x0,0x0,0x0, 30 | 0x0,0x2c,0x4,0x9,0x6,0xd5,0x2,0xd5,0x2,0xd5,0x2,0xd5,0x2,0x2b,0x41,0x1c,0x2,0x2c,0x2,0x16, 31 | 0x26,0xc5,0x2,0xc5,0x2,0x17,0xe2,0x2,0xf,0x2,0x2c,0x2,0x6,0x22,0xcf,0x3,0xf1,0x3,0x2b,0x41, 32 | 0x30,0x3,0x27,0x5,0x22,0xff,0xff,0xff,0xff,0x2c,0x2,0x6,0x2,0x0,0x0,0x2c,0x2,0x6,0x2,0x87, 33 | 0x5,0xe7,0x4,0x20,0x9b,0x3,0x7,0xf,0xb8,0x1,0xe,0xe,0x2b,0x5,0x10,0x14,0x29,0xe,0x3a,0x2c, 34 | 0x2,0x6,0x62,0xf5,0x5,0xb7,0x5,0x27,0x8,0xd0,0x2,0x0,0x0,0x20,0x41,0x2c,0x2,0x6,0x44,0xf3, 35 | 0x8,0xe9,0x8,0x27,0x8,0x8c,0x3,0x0,0x0,0x20,0xc1,0x2c,0x4,0x9,0x2,0x0,0x0,0x0,0x0,0x2c, 36 | 0x2,0x6,0x58,0xb1,0xc,0xbb,0xc,0x20,0xbc,0x7,0x1,0xa,0x3b,0xbb,0x7,0x1a,0x1,0x20,0xc5,0x7, 37 | 0x3,0xa,0x3b,0xc4,0x7,0x12,0x3,0x20,0xc8,0x7,0x1,0x17,0x3b,0xc7,0x7,0x6,0x1,0x36,0x1,0x89, 38 | 0xf,0x0,0x3,0x0,0x2,0x3b,0x38,0xea,0xe,0x7,0x3b,0x17,0x2,0x7,0x3b,0x38,0xa,0x7,0x3b,0x17, 39 | 0x2,0x7,0x10,0x47,0xef,0xd,0x46,0x47,0x3d,0x16,0x2,0x0,0x45,0x8,0x4,0x0,0x79,0x8,0x2,0x3, 40 | 0x26,0x3e,0x2,0x1,0x0,0x3,0x3e,0x19,0x0,0x10,0x51,0x24,0x46,0x51,0x3d,0x8,0x2,0x0,0x3e,0x7, 41 | 0x0,0x10,0x51,0xe,0x46,0x56,0x3d,0x8,0x2,0x0,0x3e,0x5,0x0,0x10,0x5b,0x10,0x46,0x5b,0x3d,0x5, 42 | 0x2,0x0,0x3e,0x7,0x0,0x10,0x61,0x12,0x46,0x61,0x3d,0x9,0x2,0x0,0x3e,0x7,0x0,0x10,0x61,0xe, 43 | 0x46,0x66,0x3d,0x9,0x2,0x0,0x3e,0x5,0x0,0x10,0x6b,0x10,0x46,0x6b,0x3d,0x41,0x2,0x0,0xab,0x1, 44 | 0xe,0x4,0x6e,0x6f,0x3e,0xb,0x0,0x10,0x5b,0x12,0x46,0x72,0x3d,0x5,0x2,0x0,0x10,0x5b,0x2,0x46, 45 | 0x72,0x3d,0x5,0x2,0x0,0x87,0x1,0x5,0x4,0x0,0x2,0x84,0x1,0x5,0x2,0x0,0x1,0x82,0x1,0x5, 46 | 0x2,0x9,0x0,0xab,0x1,0xe,0x2,0x7a,0x6f,0x3e,0x13,0x0,0x3e,0x92,0xd,0x90,0x3,0x3d,0x9,0x8, 47 | 0x6,0x3a,0x16,0x2,0x0,0x1,0x3e,0x7,0x0,0x3d,0x16,0xe,0x0,0x3e,0x1,0x0,0x39,0x2,0x1,0x4, 48 | 0x87,0xe,0x1,0x0,0x3d,0x9,0x2,0x5,0x3e,0x13,0x0,0x3d,0x9,0x1a,0x0,0x3e,0x1,0x0,0x7e,0x38, 49 | 0x36,0x9,0xf1,0xe,0x0,0xb,0x37,0x7,0x1,0x0,0x4,0x3d,0x7c,0xe4,0x1,0xe2,0x1,0x3d,0x6,0x2, 50 | 0xe7,0x1,0x64,0x7b,0x2,0x80,0x1,0x5f,0x2,0x9,0x2,0x82,0x1,0x81,0x1,0x2,0x61,0x1d,0x0,0x38, 51 | 0x36,0xe,0xe3,0x1,0x0,0x10,0x0,0x2,0x3b,0x7,0xec,0x1,0x7,0x3e,0x0,0x1,0x39,0x1,0x9,0x2, 52 | 0xf5,0x1,0x0,0x45,0x8,0x2,0x0,0xba,0x1,0xe,0x4,0x0,0x2,0x1d,0x0,0x38,0x36,0xe,0xed,0x1, 53 | 0x0,0x13,0x37,0x7,0x1,0x0,0x4,0x3b,0x7,0xf2,0x1,0x7,0x3b,0x92,0x1,0xa,0x7,0x10,0x24,0x7, 54 | 0x14,0x6f,0x3d,0x5,0x2,0x0,0x25,0x6,0x2,0x0,0x5f,0x3e,0x5,0x0,0x3d,0x7c,0xc,0x1f,0x3d,0x6, 55 | 0x2,0xb,0x64,0x7b,0x2,0x95,0x1,0x5f,0x2,0x9,0x2,0x97,0x1,0x96,0x1,0x2,0x61,0x10,0x24,0x4, 56 | 0x14,0x99,0x1,0x3d,0x5,0x2,0x0,0xbc,0x1,0x8,0x2,0x98,0x1,0x9b,0x1,0x3e,0xf,0x0,0x3d,0x8, 57 | 0x12,0x0,0xba,0x1,0xe,0x2,0x0,0x23,0x1d,0x0,0x38,0x36,0x9,0x85,0x2,0x0,0x19,0x37,0x17,0x1, 58 | 0x0,0x4,0x3b,0x17,0x8a,0x2,0x7,0x3b,0x17,0x26,0x7,0x3d,0x16,0x23,0xb3,0x2,0x3e,0x1,0x0,0x3d, 59 | 0x16,0x4,0x8d,0x2,0x25,0x16,0x4,0x2,0x2,0x35,0x16,0x2,0x3,0x0,0x2,0x16,0x8,0x0,0x6,0x3e, 60 | 0x11,0x0,0x10,0x92,0x1,0x14,0xa1,0x1,0x6f,0x3d,0x8,0x2,0x0,0xc,0x1,0xc5,0x2,0xad,0x1,0x1, 61 | 0x4,0xac,0x1,0x3,0x8,0xcc,0x2,0xc8,0x2,0xca,0x2,0xc,0x1,0xcb,0x2,0xb0,0x1,0x1,0x8,0xaf, 62 | 0x1,0x2,0x8,0xd0,0x2,0x84,0x1,0xce,0x2,0xc,0x1,0xcf,0x2,0xb2,0x1,0x1,0x1f,0xb1,0x1,0x10, 63 | 0x92,0x1,0xd4,0x2,0xa1,0x1,0x6f,0x3e,0x0,0x1,0x3d,0x16,0x4,0xb1,0x2,0x3e,0x1,0x0,0x10,0x92, 64 | 0x1,0x6,0xb4,0x1,0x99,0x1,0x3d,0x8,0x2,0x0,0x3,0x8,0x2,0x0,0x3,0x10,0x92,0x1,0x2,0xb4, 65 | 0x1,0x99,0x1,0x3e,0x0,0x1,0x10,0x92,0x1,0x4,0xa1,0x1,0x6f,0x3d,0x8,0x2,0x0,0x2,0x8,0x2, 66 | 0x3,0x0,0x10,0x92,0x1,0x2,0xb4,0x1,0x99,0x1,0x3d,0x8,0x2,0x0,0x3,0x8,0x2,0x0,0x3,0x10, 67 | 0x92,0x1,0x2,0xb4,0x1,0x99,0x1,0x3e,0x0,0x1,0x3d,0x16,0x2,0x1b,0x2,0x16,0x6,0x0,0x4,0x2f, 68 | 0x16,0x4,0x0,0x2,0x3,0x16,0x4,0x0,0x2,0x8d,0x1,0x16,0x2,0x0,0x9,0x1,0x16,0x2,0x0,0x3, 69 | 0x3e,0x2f,0x0,0x3d,0x16,0x32,0x0,0x3d,0x16,0x2,0x57,0x45,0x8,0x2,0x1,0x79,0x8,0x2,0x3,0x45, 70 | 0x8,0x2,0x3,0x79,0x8,0x2,0x5,0x50,0x4,0x9,0x2,0x5,0x3,0x1,0x0,0x1d,0x0,0x38,0x36,0x6, 71 | 0xe7,0x2,0x0,0x1d,0x37,0x17,0x1,0x0,0x4,0x3b,0x38,0xec,0x2,0x7,0x3b,0x17,0x2,0x7,0x3b,0x17, 72 | 0x6,0x7,0x3b,0x17,0x6,0x7,0x3b,0x17,0x3c,0x7,0x3b,0x7,0x26,0x7,0x3d,0x16,0x6b,0xdf,0x3,0x3e, 73 | 0x1,0x0,0x39,0x1,0x9,0x4,0xf7,0x2,0x0,0x3e,0x5,0x0,0x3d,0x9,0xa,0x0,0x3a,0x16,0x2,0x0, 74 | 0xb,0x3e,0x3,0x0,0x3d,0x16,0x8,0xf7,0x2,0x3d,0x3e,0x2,0xb9,0x2,0x3a,0x16,0x2,0x0,0x1,0x10, 75 | 0x4e,0x2,0x41,0x99,0x1,0x3d,0x8,0x2,0x0,0x25,0x16,0x2,0x0,0x0,0x35,0x16,0x2,0x5,0x0,0x25, 76 | 0x16,0x2,0x39,0x39,0x35,0x16,0x2,0x1,0x0,0x2f,0x16,0x2,0x0,0x83,0x1,0x3,0x16,0x2,0x11,0x0, 77 | 0x25,0x16,0x2,0x87,0x1,0x87,0x1,0x35,0x16,0x2,0x1,0x0,0x2,0x16,0x2,0x0,0x81,0x1,0x3e,0x1b, 78 | 0x0,0x10,0x92,0x1,0x20,0xdd,0x1,0x99,0x1,0x3d,0x8,0x2,0x0,0x3,0x8,0x2,0x0,0x3,0x10,0x92, 79 | 0x1,0x2,0xdd,0x1,0x99,0x1,0x3e,0x0,0x1,0x10,0x92,0x1,0x4,0xda,0x1,0x6f,0x3d,0x8,0x2,0x0, 80 | 0x2,0x8,0x2,0x3,0x0,0x2,0x8,0x2,0x0,0x59,0x1,0x8,0x2,0xd3,0x2,0x0,0x10,0x92,0x1,0x2, 81 | 0xdd,0x1,0x99,0x1,0x3d,0x8,0x2,0x0,0x3,0x8,0x2,0x0,0x3,0x10,0x92,0x1,0x2,0xdd,0x1,0x99, 82 | 0x1,0x3e,0x0,0x1,0x3d,0x16,0x4,0x39,0x3d,0x3e,0x4,0xf5,0x2,0x3a,0x16,0x2,0x0,0x1,0x10,0x4e, 83 | 0x2,0x41,0x99,0x1,0x3d,0x8,0x2,0x0,0x25,0x16,0x2,0x0,0x0,0x35,0x16,0x2,0x5,0x0,0x45,0x8, 84 | 0x2,0x0,0x1,0x8,0x2,0xd,0x0,0x2,0x8,0x4,0x0,0x2,0x3,0x8,0x2,0x0,0xf7,0x2,0x25,0x16, 85 | 0x2,0x0,0xf9,0x1,0x3,0x16,0x2,0x19,0x0,0x45,0x8,0x2,0x0,0x79,0x8,0x2,0x1,0x25,0x16,0x2, 86 | 0x1,0x0,0x3e,0x23,0x0,0x3d,0x16,0x28,0x0,0x6e,0x6,0x2,0x0,0x3e,0x3,0x0,0x3d,0x6,0x6,0x0, 87 | 0x82,0x1,0x6,0x4,0x0,0x2,0xc,0x3,0x97,0x4,0x96,0x2,0x1,0x2d,0x93,0x2,0x94,0x2,0x95,0x2, 88 | 0x1d,0x9e,0x4,0x38,0x36,0x8,0xe5,0x3,0x0,0x21,0x37,0x17,0x1,0x0,0x4,0x3d,0x16,0xea,0x3,0x3, 89 | 0x28,0x8,0x8,0x0,0x6,0xc,0x1,0xa7,0x4,0x9e,0x2,0x1,0xd,0x9d,0x2,0x2,0x8,0xae,0x4,0xaa, 90 | 0x4,0xac,0x4,0xc,0x1,0xad,0x4,0xa1,0x2,0x1,0xa,0xa0,0x2,0x1d,0xb0,0x4,0x38,0x36,0x5,0xf1, 91 | 0x3,0x0,0x26,0x37,0x24,0x1,0x0,0x4,0x3b,0x17,0x80,0x4,0x7,0x3d,0x5,0x7,0x83,0x4,0x6f,0x8, 92 | 0x2,0x0,0x3d,0x8,0x2,0xab,0x3,0x25,0x16,0x2,0x1,0x0,0x3e,0x2,0x0,0x39,0x1,0x8,0x2,0x8b, 93 | 0x4,0x0,0x2,0x8,0x2,0xb,0x0,0x6e,0x5,0x2,0x0,0x1d,0x0,0x38,0x36,0x5,0x81,0x4,0x0,0x2a, 94 | 0x0,0x2,0x1d,0x86,0x4,0x38,0x36,0x9,0x81,0x4,0x0,0xb,0x37,0x7,0x1,0x0,0x4,0x3b,0x38,0x92, 95 | 0x4,0x7,0x3b,0x38,0x4,0x7,0x3b,0x7,0x2,0x7,0x3b,0x7,0x8,0x7,0x3b,0x7,0xc,0x7,0x3b,0x7, 96 | 0x10,0x7,0x3b,0x7,0x2,0x7,0x3b,0x17,0x1c,0x7,0x3b,0x7,0x1c,0x7,0x3b,0x24,0x2a,0x7,0x3b,0x7, 97 | 0x4,0x7,0x3b,0x7,0x24,0x7,0x3b,0x24,0x8,0x7,0x3b,0x24,0x2,0x7,0x3b,0x9a,0x3,0x8,0x7,0x3b, 98 | 0x24,0x4,0x7,0x3b,0x7,0x1e,0x7,0x3b,0x7,0x1e,0x7,0x3b,0x7,0x36,0x7,0x39,0x0,0xe,0xc9,0x2, 99 | 0x8b,0x7,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x1d,0x6,0x0,0x3,0x3e,0x8,0xa,0x3d, 100 | 0x6,0x8,0x95,0x4,0x3e,0x1,0x0,0x39,0x1,0x9,0x4,0xdb,0x4,0x0,0x3e,0x5,0x0,0x3d,0x9,0x8, 101 | 0x0,0x3e,0xb,0x0,0x3e,0xe,0x4b,0x39,0x1,0x9,0x2,0xe3,0x4,0x0,0x45,0x8,0x2,0x0,0xbe,0x1, 102 | 0xe,0x2,0x0,0xeb,0x2,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3e,0x4,0x61,0x39,0x1, 103 | 0x9,0x2,0xef,0x4,0x0,0x7a,0x8,0x4,0x0,0xba,0x1,0xe,0x2,0x0,0xf9,0x2,0x4,0x9,0x0,0x0, 104 | 0xf5,0x1,0x4,0xe,0xc,0x3,0x1f,0xa,0x1,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3e, 105 | 0x6,0x71,0x39,0x1,0x9,0x2,0x81,0x5,0x0,0x3a,0x16,0x2,0x0,0x1,0x25,0x16,0x2,0xc3,0x2,0xc3, 106 | 0x2,0x1,0x16,0x2,0x1,0x0,0x3d,0x3e,0x2,0xa1,0x4,0x3a,0x16,0x2,0x0,0x1,0x10,0x4e,0x2,0x41, 107 | 0x99,0x1,0x3d,0x8,0x2,0x0,0x25,0x16,0x2,0x0,0x0,0x35,0x16,0x2,0x5,0x0,0x2,0x16,0x2,0xb, 108 | 0x0,0x2,0x16,0x4,0x0,0x2,0x3e,0x2,0x0,0x39,0x1,0x6,0x2,0xf9,0x4,0x0,0x3e,0x1f,0x0,0x3d, 109 | 0x6,0x22,0xbf,0x4,0x10,0x24,0x2,0xcd,0x2,0x6f,0x3d,0x5,0x2,0x0,0x25,0x6,0x2,0x0,0xfd,0x3, 110 | 0x54,0xe1,0x2,0x4,0x5,0x0,0x9b,0x1,0xe,0x2,0xe3,0x2,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0, 111 | 0x0,0x2,0x10,0x24,0x4,0xcd,0x2,0x99,0x1,0x3d,0x5,0x2,0x0,0x10,0x92,0x1,0x2,0xb8,0x2,0xe8, 112 | 0x2,0x3e,0x0,0xbb,0x4,0x4,0x5,0x0,0x0,0x10,0x24,0xc,0xcd,0x2,0x6f,0x3d,0x5,0x2,0x0,0xfd, 113 | 0x1,0x5,0x2,0xed,0x2,0x10,0x24,0x2,0xcd,0x2,0x99,0x1,0x3d,0x5,0x2,0x0,0x25,0x6,0x2,0x3, 114 | 0x0,0x53,0x6,0x2,0xb,0x0,0x53,0x6,0x2,0x0,0xd,0x3e,0x11,0x0,0x3d,0x6,0x14,0xf9,0x4,0x10, 115 | 0x24,0x2,0xea,0x2,0x6f,0x3d,0x5,0x2,0x0,0x25,0x6,0x2,0x0,0xa9,0x4,0x54,0xe1,0x2,0x2,0x5, 116 | 0x0,0x9b,0x1,0xe,0x2,0xf8,0x2,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x10,0x24,0x4, 117 | 0xea,0x2,0x99,0x1,0x3d,0x5,0x2,0x0,0x10,0x92,0x1,0x2,0xb8,0x2,0xfd,0x2,0x3e,0x0,0x91,0x1, 118 | 0x4,0x5,0x0,0x0,0x4,0x5d,0x0,0x0,0x3d,0x5,0x68,0xe3,0x3,0x3e,0x2,0xf1,0x3,0x39,0x1,0x9, 119 | 0x2,0xe7,0x5,0x0,0x7b,0x8,0x4,0x0,0x6e,0x5,0x2,0x0,0x82,0x1,0x5,0x2,0x9,0x0,0x3e,0xd, 120 | 0x0,0x3d,0x5,0x10,0x0,0x39,0x0,0x5,0x2,0xb7,0x5,0x87,0x1,0x5,0x2,0x1,0x0,0xb3,0x1,0xe, 121 | 0x2,0x0,0xa3,0x4,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3d,0x5,0x4,0x17,0x39,0x0, 122 | 0x5,0x2,0xc3,0x5,0x8b,0x1,0x5,0x2,0x8d,0x3,0x8e,0x3,0x54,0xe,0x2,0x0,0xdb,0x4,0x23,0x4, 123 | 0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3e,0x4,0x8,0x3e,0x0,0x6,0x3d,0x5,0xc,0xf1,0x4,0x3e, 124 | 0x1,0x0,0x39,0x1,0x5,0x4,0xdf,0x5,0x0,0x3e,0x5,0x0,0x3e,0xa,0xc,0x3e,0x4,0xf5,0x4,0x4, 125 | 0x2,0x0,0x0,0xf6,0x1,0x4,0xa2,0x3,0x0,0x4,0x4,0x0,0x0,0x3d,0x5,0x2,0x9,0xb1,0x1,0xe, 126 | 0x4,0x0,0x2,0x22,0x0,0x0,0xb,0x9,0x0,0xb,0x3d,0xe,0xe,0x7,0xa8,0x1,0xe,0x2,0x0,0x23, 127 | 0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3d,0x5,0x4,0x23,0x8b,0x1,0x5,0x2,0xab,0x3,0xa5, 128 | 0x3,0x3e,0x29,0x0,0x10,0x24,0x2e,0x93,0x3,0x6f,0x3d,0x5,0x2,0x0,0x3d,0x5,0x2,0x2f,0x53,0x5, 129 | 0x2,0x1,0x0,0x3d,0x5,0x2,0x33,0x87,0x1,0x5,0x2,0x0,0xff,0x4,0x84,0x1,0x5,0x2,0x81,0x5, 130 | 0x0,0x82,0x1,0x5,0x2,0x5,0x0,0x10,0x24,0x2,0x93,0x3,0x99,0x1,0x3d,0x5,0x2,0x0,0x3d,0x5, 131 | 0x2,0x3f,0x87,0x1,0x5,0x2,0x0,0x8b,0x5,0x53,0x5,0x2,0x3,0x0,0x25,0x6,0x2,0x9,0x0,0x3e, 132 | 0x1b,0x0,0x3d,0x6,0x20,0x0,0x3e,0x1,0x0,0x39,0x1,0xe,0x4,0xcd,0x6,0x0,0xa8,0x1,0xe,0x2, 133 | 0x0,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3e,0x47,0x4,0x3d,0x6,0x4e,0x22,0x3e,0x5f, 134 | 0x0,0x4,0x1c,0x0,0x40,0x3d,0x5,0x8,0x53,0x53,0x5,0x2,0x0,0xbd,0x5,0x3e,0x5d,0x0,0x4,0x26, 135 | 0x0,0x0,0x4,0xf,0x0,0x0,0x3d,0x5,0x4a,0x7,0x53,0x5,0x2,0x0,0xc1,0x5,0x3e,0x53,0x0,0x4, 136 | 0x2,0x0,0x4,0x3d,0x6,0x50,0xe7,0x5,0x10,0x24,0x2,0x93,0x3,0x6f,0x3d,0x5,0x2,0x0,0x25,0x6, 137 | 0x2,0x0,0xd3,0x5,0x54,0xe1,0x2,0x2,0x5,0x0,0x9b,0x1,0xe,0x2,0xcd,0x3,0x23,0x4,0x0,0x22, 138 | 0x0,0x3,0x1,0x0,0x0,0x2,0x10,0x24,0x4,0x93,0x3,0x99,0x1,0x3d,0x5,0x2,0x0,0x10,0x92,0x1, 139 | 0x2,0xb8,0x2,0xd2,0x3,0x3e,0x0,0x8f,0x6,0x4,0x5,0x0,0x0,0x3d,0xe,0x8,0x67,0x23,0x4,0x0, 140 | 0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x10,0x24,0x6,0x93,0x3,0x6f,0x3d,0x5,0x2,0x0,0xfd,0x1,0x5, 141 | 0x2,0xd9,0x3,0x10,0x24,0x2,0x93,0x3,0x99,0x1,0x3d,0x5,0x2,0x0,0x25,0x6,0x2,0x3,0x0,0x53, 142 | 0x6,0x2,0xe3,0x1,0x0,0x53,0x6,0x2,0x0,0xe5,0x1,0x3e,0xf,0x0,0x3d,0x6,0x12,0xd3,0x6,0x10, 143 | 0x24,0x2,0xd7,0x3,0x6f,0x3d,0x5,0x2,0x0,0x25,0x6,0x2,0x0,0x81,0x6,0x54,0xe1,0x2,0x2,0x5, 144 | 0x0,0x9b,0x1,0xe,0x2,0xe4,0x3,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x10,0x24,0x4, 145 | 0xd7,0x3,0x99,0x1,0x3d,0x5,0x2,0x0,0x10,0x92,0x1,0x2,0xb8,0x2,0xe9,0x3,0x3e,0x0,0xe9,0x2, 146 | 0x4,0x5,0x0,0x0,0x4,0x21,0x0,0x0,0x4,0x87,0x1,0x0,0x0,0x4,0xb,0x0,0x0,0x3d,0x9,0xbe, 147 | 0x1,0xa7,0x1,0x1d,0x0,0x38,0x36,0x9,0xf3,0x6,0x0,0x30,0x0,0x2,0x3b,0x38,0x80,0x7,0x7,0x3b, 148 | 0x7,0x4,0x7,0x3b,0x92,0x1,0x4,0x7,0x3b,0x92,0x1,0x6,0x7,0x3b,0x92,0x1,0x6,0x7,0x3b,0x92, 149 | 0x1,0x6,0x7,0x3b,0x7,0xe,0x7,0x3b,0x7,0xc,0x7,0x3b,0x7,0xe,0x7,0x3b,0x7,0x2,0x7,0x3b, 150 | 0x17,0x1a,0x7,0x3b,0x7,0x4,0x7,0x3b,0x7,0xc,0x7,0x3b,0x38,0x26,0x7,0x3b,0x7,0x2,0x7,0x39, 151 | 0x0,0xe,0x9d,0x1,0xd7,0x8,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x1d,0xf1,0x2,0x0, 152 | 0xf4,0x2,0x3e,0x8,0x6,0x39,0x1,0x9,0x2,0xcd,0x7,0x0,0x3e,0x5,0x0,0x10,0x92,0x1,0xa,0xf2, 153 | 0x3,0x6f,0x3d,0x8,0x2,0x0,0x3e,0x3,0x0,0x10,0x92,0x1,0x8,0xf2,0x3,0x99,0x1,0x3d,0x8,0x2, 154 | 0x0,0x3e,0x3,0x0,0x10,0x92,0x1,0x8,0xf2,0x3,0xc7,0x2,0x3d,0x8,0x2,0x0,0x3e,0x3,0x0,0x10, 155 | 0x92,0x1,0x8,0xf2,0x3,0x83,0x3,0x3d,0x8,0x2,0x0,0x3e,0x3,0x0,0x3d,0x8,0x6,0x11,0x2a,0xe, 156 | 0x2,0x0,0xed,0x5,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3e,0x1b,0xf1,0x5,0x4,0x1e, 157 | 0x0,0x0,0x3e,0x2,0xe5,0x3,0x39,0x1,0x9,0x2,0xf1,0x7,0x0,0x45,0x8,0x2,0x0,0xbe,0x1,0xe, 158 | 0x2,0x0,0xf9,0x5,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3e,0x4,0xef,0x3,0x39,0x1, 159 | 0x9,0x2,0xfd,0x7,0x0,0x7a,0x8,0x2,0x0,0xba,0x1,0xe,0x2,0x0,0x85,0x6,0x4,0x7,0x0,0x0, 160 | 0xf5,0x1,0x4,0xe,0xa,0x3,0xb,0x8,0x1,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3e, 161 | 0x6,0xfd,0x3,0x39,0x1,0x9,0x2,0x8d,0x8,0x0,0x3a,0x16,0x2,0x0,0x1,0x25,0x16,0x2,0xcf,0x5, 162 | 0xcf,0x5,0x1,0x16,0x2,0x1,0x0,0x3d,0x3e,0x2,0xad,0x7,0x3a,0x16,0x2,0x0,0x1,0x10,0x4e,0x2, 163 | 0x41,0x99,0x1,0x3d,0x8,0x2,0x0,0x25,0x16,0x2,0x0,0x0,0x35,0x16,0x2,0x5,0x0,0x2,0x16,0x2, 164 | 0xb,0x0,0x2,0x16,0x2,0x0,0x89,0x3,0x3e,0x2,0x0,0x39,0x1,0x6,0x2,0x83,0x8,0x0,0x3e,0x1d, 165 | 0x0,0x3d,0x8,0x22,0x33,0x6e,0x5,0x2,0x0,0x3d,0x8,0x2,0x51,0x6e,0x5,0x2,0x0,0x25,0x6,0x2, 166 | 0x3,0x0,0x3e,0x9,0x0,0x3d,0x6,0xe,0x1f,0x3e,0x1,0x0,0x39,0x1,0xe,0x4,0xa7,0x8,0x0,0xa8, 167 | 0x1,0xe,0x2,0x0,0x3d,0x6,0x2,0x31,0x3d,0x6,0x2,0x13,0xab,0x1,0xe1,0x2,0x2,0xad,0x4,0xae, 168 | 0x4,0x9a,0x1,0xe,0x2,0xaf,0x4,0xa6,0x1,0xe,0x2,0x7,0x0,0x23,0x4,0x0,0x22,0x0,0x3,0x1, 169 | 0x0,0x0,0x2,0x3d,0x8,0x4,0x77,0x3,0x8,0x2,0x0,0xd1,0x7,0x3e,0x7d,0x0,0x10,0x24,0x80,0x1, 170 | 0x93,0x4,0x6f,0x3d,0x5,0x2,0x0,0x6f,0x8,0x2,0x0,0x3e,0x7d,0x0,0x10,0x24,0x80,0x1,0x93,0x4, 171 | 0x99,0x1,0x3d,0x5,0x2,0x0,0x6f,0x8,0x2,0x0,0x3e,0x7d,0x0,0x4,0x6e,0x0,0x0,0x4,0x41,0x0, 172 | 0x0,0x3e,0x56,0x95,0x6,0x39,0x1,0x9,0x2,0xdf,0x8,0x0,0x3e,0x3,0x0,0x3d,0x8,0x6,0x8b,0x1, 173 | 0x3d,0x8,0x2,0x8b,0x1,0x3d,0x8,0x2,0x87,0x1,0x3d,0x8,0x2,0x83,0x1,0x50,0x4,0x9,0x2,0x5, 174 | 0x3,0x1,0x0,0x1d,0x0,0x38,0x36,0x9,0x9f,0x8,0x0,0x30,0x0,0x2,0x3b,0x38,0xa4,0x8,0x7,0x3b, 175 | 0x7,0x2,0x7,0x3b,0x92,0x1,0x4,0x7,0x3b,0x92,0x1,0x6,0x7,0x3b,0x92,0x1,0x6,0x7,0x3b,0x92, 176 | 0x1,0x6,0x7,0x3b,0x7,0xe,0x7,0x3b,0x7,0xc,0x7,0x3b,0x7,0xe,0x7,0x3b,0x7,0x2,0x7,0x3b, 177 | 0x17,0x1a,0x7,0x3b,0x7,0x4,0x7,0x3b,0x7,0x12,0x7,0x3b,0x7,0xc,0x7,0x3b,0x38,0x34,0x7,0x3b, 178 | 0x7,0x2,0x7,0x3b,0x24,0x4,0x7,0x3e,0xb5,0x1,0xb5,0x8,0x39,0x1,0x9,0x2,0xf3,0x8,0x0,0x3e, 179 | 0x3,0x0,0x10,0x92,0x1,0x8,0xc6,0x4,0x6f,0x3d,0x8,0x2,0x0,0x3e,0x3,0x0,0x10,0x92,0x1,0x8, 180 | 0xc6,0x4,0x99,0x1,0x3d,0x8,0x2,0x0,0x3e,0x3,0x0,0x10,0x92,0x1,0x8,0xc6,0x4,0xc7,0x2,0x3d, 181 | 0x8,0x2,0x0,0x3e,0x3,0x0,0x10,0x92,0x1,0x8,0xc6,0x4,0x83,0x3,0x3d,0x8,0x2,0x0,0x3e,0x3, 182 | 0x0,0x3d,0x8,0x6,0x11,0x2a,0xe,0x2,0x0,0x93,0x7,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x6a,0x0, 183 | 0x2,0x3e,0x4,0x89,0x5,0x39,0x1,0x9,0x2,0x97,0x9,0x0,0x45,0x8,0x2,0x0,0xbe,0x1,0xe,0x2, 184 | 0x0,0x9f,0x7,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3e,0x4,0x95,0x5,0x39,0x1,0x9, 185 | 0x2,0xa3,0x9,0x0,0x7a,0x8,0x2,0x0,0xba,0x1,0xe,0x2,0x0,0xab,0x7,0x4,0x7,0x0,0x0,0xf5, 186 | 0x1,0x4,0xe,0xa,0x3,0xd,0x8,0x1,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3e,0x6, 187 | 0xa3,0x5,0x39,0x1,0x9,0x2,0xb3,0x9,0x0,0x3a,0x16,0x2,0x0,0x1,0x25,0x16,0x2,0xf5,0x6,0xf5, 188 | 0x6,0x1,0x16,0x2,0x1,0x0,0x3d,0x3e,0x2,0xd3,0x8,0x3a,0x16,0x2,0x0,0x1,0x10,0x4e,0x2,0x41, 189 | 0x99,0x1,0x3d,0x8,0x2,0x0,0x25,0x16,0x2,0x0,0x0,0x35,0x16,0x2,0x5,0x0,0x2,0x16,0x2,0xb, 190 | 0x0,0x2,0x16,0x2,0x0,0xaf,0x4,0x3e,0x2,0x0,0x39,0x1,0x6,0x2,0xa9,0x9,0x0,0x3e,0x1d,0x0, 191 | 0x10,0x24,0x22,0xe6,0x4,0x6f,0x3d,0x5,0x2,0x0,0xfd,0x1,0x5,0x2,0xf8,0x4,0x10,0x24,0x2,0xe6, 192 | 0x4,0x99,0x1,0x3d,0x5,0x2,0x0,0x25,0x6,0x2,0x3,0x0,0x53,0x6,0x2,0xa1,0x4,0x0,0x53,0x6, 193 | 0x2,0x0,0xa3,0x4,0x3e,0xf,0x0,0x3d,0x6,0x14,0x1f,0x3e,0x1,0x0,0x39,0x1,0xe,0x4,0xd3,0x9, 194 | 0x0,0xa8,0x1,0xe,0x2,0x0,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3d,0x6,0x6,0x19, 195 | 0x3e,0x1,0x0,0x39,0x1,0xe,0x4,0xdf,0x9,0x0,0xa8,0x1,0xe,0x2,0x0,0x4,0x7,0x0,0x0,0xf5, 196 | 0x1,0x4,0xe,0xa,0x3,0x3f,0x8,0x1,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3e,0x81, 197 | 0x1,0xfd,0x8,0x3d,0x8,0x86,0x1,0xf1,0x7,0x3e,0x7f,0x0,0x4,0x7e,0x0,0x0,0x4,0x4b,0x0,0x0, 198 | 0x4,0x19,0x0,0x6a,0x3d,0x8,0x2,0xf9,0x8,0x3d,0x8,0x2,0x83,0x1,0x1,0x8,0x2,0x1,0x0,0xba, 199 | 0x1,0xe,0x2,0x0,0x89,0x9,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3e,0x91,0x1,0xb9, 200 | 0x5,0x4,0x94,0x1,0x0,0x0,0x4,0x75,0x0,0x0,0x3d,0x8,0x78,0x11,0x2a,0xe,0x2,0x0,0x91,0x8, 201 | 0x3d,0x8,0x2,0x97,0x1,0xba,0x1,0xe,0x2,0x0,0x95,0x8,0xa6,0x1,0xe,0x2,0x3,0x0,0x23,0x4, 202 | 0x0,0x22,0x0,0x3,0x1,0x8,0x0,0x2,0x3e,0x93,0x1,0x4,0x3d,0x5,0x9a,0x1,0xe9,0x7,0x6f,0x8, 203 | 0x2,0x0,0x3e,0x95,0x1,0x0,0x4,0x90,0x1,0x0,0x8,0x3e,0x4,0xd5,0x2,0x39,0x1,0x9,0x2,0xa5, 204 | 0xa,0x0,0x3e,0x3,0x0,0x10,0x92,0x1,0x8,0x9f,0x5,0x6f,0x3d,0x8,0x2,0x0,0x6e,0x5,0x2,0x0, 205 | 0x3e,0x5,0x0,0x3d,0x8,0x8,0xa5,0x1,0x6e,0x5,0x2,0x0,0x3d,0x5,0x2,0x9,0xb3,0x1,0xe,0x2, 206 | 0x1,0x0,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3d,0x5,0x4,0xf,0x6f,0x8,0x2,0x0, 207 | 0x3,0x8,0x2,0x0,0x23,0x3e,0xbd,0x1,0x0,0x3d,0x5,0xc0,0x1,0xe9,0x7,0x6f,0x8,0x2,0x0,0x3e, 208 | 0xbb,0x1,0x0,0x4,0xb2,0x1,0x0,0x0,0x4,0x21,0x0,0x0,0x3d,0x8,0x2e,0xa1,0x1,0x3d,0x8,0x2, 209 | 0xc9,0x1,0x3d,0x8,0x2,0xc5,0x1,0x3d,0x8,0x2,0xc1,0x1,0x50,0x4,0x9,0x2,0x5,0x3,0x1,0x0, 210 | 0x1d,0x0,0x38,0x36,0x9,0xff,0x9,0x0,0x30,0x0,0x2,0x3b,0x38,0x8c,0xa,0x7,0x3b,0x7,0x4,0x7, 211 | 0x3b,0x92,0x1,0x4,0x7,0x3b,0x92,0x1,0x6,0x7,0x3b,0x92,0x1,0x6,0x7,0x3b,0x92,0x1,0x6,0x7, 212 | 0x3b,0x24,0x6,0x7,0x3b,0x7,0x4,0x7,0x3b,0x7,0x22,0x7,0x3b,0x24,0x2,0x7,0x3b,0x24,0x2,0x7, 213 | 0x3b,0x9a,0x3,0x6,0x7,0x3b,0x24,0x2,0x7,0x3b,0x7,0x1c,0x7,0x3b,0x7,0x1e,0x7,0x39,0x0,0xe, 214 | 0x93,0x1,0xe1,0xb,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x1d,0x85,0x6,0x0,0x88,0x6, 215 | 0x3e,0x8,0x6,0x39,0x1,0x9,0x2,0xe1,0xa,0x0,0x3e,0x5,0x0,0x10,0x92,0x1,0xa,0xbc,0x5,0x6f, 216 | 0x3d,0x8,0x2,0x0,0x3e,0x3,0x0,0x10,0x92,0x1,0x8,0xbc,0x5,0x99,0x1,0x3d,0x8,0x2,0x0,0x3e, 217 | 0x3,0x0,0x10,0x92,0x1,0x8,0xbc,0x5,0xc7,0x2,0x3d,0x8,0x2,0x0,0x3e,0x3,0x0,0x10,0x92,0x1, 218 | 0x8,0xbc,0x5,0x83,0x3,0x3d,0x8,0x2,0x0,0x3e,0x3,0x0,0x3d,0x5,0x8,0xdd,0x9,0x3e,0x2,0x8b, 219 | 0x9,0x39,0x1,0x9,0x2,0x81,0xb,0x0,0x7b,0x8,0x2,0x0,0x6e,0x5,0x2,0x0,0x82,0x1,0x5,0x2, 220 | 0x7,0x0,0x3e,0xb,0x0,0x3d,0x5,0xe,0x0,0x39,0x0,0x5,0x2,0xcf,0xa,0x87,0x1,0x5,0x2,0x1, 221 | 0x0,0xb3,0x1,0xe,0x2,0x0,0xbb,0x9,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3d,0x5, 222 | 0x4,0x15,0x39,0x0,0x5,0x2,0xdb,0xa,0x8b,0x1,0x5,0x2,0xd9,0x5,0xda,0x5,0x54,0xe,0x2,0x0, 223 | 0xf3,0x9,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3e,0x4,0x8f,0x5,0x3e,0x0,0x91,0x5, 224 | 0x3d,0x5,0x6,0x89,0xa,0x3e,0x1,0x0,0x39,0x1,0x5,0x4,0xf1,0xa,0x0,0x3e,0x5,0x0,0x3e,0x8, 225 | 0x85,0x5,0x3e,0x2,0x85,0xa,0x4,0x2,0x0,0x0,0xf6,0x1,0x4,0xe9,0x5,0x0,0x4,0x4,0x0,0x0, 226 | 0x3d,0x5,0x2,0x9,0xb1,0x1,0xe,0x2,0x0,0x8b,0x5,0x22,0x0,0x0,0x9,0x7,0x0,0x9,0x3d,0xe, 227 | 0xc,0x5,0xa8,0x1,0xe,0x2,0x0,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3d,0x5,0x4, 228 | 0x1d,0x8b,0x1,0x5,0x2,0xf1,0x5,0xa5,0x3,0x3e,0x23,0x0,0x10,0x24,0x28,0xdf,0x5,0x6f,0x3d,0x5, 229 | 0x2,0x0,0x3d,0x5,0x2,0x29,0x53,0x5,0x2,0x1,0x0,0x3d,0x5,0x2,0x2d,0x87,0x1,0x5,0x2,0x0, 230 | 0x8b,0xa,0x84,0x1,0x5,0x2,0x8d,0xa,0x0,0x82,0x1,0x5,0x2,0x5,0x0,0x10,0x24,0x2,0xdf,0x5, 231 | 0x99,0x1,0x3d,0x5,0x2,0x0,0x3d,0x5,0x2,0x39,0x87,0x1,0x5,0x2,0x0,0x97,0xa,0x53,0x5,0x2, 232 | 0x3,0x0,0x25,0x6,0x2,0x9,0x0,0x3e,0x1b,0x0,0x3d,0x6,0x20,0x0,0x3e,0x1,0x0,0x39,0x1,0xe, 233 | 0x4,0xd9,0xb,0x0,0xa8,0x1,0xe,0x2,0x0,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3e, 234 | 0x43,0x87,0x5,0x3d,0x6,0x48,0x1e,0x3e,0x51,0x0,0x4,0x12,0x0,0x3e,0x3d,0x5,0x6,0x4d,0x53,0x5, 235 | 0x2,0x0,0xc7,0xa,0x3e,0x55,0x0,0x4,0x20,0x0,0x0,0x4,0xd,0x0,0x0,0x3d,0x5,0x46,0x7,0x53, 236 | 0x5,0x2,0x0,0xcb,0xa,0x3e,0x4f,0x0,0x4,0x2,0x0,0x4,0x3d,0xe,0x4c,0x7,0x23,0x4,0x0,0x22, 237 | 0x0,0x3,0x1,0x0,0x0,0x2,0x3d,0x8,0x4,0xfd,0xa,0x3e,0x95,0x1,0x0,0x4,0x94,0x1,0x0,0x0, 238 | 0x3d,0x8,0x4,0x99,0x1,0x3e,0xa3,0x1,0x0,0x3d,0x5,0xa6,0x1,0x40,0x6f,0x8,0x2,0x0,0x3e,0xa1, 239 | 0x1,0x0,0x3d,0xe,0xa4,0x1,0x42,0xa8,0x1,0xe,0x2,0x0,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0, 240 | 0x0,0x2,0x3e,0xa7,0x1,0xc3,0x7,0x4,0xaa,0x1,0x0,0x0,0x4,0x73,0x0,0x0,0x4,0xb,0x0,0x0, 241 | 0x3d,0x8,0x82,0x1,0x2f,0x3d,0x8,0x2,0xab,0x1,0x3d,0x8,0x2,0xa7,0x1,0x3d,0x8,0x2,0xa3,0x1, 242 | 0x50,0x4,0x9,0x2,0x5,0x3,0x1,0x0,0x1d,0x0,0x38,0x36,0x9,0xcb,0xb,0x0,0x30,0x0,0x2,0x3b, 243 | 0x24,0xd8,0xb,0x7,0x3b,0x7,0x4,0x7,0x3b,0x38,0x14,0x7,0x3b,0x7,0x2,0x7,0x3b,0x92,0x1,0x4, 244 | 0x7,0x3b,0x92,0x1,0x6,0x7,0x3b,0x92,0x1,0x6,0x7,0x3b,0x92,0x1,0x6,0x7,0x3b,0x7,0x18,0x7, 245 | 0x3b,0x17,0x20,0x7,0x3b,0x7,0x4,0x7,0x3b,0x38,0x38,0x7,0x39,0x0,0xe,0xab,0x1,0xc9,0xd,0x23, 246 | 0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x1d,0xd5,0x7,0x0,0xd8,0x7,0x3d,0x5,0x6,0x8f,0xb, 247 | 0x3e,0x2,0xbb,0xa,0x39,0x1,0x9,0x2,0xb1,0xc,0x0,0x7b,0x8,0x2,0x0,0x6e,0x5,0x2,0x0,0x82, 248 | 0x1,0x5,0x2,0x7,0x0,0x3e,0xb,0x0,0x3d,0x5,0xe,0x0,0x54,0xe,0x2,0x0,0x89,0xb,0x23,0x4, 249 | 0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x1d,0xed,0x7,0x0,0xf0,0x7,0x3e,0x6,0xb7,0x8,0x39,0x1, 250 | 0x9,0x2,0xc7,0xc,0x0,0x3e,0x3,0x0,0x10,0x92,0x1,0x8,0xb0,0x6,0x6f,0x3d,0x8,0x2,0x0,0x3e, 251 | 0x3,0x0,0x10,0x92,0x1,0x8,0xb0,0x6,0x99,0x1,0x3d,0x8,0x2,0x0,0x3e,0x3,0x0,0x10,0x92,0x1, 252 | 0x8,0xb0,0x6,0xc7,0x2,0x3d,0x8,0x2,0x0,0x3e,0x3,0x0,0x10,0x92,0x1,0x8,0xb0,0x6,0x83,0x3, 253 | 0x3d,0x8,0x2,0x0,0x3e,0x3,0x0,0x10,0x4e,0x6,0x60,0xc7,0x2,0x3d,0x8,0x2,0x0,0xba,0x1,0xe, 254 | 0x2,0x0,0xe9,0xa,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x64,0x0,0x2,0x3d,0x8,0x4,0x11,0x2a,0xe, 255 | 0x2,0x0,0xf1,0xa,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3d,0x9,0x6,0xcb,0xb,0x3a, 256 | 0x16,0x2,0x0,0x1,0x3d,0x3e,0x2,0x91,0xc,0x3a,0x16,0x2,0x0,0x1,0x35,0x16,0x2,0x3,0x0,0x25, 257 | 0x16,0x2,0xbd,0xa,0xbd,0xa,0x1,0x16,0x2,0x1,0x0,0x3d,0x3e,0x2,0x9b,0xc,0x3a,0x16,0x2,0x0, 258 | 0x1,0x10,0x4e,0x2,0x41,0x99,0x1,0x3d,0x8,0x2,0x0,0x25,0x16,0x2,0x0,0x0,0x35,0x16,0x2,0x5, 259 | 0x0,0x2,0x16,0x2,0xb,0x0,0x2,0x16,0x2,0x0,0xf7,0x7,0x3e,0x2,0x0,0x39,0x1,0x6,0x2,0xf1, 260 | 0xc,0x0,0x3e,0x21,0x0,0x3d,0x6,0x26,0x0,0x3e,0x1,0x0,0x39,0x1,0xe,0x4,0x89,0xd,0x0,0xa8, 261 | 0x1,0xe,0x2,0x0,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x10,0x24,0x4,0xc8,0x6,0x6f, 262 | 0x3d,0x5,0x2,0x0,0xb1,0x1,0xe,0x2,0x0,0x9f,0xc,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0, 263 | 0x2,0x10,0x24,0x4,0xc8,0x6,0x6f,0x3d,0x5,0x2,0x0,0xab,0x1,0xe,0x2,0xe6,0x6,0x72,0x23,0x4, 264 | 0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x10,0x4e,0x4,0x60,0x6f,0x3d,0x8,0x2,0x0,0x10,0x4e,0x2, 265 | 0x41,0x6f,0x3d,0x8,0x2,0x0,0x35,0x8,0x2,0x3,0x0,0x3e,0x75,0x0,0x10,0x4e,0x78,0x60,0x99,0x1, 266 | 0x3d,0x8,0x2,0x0,0x10,0x4e,0x2,0x41,0x99,0x1,0x3d,0x8,0x2,0x0,0x35,0x8,0x2,0x3,0x0,0x3e, 267 | 0x79,0x0,0x3d,0x8,0x7c,0xcb,0xb,0x3e,0x6f,0x0,0x4,0x5a,0x0,0x0,0x4,0x9,0x0,0x0,0x4,0x9, 268 | 0x0,0x0,0x4,0x2f,0x0,0x0,0x3e,0x1b,0xf7,0xb,0x4,0x14,0x0,0x64,0x3e,0x77,0xff,0x8,0x4,0x14, 269 | 0x0,0x0,0x3d,0x8,0x68,0x1f,0x3d,0x8,0x2,0x81,0x1,0x3d,0x8,0x2,0x7d,0x3d,0x8,0x2,0x79,0x50, 270 | 0x4,0x9,0x2,0x5,0x3,0x1,0x0,0x3e,0x9,0x0,0x3d,0x9,0xc,0x0,0x1d,0x0,0x38,0x36,0x1,0xfd, 271 | 0xc,0x0,0x3a,0x37,0x38,0x3,0x37,0x17,0x2,0x0,0x4,0x3b,0x7,0x90,0xd,0x7,0x3b,0x7,0x1c,0x7, 272 | 0x3d,0x5,0x29,0xf3,0xc,0xb1,0x1,0xe,0x2,0x0,0x8f,0xc,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0, 273 | 0x0,0x2,0x3e,0x8b,0xd,0x6,0x7e,0x0,0x8e,0xd,0x3e,0x8d,0xd,0x91,0x9,0x3d,0x16,0x98,0xd,0x2, 274 | 0x6e,0x6,0x2,0x0,0x3e,0x3,0x0,0x10,0x24,0x6,0x86,0x7,0x6f,0x3d,0x5,0x2,0x0,0xb3,0x1,0xe, 275 | 0x2,0x0,0xa5,0xc,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x10,0x24,0x4,0x86,0x7,0x99, 276 | 0x1,0x3d,0x5,0x2,0x0,0xb1,0x1,0xe,0x2,0x0,0xd1,0xc,0x4,0x5,0x0,0x0,0xf5,0x1,0x4,0xe, 277 | 0x8,0x3,0x15,0x6,0x1,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3d,0x6,0x6,0x17,0x3e, 278 | 0x1,0x0,0x39,0x1,0x9,0x4,0xcb,0xd,0x0,0x3e,0xb5,0xd,0x0,0x4,0xb0,0xd,0x0,0x0,0x3d,0x6, 279 | 0x8,0x19,0x54,0xe1,0x2,0x2,0x0,0x89,0xa,0x9b,0x1,0xe,0x2,0x98,0x7,0x23,0x4,0x0,0x22,0x0, 280 | 0x3,0x1,0x0,0x0,0x2,0x39,0x0,0x9,0x4,0xc5,0xd,0x3e,0xc1,0xd,0x0,0x4,0xc0,0xd,0x0,0x0, 281 | 0x3d,0x6,0x4,0x29,0x54,0xe1,0x2,0x2,0x0,0xbf,0x3,0x9b,0x1,0xe,0x2,0x9e,0x7,0x23,0x4,0x0, 282 | 0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x39,0x0,0x9,0x4,0xd5,0xd,0x3e,0xcd,0xd,0x0,0x4,0xcc,0xd, 283 | 0x0,0x0,0x3d,0x6,0x4,0x35,0x54,0xe1,0x2,0x2,0x0,0xb7,0xc,0x9b,0x1,0xe,0x2,0xa4,0x7,0x23, 284 | 0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x39,0x0,0x9,0x4,0xe5,0xd,0x3e,0xd9,0xd,0x0,0x4, 285 | 0xd8,0xd,0x0,0x0,0x3d,0x6,0x4,0x41,0x54,0xe1,0x2,0x2,0x0,0xeb,0x6,0x9b,0x1,0xe,0x2,0xaa, 286 | 0x7,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x39,0x0,0x9,0x4,0xf5,0xd,0x3e,0xe5,0xd, 287 | 0x0,0x4,0xe4,0xd,0x0,0x0,0x3d,0x6,0x4,0x4d,0x54,0xe1,0x2,0x4,0x0,0x2,0x9b,0x1,0xe,0x2, 288 | 0xb1,0x7,0x23,0x4,0x0,0x22,0x0,0x3,0x1,0x0,0x0,0x2,0x3d,0x3e,0x4,0xe3,0xd,0x3a,0x16,0x2, 289 | 0x0,0x1,0x45,0x8,0x2,0x0,0x79,0x8,0x2,0x1,0x50,0x4,0x9,0x2,0x1,0x0,0xd9,0xc,0xd9,0xc, 290 | 0x3e,0xfb,0xd,0x0,0x4,0xf2,0xd,0x0,0x0,0x7e,0x38, -------------------------------------------------------------------------------- /example_fbo/shaders/src/bin/buf.frag.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_fbo/shaders/src/bin/buf.frag.spv -------------------------------------------------------------------------------- /example_fbo/shaders/src/bin/buf.frag.yariv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_fbo/shaders/src/bin/buf.frag.yariv -------------------------------------------------------------------------------- /example_fbo/shaders/src/bin/buf.vert.hex: -------------------------------------------------------------------------------- 1 | 0x1,0x0,0x8a,0x80,0x20,0x21,0xfd,0x3,0x1,0xf8,0x3,0x3,0x0,0x47,0x4c,0x53,0x4c,0x2e,0x73,0x74, 2 | 0x64,0x2e,0x34,0x35,0x30,0x0,0x0,0x0,0x0,0xf9,0x3,0x0,0x1,0xf,0x4,0x0,0x4,0xed,0xc2,0xa5, 3 | 0xf3,0x6,0x0,0xd,0x12,0x1d,0xe,0x14,0x0,0xb,0x0,0xe,0x0,0x1,0xb,0x1,0xe,0x0,0x2,0xb, 4 | 0x3,0xe,0x0,0x3,0xb,0x4,0x8,0x0,0x2,0x7d,0xe,0x0,0x7d,0x16,0x0,0xfe,0x3,0x2,0x21,0x0, 5 | 0x3,0x2,0x16,0x6,0x20,0x17,0x7,0x6,0x4,0x15,0x8,0x20,0x0,0x2b,0x7,0x27,0x1,0x1c,0xa,0x6, 6 | 0x9,0x1e,0x4,0xb,0x7,0x6,0xa,0xa,0x20,0xc,0x3,0xb,0x3b,0xb,0x8,0x3,0x15,0xe,0x20,0x1, 7 | 0x2b,0xd,0x4,0x0,0x17,0x10,0x6,0x3,0x20,0x11,0x1,0x10,0x3b,0x10,0x6,0x1,0x27,0x5,0x4,0x0, 8 | 0x0,0x80,0x3f,0x20,0x19,0x3,0x7,0x17,0x1b,0x6,0x2,0x20,0x1c,0x3,0x1b,0x3b,0x1b,0x12,0x3,0x36, 9 | 0x1,0x31,0x0,0x3,0x0,0x2,0x3d,0xf,0x1c,0x1a,0x45,0x5,0x4,0x0,0x79,0x5,0x2,0x3,0x7a,0x5, 10 | 0x2,0x5,0x50,0x4,0x6,0x2,0x3,0x1,0x0,0x5,0x10,0x18,0x4,0xd,0xf,0x3e,0x0,0x3,0x10,0x18, 11 | 0x8,0xd,0xf,0x3d,0x6,0x2,0x0,0x3a,0x1a,0x2,0x0,0x1,0x3e,0x5,0x0,0x7e,0x38, -------------------------------------------------------------------------------- /example_fbo/shaders/src/bin/buf.vert.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_fbo/shaders/src/bin/buf.vert.spv -------------------------------------------------------------------------------- /example_fbo/shaders/src/bin/buf.vert.yariv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_fbo/shaders/src/bin/buf.vert.yariv -------------------------------------------------------------------------------- /example_fbo/shaders/src/bin/main.frag.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_fbo/shaders/src/bin/main.frag.spv -------------------------------------------------------------------------------- /example_fbo/shaders/src/bin/main.frag.yariv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_fbo/shaders/src/bin/main.frag.yariv -------------------------------------------------------------------------------- /example_fbo/shaders/src/bin/main.vert.hex: -------------------------------------------------------------------------------- 1 | 0x1,0x0,0x8a,0x80,0x20,0x21,0xfd,0x3,0x1,0xf8,0x3,0x3,0x0,0x47,0x4c,0x53,0x4c,0x2e,0x73,0x74, 2 | 0x64,0x2e,0x34,0x35,0x30,0x0,0x0,0x0,0x0,0xf9,0x3,0x0,0x1,0xf,0x4,0x0,0x4,0xed,0xc2,0xa5, 3 | 0xf3,0x6,0x0,0xd,0x12,0x1d,0xe,0x14,0x0,0xb,0x0,0xe,0x0,0x1,0xb,0x1,0xe,0x0,0x2,0xb, 4 | 0x3,0xe,0x0,0x3,0xb,0x4,0x8,0x0,0x2,0x7d,0xe,0x0,0x7d,0x16,0x0,0xfe,0x3,0x2,0x21,0x0, 5 | 0x3,0x2,0x16,0x6,0x20,0x17,0x7,0x6,0x4,0x15,0x8,0x20,0x0,0x2b,0x7,0x27,0x1,0x1c,0xa,0x6, 6 | 0x9,0x1e,0x4,0xb,0x7,0x6,0xa,0xa,0x20,0xc,0x3,0xb,0x3b,0xb,0x8,0x3,0x15,0xe,0x20,0x1, 7 | 0x2b,0xd,0x4,0x0,0x17,0x10,0x6,0x3,0x20,0x11,0x1,0x10,0x3b,0x10,0x6,0x1,0x27,0x5,0x4,0x0, 8 | 0x0,0x80,0x3f,0x20,0x19,0x3,0x7,0x17,0x1b,0x6,0x2,0x20,0x1c,0x3,0x1b,0x3b,0x1b,0x12,0x3,0x36, 9 | 0x1,0x31,0x0,0x3,0x0,0x2,0x3d,0xf,0x1c,0x1a,0x45,0x5,0x4,0x0,0x79,0x5,0x2,0x3,0x7a,0x5, 10 | 0x2,0x5,0x50,0x4,0x6,0x2,0x3,0x1,0x0,0x5,0x10,0x18,0x4,0xd,0xf,0x3e,0x0,0x3,0x10,0x18, 11 | 0x8,0xd,0xf,0x3d,0x6,0x2,0x0,0x3a,0x1a,0x2,0x0,0x1,0x3e,0x5,0x0,0x7e,0x38, -------------------------------------------------------------------------------- /example_fbo/shaders/src/bin/main.vert.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_fbo/shaders/src/bin/main.vert.spv -------------------------------------------------------------------------------- /example_fbo/shaders/src/bin/main.vert.yariv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_fbo/shaders/src/bin/main.vert.yariv -------------------------------------------------------------------------------- /example_fbo/shaders/src/buf.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #extension GL_ARB_separate_shader_objects: enable 4 | #extension GL_ARB_shading_language_420pack: enable 5 | #extension GL_GOOGLE_include_directive : enable 6 | 7 | layout (location = 0) in vec2 frag_pos; 8 | 9 | layout (set = 0, binding = 0) uniform sampler2D u_Channel0; 10 | 11 | layout (push_constant) uniform push_constants 12 | { 13 | vec4 u_Mouse; 14 | vec4 u_Date; 15 | bvec2 u_Mouse_lr; 16 | vec2 u_Resolution; 17 | bool u_debugdraw; 18 | int pCustom; 19 | float u_Time; 20 | float u_TimeDelta; 21 | int u_Frame; 22 | } constants; 23 | 24 | vec3 iResolution=vec3(constants.u_Resolution,1.); 25 | float iTime=constants.u_Time; 26 | float iTimeDelta=constants.u_TimeDelta; 27 | int iFrame=constants.u_Frame; 28 | vec4 iMouse=constants.u_Mouse; 29 | vec4 iDate=constants.u_Date; 30 | bool is_debugdraw=constants.u_debugdraw; 31 | bool is_pause=bool(constants.pCustom-(constants.pCustom/10)*10); 32 | 33 | #define iChannel0 u_Channel0 34 | 35 | layout (location = 0) out vec4 out_color; 36 | 37 | #include "buf0.glsl" 38 | 39 | void main() 40 | { 41 | vec4 uFragColor=vec4(0.); 42 | vec2 fragCoord=gl_FragCoord.xy; 43 | 44 | mainImage(uFragColor,fragCoord); 45 | out_color=uFragColor; 46 | } 47 | -------------------------------------------------------------------------------- /example_fbo/shaders/src/buf.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #extension GL_ARB_separate_shader_objects: enable 4 | #extension GL_ARB_shading_language_420pack: enable 5 | 6 | layout (location = 0) in vec3 in_pos; 7 | layout (location = 0) out vec2 frag_pos; 8 | 9 | void main() 10 | { 11 | gl_Position = vec4(in_pos.xyz, 1); 12 | frag_pos = gl_Position.xy; 13 | } 14 | -------------------------------------------------------------------------------- /example_fbo/shaders/src/buf0.glsl: -------------------------------------------------------------------------------- 1 | // self https://www.shadertoy.com/view/3syXDD 2 | 3 | // Created by Danil (2019+) https://github.com/danilw 4 | // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. 5 | 6 | //logic 7 | 8 | #define res (iResolution.xy / iResolution.y) 9 | 10 | const int spawn_per_frame=60; 11 | 12 | vec4 loadval(ivec2 ipx) { 13 | return texelFetch(iChannel0, ipx, 0); 14 | } 15 | 16 | bool is_end(){ 17 | return loadval(ivec2(2,1)).x>0.; 18 | } 19 | 20 | bool get_map_by_id(ivec2 idx){ 21 | ivec2 ipx=ivec2(idx.x,0); 22 | float val=texelFetch(iChannel0,ipx,0)[idx.y]; 23 | return val>0.; 24 | } 25 | 26 | vec4 tile_uv(vec2 p){ 27 | vec2 tuv=p; 28 | tuv=(p)/3.*vec2(3.5*1.77,6.); 29 | tuv.x=sqrt(1.*floor(abs(tuv.x)+0.50)); 30 | vec2 op=p; 31 | op.y+=-.03; 32 | op.y+=-0.15*(tuv.x); 33 | op=mod(op*vec2(4.,6.)*2.+(1./2.)*vec2(4.,6.),vec2(4.,6.))-(1./2.)*vec2(4.,6.); 34 | return vec4(op,tuv); 35 | } 36 | 37 | ivec2 tile_idx(vec2 p){ 38 | vec4 tup=tile_uv(p); 39 | vec2 ti=tup.zw; 40 | vec2 etd=(p+res/2.*3.)/3.*vec2(3.5*1.77,6.); 41 | etd.y+=-.25*3.; 42 | etd.y+=1.-0.1*(ti.x)*2.; 43 | vec2 ftid=vec2(etd+vec2(((16./9.)-res.x)*3.1+1.,0.)); 44 | ivec2 tid=ivec2(ftid); 45 | return clamp(tid-ivec2(1),ivec2(0),ivec2(10,3)); 46 | } 47 | 48 | float rand(vec2 co){ 49 | return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); 50 | } 51 | 52 | int spawner(int ifr){ 53 | return int(20.*rand(vec2(float(ifr),iTime))); 54 | } 55 | 56 | int timer_cd(){ 57 | return spawn_per_frame; 58 | } 59 | 60 | // map in [x[0-10],y[0]], [0,0].x==[0,0] element [0,0].y=[0,1] elem...etc 61 | vec4 logic_map(ivec2 ipx){ 62 | if(is_end()){ 63 | return vec4(-1.); 64 | } 65 | vec4 retc=vec4(0.); 66 | vec4 ocol=loadval(ipx); 67 | retc=ocol; 68 | if((loadval(ivec2(1,1)).x>=0.)&&(loadval(ivec2(1,1)).z>0.)){ 69 | ivec2 tidx=tile_idx((loadval(ivec2(1,1)).xy-0.5)*res*vec2(3.)); 70 | if(ipx==ivec2(tidx.x,0))retc[tidx.y]=1.; 71 | ivec2 mtidx=ivec2(5,0)+ivec2(-tidx.x,tidx.y)+ivec2(5,0); 72 | if(ipx==ivec2(mtidx.x,0))retc[mtidx.y]=-1.; 73 | } 74 | 75 | int local_iFrame=iFrame-int(loadval(ivec2(2,1)).w); 76 | if(local_iFrame/timer_cd()<=10){ 77 | if(local_iFrame%timer_cd()==0){ 78 | ivec2 rr=ivec2(-1); 79 | rr=ivec2(6,0); 80 | int rnd=spawner(iFrame); 81 | bool br=false; 82 | for(int a=0;a<20;a++){ 83 | if(!br){ 84 | rnd=rnd%20; 85 | ivec2 trr=ivec2(rr.x+rnd-5*(rnd/5),rr.y+rnd/5); 86 | if(!get_map_by_id(trr)){ 87 | br=true; 88 | rr=trr; 89 | break; 90 | } 91 | rnd+=1; 92 | } 93 | } 94 | if(ipx==ivec2(rr.x,0))retc[rr.y]=1.; 95 | if(br){ 96 | ivec2 mtidx=ivec2(5,0)+ivec2(-rr.x,rr.y)+ivec2(5,0); 97 | if(ipx==ivec2(mtidx.x,0))retc[mtidx.y]=-1.; 98 | } 99 | 100 | } 101 | } 102 | 103 | return retc; 104 | } 105 | 106 | //[3,1] 107 | //[score,last_click.x,last_click,y,0] 108 | vec4 logic_vals3(){ 109 | if(is_end()){ 110 | return vec4(-1.); 111 | } 112 | vec4 self_dat=loadval(ivec2(3,1)); 113 | float a=self_dat.x; 114 | float b=self_dat.y; 115 | float c=self_dat.z; 116 | float d=self_dat.w; 117 | 118 | if(a<0.)a=0.; 119 | 120 | if((loadval(ivec2(1,1)).x>=0.)&&(loadval(ivec2(1,1)).z>0.)){ 121 | ivec2 tidx=tile_idx((loadval(ivec2(1,1)).xy-0.5)*res*vec2(3.)); 122 | ivec2 ltidx=ivec2(b,c); 123 | if((!get_map_by_id(tidx))||(tidx!=ltidx)){ 124 | a+=1.; 125 | b=float(tidx.x); 126 | c=float(tidx.y); 127 | } 128 | } 129 | 130 | vec4 sc_dat=loadval(ivec2(2,1)); 131 | 132 | 133 | return vec4(a,b,c,d); 134 | } 135 | 136 | //[2,1] 137 | //[is_end,timer,spwan_at_score,iFrame_spawn_start] 138 | vec4 logic_vals2(){ 139 | vec4 self_dat=loadval(ivec2(2,1)); 140 | float a=self_dat.x; 141 | float b=self_dat.y; 142 | float c=self_dat.z; 143 | float d=self_dat.w; 144 | if(a<0.){ 145 | if((loadval(ivec2(1,1)).x>=0.)&&(loadval(ivec2(1,1)).z>0.)){ 146 | ivec2 tidx=tile_idx((loadval(ivec2(1,1)).xy-0.5)*res*vec2(3.)); 147 | ivec2 mtidx=ivec2(5,0)+ivec2(-tidx.x,tidx.y)+ivec2(5,0); 148 | if((!get_map_by_id(tidx))&&(!get_map_by_id(mtidx))){ 149 | a=1.; 150 | b=iTime; 151 | } 152 | } 153 | }else{ 154 | if(iTime-b>1.){ 155 | a=-1.; 156 | } 157 | } 158 | 159 | if((c<0.)||(a>0.)){ 160 | c=10.; 161 | d=float(iFrame); 162 | }else{ 163 | vec4 sc_val=loadval(ivec2(3,1)); 164 | int score=int(sc_val.x); 165 | if(int(c)<=score){ 166 | c=float(score)+10.; 167 | d=float(iFrame); 168 | } 169 | } 170 | return vec4(a,b,c,d); 171 | } 172 | 173 | //[0,1] 174 | //[last_rand,this_rand,timer,0] 175 | vec4 logic_vals1(){ 176 | if(is_end()){ 177 | return vec4(-1.); 178 | } 179 | vec4 self_dat=loadval(ivec2(0,1)); 180 | float a=self_dat.x; 181 | float b=self_dat.y; 182 | float c=self_dat.z; 183 | float d=self_dat.w; 184 | int local_iFrame=iFrame-int(loadval(ivec2(2,1)).w); 185 | if(local_iFrame/timer_cd()<=10){ 186 | if(local_iFrame%timer_cd()==0){ 187 | ivec2 rr=ivec2(-1); 188 | rr=ivec2(6,0); 189 | int rnd=spawner(iFrame); 190 | bool br=false; 191 | for(int a=0;a<20;a++){ 192 | if(!br){ 193 | rnd=rnd%20; 194 | ivec2 trr=ivec2(rr.x+rnd-5*(rnd/5),rr.y+rnd/5); 195 | if(!get_map_by_id(trr)){ 196 | br=true; 197 | rr=trr; 198 | break; 199 | } 200 | rnd+=1; 201 | } 202 | } 203 | if(br)c=iTime; 204 | a=b; 205 | b=float(rnd); 206 | if(!br)b=-1.; 207 | } 208 | } 209 | 210 | return vec4(a,b,c,d); 211 | } 212 | 213 | //[1,1] 214 | //[m.x,m.y,click,timer] 215 | vec4 focus_mouse(){ 216 | if(is_end()){ 217 | return vec4(-1.); 218 | } 219 | 220 | int local_iFrame=iFrame-int(loadval(ivec2(2,1)).w); 221 | if(local_iFrame==1){ 222 | return vec4(-1.); 223 | } 224 | 225 | 226 | vec4 self_dat=loadval(ivec2(1,1)); 227 | float fpx=self_dat.x; 228 | float fpy=self_dat.y; 229 | float a=self_dat.z; 230 | float b=self_dat.w; 231 | 232 | if(iMouse.z>0.){ 233 | if(a<0.){ 234 | ivec2 tidx=tile_idx((iMouse.xy/iResolution.xy-0.5)*res*vec2(3.)); 235 | if(!get_map_by_id(tidx)) 236 | if(tidx.x<6) 237 | if(tidx.x!=5){ 238 | fpx=iMouse.x/iResolution.x; 239 | fpy=iMouse.y/iResolution.y; 240 | b=iTime; 241 | } 242 | } 243 | a=1.; 244 | } 245 | else{ 246 | a=-1.; 247 | } 248 | vec4 col = vec4(fpx,fpy,a,b); 249 | return col; 250 | } 251 | 252 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 253 | { 254 | //init 255 | if(iFrame<10){ 256 | fragColor=vec4(-10.); 257 | return; 258 | } 259 | fragColor=vec4(0.); 260 | ivec2 ipx = ivec2(fragCoord); 261 | if((ipx.x<=10)&&(ipx.y<1)){ 262 | fragColor=logic_map(ipx); 263 | } 264 | if(ipx==ivec2(1,1)){ 265 | fragColor=focus_mouse(); 266 | } 267 | if(ipx==ivec2(0,1)){ 268 | fragColor=logic_vals1(); 269 | } 270 | if(ipx==ivec2(2,1)){ 271 | fragColor=logic_vals2(); 272 | } 273 | if(ipx==ivec2(3,1)){ 274 | fragColor=logic_vals3(); 275 | } 276 | if(ipx==ivec2(4,1)){ 277 | fragColor=vec4(iResolution.xy,0.,0.); 278 | } 279 | } 280 | -------------------------------------------------------------------------------- /example_fbo/shaders/src/main.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #extension GL_ARB_separate_shader_objects: enable 4 | #extension GL_ARB_shading_language_420pack: enable 5 | #extension GL_GOOGLE_include_directive : enable 6 | 7 | layout (location = 0) in vec2 frag_pos; 8 | 9 | layout (set = 0, binding = 0) uniform sampler2D u_Channel0; 10 | 11 | layout (push_constant) uniform push_constants 12 | { 13 | vec4 u_Mouse; 14 | vec4 u_Date; 15 | bvec2 u_Mouse_lr; 16 | vec2 u_Resolution; 17 | bool u_debugdraw; 18 | int pCustom; 19 | float u_Time; 20 | float u_TimeDelta; 21 | int u_Frame; 22 | } constants; 23 | 24 | vec3 iResolution=vec3(constants.u_Resolution,1.); 25 | float iTime=constants.u_Time; 26 | float iTimeDelta=constants.u_TimeDelta; 27 | int iFrame=constants.u_Frame; 28 | vec4 iMouse=constants.u_Mouse; 29 | vec4 iDate=constants.u_Date; 30 | bool is_debugdraw=constants.u_debugdraw; 31 | bool is_pause=bool(constants.pCustom-(constants.pCustom/10)*10); 32 | bool main_image_srgb=bool((constants.pCustom/10)*10-(constants.pCustom/100)*100); 33 | 34 | #define iChannel0 u_Channel0 35 | 36 | layout (location = 0) out vec4 out_color; 37 | 38 | #include "main_image.glsl" 39 | 40 | void main() 41 | { 42 | vec4 uFragColor=vec4(0.); 43 | vec2 fragCoord=gl_FragCoord.xy; 44 | fragCoord.y=iResolution.y-fragCoord.y; // shadertoy v(y)-flip main_image 45 | 46 | mainImage(uFragColor,fragCoord); 47 | out_color=uFragColor; 48 | if(main_image_srgb)out_color.rgb = ((exp2(out_color.rgb)-1.0)-out_color.rgb*0.693147)*3.258891; 49 | } 50 | -------------------------------------------------------------------------------- /example_fbo/shaders/src/main.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #extension GL_ARB_separate_shader_objects: enable 4 | #extension GL_ARB_shading_language_420pack: enable 5 | 6 | layout (location = 0) in vec3 in_pos; 7 | layout (location = 0) out vec2 frag_pos; 8 | 9 | void main() 10 | { 11 | gl_Position = vec4(in_pos.xyz, 1); 12 | frag_pos = gl_Position.xy; 13 | } 14 | -------------------------------------------------------------------------------- /example_fbo/shaders/src/main_image.glsl: -------------------------------------------------------------------------------- 1 | // self https://www.shadertoy.com/view/3syXDD 2 | 3 | // this is clicker(made for last two days...) 4 | 5 | // Gamplay: 6 | // Left side is for player, player click same buttons (in mirror) as on right side. 7 | // right side spawn 10 elements at same time max, when player clean all spawn again. 8 | // Goal is-get max score as you can. 9 | // score is numbers in right of screen 10 | 11 | // Created by Danil (2019+) https://github.com/danilw 12 | // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. 13 | 14 | #define SS(x, y, z) smoothstep (x, y, z) 15 | #define MD(a) mat2(cos(a), -sin(a), sin(a), cos(a)) 16 | #define PI atan(0.,-1.) 17 | #define TAU (2.*PI) 18 | #define E exp(1.) 19 | #define res (iResolution.xy / iResolution.y) 20 | 21 | float global_zoom=3.; 22 | const float smooth_zoom=2.; 23 | 24 | const vec3 redocol=vec3(ivec3(0xff,0x78,0x78))/float(0xff); 25 | const vec3 reddcol=vec3(ivec3(0xe8,0x00,0x00))/float(0xff); 26 | const vec3 darkcol=vec3(ivec3(0x22,0x22,0x22))/float(0xff); 27 | const vec3 bluocol=vec3(ivec3(0xd4,0xe6,0xff))/float(0xff); 28 | const vec3 colhl1=vec3(0x7a,0xda,0xfd)/float(0xff); 29 | const vec3 colhl2=vec3(0xfa,0x1a,0x0d)/float(0xff); 30 | const vec3 redd = vec3(0xe1, 0x46, 0x14) / float(0xff); 31 | 32 | vec4 mix_alpha(vec4 src1, vec4 src2){ 33 | return vec4(mix(src1.rgb, src2.rgb, src2.a), max(src1.a, src2.a)); 34 | } 35 | 36 | vec4 loadval(ivec2 ipx) { 37 | return texelFetch(iChannel0, ipx, 0); 38 | } 39 | 40 | bool get_map_by_id(ivec2 idx){ 41 | ivec2 ipx=ivec2(idx.x,0); 42 | float val=texelFetch(iChannel0,ipx,0)[idx.y]; 43 | return val>0.; 44 | } 45 | 46 | float rand(vec2 co){ 47 | return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); 48 | } 49 | 50 | //http://www.iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm 51 | 52 | float sdCircle( vec2 p, float r ) 53 | { 54 | return length(p) - r; 55 | } 56 | 57 | float sdBox( in vec2 p, in vec2 b ) 58 | { 59 | vec2 d = abs(p)-b; 60 | return length(max(d,vec2(0))) + min(max(d.x,d.y),0.0); 61 | } 62 | 63 | float sdTriangleIsosceles( in vec2 p, in vec2 q ) 64 | { 65 | p.x = abs(p.x); 66 | vec2 a = p - q*clamp( dot(p,q)/dot(q,q), 0.0, 1.0 ); 67 | vec2 b = p - q*vec2( clamp( p.x/q.x, 0.0, 1.0 ), 1.0 ); 68 | float s = -sign( q.y ); 69 | vec2 d = min( vec2( dot(a,a), s*(p.x*q.y-p.y*q.x) ), 70 | vec2( dot(b,b), s*(p.y-q.y) )); 71 | return -sqrt(d.x)*sign(d.y); 72 | } 73 | 74 | float sdUnevenCapsule( vec2 p, float r1, float r2, float h ) 75 | { 76 | p.x = abs(p.x); 77 | float b = (r1-r2)/h; 78 | float a = sqrt(1.0-b*b); 79 | float k = dot(p,vec2(-b,a)); 80 | if( k < 0.0 ) return length(p) - r1; 81 | if( k > a*h ) return length(p-vec2(0.0,h)) - r2; 82 | return dot(p, vec2(a,b) ) - r1; 83 | } 84 | 85 | float sdCross( in vec2 p, in vec2 b, float r ) 86 | { 87 | p = abs(p); p = (p.y>p.x) ? p.yx : p.xy; 88 | vec2 q = p - b; 89 | float k = max(q.y,q.x); 90 | vec2 w = (k>0.0) ? q : vec2(b.y-p.x,-k); 91 | return sign(k)*length(max(w,0.0)) + r; 92 | } 93 | 94 | //https://www.shadertoy.com/view/ldsyz4 95 | // The MIT License 96 | // Copyright © 2017 Inigo Quilez 97 | // Digit data by P_Malin (https://www.shadertoy.com/view/4sf3RN) 98 | const int[] font = int[](0x75557, 0x22222, 0x74717, 0x74747, 0x11574, 0x71747, 0x71757, 0x74444, 0x75757, 0x75747); 99 | const int[] powers = int[](1, 10, 100, 1000, 10000, 100000, 1000000); 100 | 101 | int PrintInt( in vec2 uv, in int value, const int maxDigits ) 102 | { 103 | if( abs(uv.y-0.5)<0.5 ) 104 | { 105 | int iu = int(floor(uv.x)); 106 | if( iu>=0 && iu> (p.x+p.y*4)) & 1; 112 | } 113 | } 114 | return 0; 115 | } 116 | 117 | float hand_dist(vec2 p){ 118 | p.y+=0.05; 119 | float dsq1=sdBox(p+vec2(-0.25,-0.1),vec2(0.035,0.15))-0.01; 120 | float dsq2=sdBox(p+vec2(0.0,-0.1),vec2(0.11,0.11))-0.05; 121 | float dtr1=sdTriangleIsosceles(p*vec2(1.,-1.)+vec2(0.1275,0.25-0.03),vec2(0.07,0.18))-0.03; 122 | float dsq3=max(min(1.,step(0.05,p.x)+step(0.04,p.y)),sdBox(p+vec2(0.0276,-0.14),vec2(0.13,0.13))-0.07); 123 | float dtr2=max(step(p.x,-0.03),sdTriangleIsosceles(p+vec2(0.05,0.2),vec2(0.18,0.18))-0.03); 124 | float duc1=max(step(-0.03,p.x),sdUnevenCapsule(p+vec2(-0.001,0.148),0.05,0.005,0.2)-0.03); 125 | float dcr1=max(min(1.,step(0.05,p.x)+step(0.1,p.y)),sdCross(p+vec2(-0.011,-0.017),vec2(0.15,0.1),0.025)); 126 | float dsum=min(min(min(min(dsq1,dsq2),min(dtr1,dsq3)),min(dtr2,duc1)),dcr1); 127 | return dsum; 128 | } 129 | 130 | vec4 draw_dlike(vec2 p){ 131 | float a=1.; 132 | vec3 col=vec3(0.); 133 | float px=global_zoom/iResolution.y; 134 | px*=smooth_zoom; 135 | 136 | float dc=SS(0.,0.+px,sdCircle(p,0.5)); 137 | 138 | float dh=hand_dist(p); 139 | 140 | float dsum=SS(0.,0.+px,dh); 141 | 142 | col=mix(vec3(1.),reddcol,dc); 143 | col=mix(darkcol,col,dsum); 144 | 145 | float dhq=sdBox(p,vec2(0.5)); 146 | float dq=SS(0.-px,0.+px,dhq-0.1); 147 | a=1.-dq; 148 | col.rgb*=a; 149 | a=min(1.,a+0.5-0.5*SS(0.,0.+px+0.015*global_zoom,dhq-0.1)); 150 | 151 | return vec4(col,1.-dq); 152 | 153 | } 154 | 155 | vec2 heart_uv(vec2 p){ 156 | p.x *= 1.; 157 | p.y -= sqrt(abs(p.x))*.65; 158 | return p; 159 | } 160 | 161 | float heartLength(vec2 p,float z){ 162 | p.y -= 0.1; 163 | p*=z; 164 | float r = abs(atan(p.x, p.y) / PI); 165 | float r2 = r * r; 166 | float s = (39.0 * r - 66.0 * r2 + 30.0 * r2 * r) / (6.0 - 5.0 * r); 167 | return length(p) / s; 168 | } 169 | 170 | vec4 draw_heart(vec2 p){ 171 | float heart_zoom=7.; 172 | float px=global_zoom/iResolution.y; 173 | float heart_dist = heartLength(p,heart_zoom); 174 | float dh = (1.0 - SS(1.0, 1.0+px*heart_zoom*smooth_zoom, heart_dist)); 175 | float a=1.; 176 | vec3 col=vec3(0.); 177 | float dc=SS(0.-px,0.+px,sdCircle(p,0.5)); 178 | col=mix(redocol,vec3(1.),dh); 179 | col=mix(col,vec3(1.),dc); 180 | a=1.-dc; 181 | col.rgb*=a; 182 | a=min(1.,a+0.5-0.5*SS(0.,0.+px+0.015*global_zoom,sdCircle(p,0.5))); 183 | return vec4(col,a); 184 | } 185 | 186 | //this is bad, dont use it 187 | vec4 tile_uv(vec2 p){ 188 | vec2 tuv=p; 189 | tuv=(p)/3.*vec2(3.5*1.77,6.); 190 | tuv.x=sqrt(1.*floor(abs(tuv.x)+0.50)); 191 | vec2 op=p; 192 | op.y+=-.03; 193 | op.y+=-0.15*(tuv.x); 194 | op=mod(op*vec2(4.,6.)*2.+(1./2.)*vec2(4.,6.),vec2(4.,6.))-(1./2.)*vec2(4.,6.); 195 | return vec4(op,tuv); 196 | } 197 | 198 | vec2 local_res(){ 199 | vec2 p=loadval(ivec2(1,1)).xy; 200 | vec2 ores=loadval(ivec2(4,1)).xy; 201 | ores=ores.xy/ores.y; 202 | return (p-0.5)*ores; 203 | } 204 | 205 | ivec2 tile_idx(vec2 p){ 206 | vec4 tup=tile_uv(p); 207 | vec2 ti=tup.zw; 208 | vec2 etd=(p+res/2.*3.)/3.*vec2(3.5*1.77,6.); 209 | etd.y+=-.25*3.; 210 | etd.y+=1.-0.1*(ti.x)*2.; 211 | vec2 ftid=vec2(etd+vec2(((16./9.)-res.x)*3.1+1.,0.)); 212 | ivec2 tid=ivec2(ftid); 213 | return clamp(tid-ivec2(1),ivec2(0),ivec2(10,3)); 214 | } 215 | 216 | vec2 get_posidx(ivec2 idx){ 217 | vec2 tid=vec2(idx)-vec2(5.,2.); 218 | tid*=vec2((0.5)/1.,0.5); 219 | tid.y+=0.15*sqrt(1.*floor(abs(tid.x*2.)+0.50)); 220 | return tid; 221 | } 222 | 223 | float map(vec2 p) { 224 | float hz=8.; 225 | vec2 tp=heart_uv(p*hz); 226 | vec2 otp=tp; 227 | tp=mod(tp+1.*2.,2.*2.)-1.*2.; 228 | float d=1.; 229 | d=(1.-length(tp)); 230 | float td = smoothstep(-0.05,0.35,-otp.y-hz-2.); 231 | td = max(td,smoothstep(0.,0.4,otp.y-hz+2.)); 232 | td = max(td,smoothstep(0.4,0.,otp.x+hz*2.+4.5+0.5*res.x)); 233 | td = max(td,smoothstep(0.4,0.,-otp.x+hz*2.+4.5+0.5*res.x)); 234 | if(loadval(ivec2(1,1)).x>=0.){ 235 | ivec2 tidx=tile_idx(((local_res()))*3.); 236 | if(get_map_by_id(tidx)) 237 | d=min(d,sdCircle(0.5*hz*((p-get_posidx(tidx))),0.65)); 238 | } 239 | if(loadval(ivec2(0,1)).y>=0.){ 240 | ivec2 rr=ivec2(6,0); 241 | int rnd=int(loadval(ivec2(0,1)).y); 242 | ivec2 tidx=ivec2(rr.x+rnd-5*(rnd/5),rr.y+rnd/5); 243 | if(get_map_by_id(tidx)) 244 | d=min(d,sdCircle(0.5*hz*((p-get_posidx(tidx))),0.65)); 245 | } 246 | d=max(td,d); 247 | return max(d,0.0001); 248 | } 249 | 250 | vec4 calcNormal(vec2 p) { 251 | vec2 e = vec2(0.001, 0.00); 252 | float m=map(p); 253 | vec3 nor = vec3( 254 | map(p + e.xy) - map(p - e.xy), 255 | map(p + e.yx) - map(p - e.yx), 256 | m * 0.13 257 | ); 258 | return vec4(normalize(nor),m); 259 | } 260 | 261 | /* 262 | vec3 calcNormal(vec2 p) { 263 | return texture(iChannel3,(p/3.)/(res)+0.5).rgb; 264 | }*/ 265 | 266 | float lineSegToBrightness(vec2 U, vec2 P0, vec2 P1) 267 | { 268 | P0 -= U; P1 -= U; 269 | float a = mod ( ( atan(P0.y,P0.x) - atan(P1.y,P1.x) ) / PI, 2.); 270 | return min( a, 2.-a ); 271 | } 272 | 273 | vec4 ggnergne( vec2 p ) 274 | { 275 | float sx = 0.; 276 | //sx=0.18 * cos( 4.0 * p.y - iTime*2.)*SS(0.2,0.84,p.y+0.5*3.)*SS(2.28,1.5,p.y+0.5*3.); 277 | p*=12.; 278 | float dy = 79./ ( 423. * abs(p.x-sx)); //-sx 279 | dy += 11./ (200. * max(-0.01+length(p.yx - vec2(p.y, 0.0)),0.0001)); 280 | return vec4( (p.y + 0.2) * dy, 0.43 * dy, dy, 1. ); 281 | 282 | } 283 | 284 | vec4 draw_bg(vec2 p){ 285 | float ed2=SS(.15,0.0,(p.y-01.)); 286 | vec3 rd = normalize(vec3(0.0, 0.0, -1.0)); 287 | vec3 nor = calcNormal(p).rgb; 288 | vec3 col=vec3(0.); 289 | 290 | vec4 tup=tile_uv(p); 291 | vec2 ti=tup.zw; 292 | vec2 etd=(p+res/2.*3.)/3.*vec2(3.5*1.77,6.); 293 | etd.y+=-.25*3.; 294 | etd.y+=1.-0.1*(ti.x)*2.; 295 | vec2 ftid=vec2(etd+vec2(((16./9.)-res.x)*3.1+1.,0.)); 296 | ivec2 tid=ivec2(ftid); 297 | vec2 tuv=tup.xy; 298 | vec3 ecol=clamp(ggnergne(p).rgb*(0.05+0.95*SS(0.2,0.4,p.y+0.5*3.)*SS(2.28,2.1,p.y-0.15*sqrt(abs(p.x))*1.5+0.5*3.))*SS(01.5,0.3,abs(p.x)),0.,15.); 299 | vec4 tile_col=vec4(0.); 300 | if((tid.y<5)&&(tid.y>=1)&&(tid.x<12)&&(tid.x>=1)){ 301 | if(get_map_by_id(tid-ivec2(1))){ 302 | float odz=global_zoom; 303 | global_zoom=global_zoom*3.; 304 | if(ftid.x<=6.5){ 305 | tile_col=draw_heart(tuv*(vec2(1.,.67))*0.5+vec2(0.,0.)); 306 | }else{ 307 | tile_col=draw_dlike(tuv*(vec2(1.,.67))*0.5+vec2(0.,0.)); 308 | } 309 | tile_col*=tile_col; 310 | global_zoom=odz; 311 | } 312 | } 313 | 314 | { 315 | vec3 elc=0.8*vec3((redocol*0.3+0.7)*lineSegToBrightness((vec2(-(p.x),p.y)+vec2(-1.1,-1.5)),vec2(0.),vec2(1.,0.))); 316 | vec3 lig = normalize(vec3(p.x, p.y, 0.0) - vec3(-1.5-0.1, 01.5, -1.0)); 317 | float dif = clamp(dot(nor, lig), 0.0, 1.0); 318 | float spea=clamp(dot(reflect(rd, nor), lig), 0.0, 1.0); 319 | float spe = pow(spea, 64.0); 320 | float fre = 1.0 - dot(-rd, nor); 321 | vec3 c=1.25*elc+redocol*0.1*step(p.x,0.)+redocol*ecol*dif+tile_col.rgb*dif; 322 | col = (1.)*(c * dif + spe*ed2 + fre * 0.2*elc.r); 323 | } 324 | { 325 | vec3 elc=0.7*vec3((bluocol*0.3+0.7)*lineSegToBrightness((vec2((p.x),p.y)+vec2(-1.1,-1.5)),vec2(0.),vec2(1.,0.))); 326 | vec3 lig = normalize(vec3(p.x, p.y, 0.0) - vec3(1.5+0.1, 01.5, -1.0)); 327 | float dif = clamp(dot(nor, lig), 0.0, 1.0); 328 | float spea=clamp(dot(reflect(rd, nor), lig), 0.0, 1.0); 329 | float spe = pow(spea, 64.0); 330 | float fre = 1.0 - dot(-rd, nor); 331 | vec3 c=1.25*elc+bluocol*0.1*step(0.,p.x)+bluocol*ecol*dif+tile_col.rgb*dif; 332 | col = max(col,(1.)*(c * dif + spe*ed2 + fre *0.2*elc.r)); 333 | } 334 | { 335 | vec3 lig = normalize(vec3(p.x, p.y, 0.0) - vec3(vec2(0.,0.03)+get_posidx(tile_idx((local_res())*3.)), -.50)); 336 | float dif = clamp(dot(nor, lig), 0.0, 1.0); 337 | float spea=clamp(dot(reflect(rd, nor), lig), 0.0, 1.0); 338 | float spe = pow(spea, 128.0); 339 | float fre = 1.0 - dot(-rd, nor); 340 | vec3 c=mix(2.*(colhl1)*(0.2+0.8*SS(0.3,0.,length(lig.xy))),tile_col.rgb,+tile_col.a)*SS(1.,0.,iTime-loadval(ivec2(1,1)).w); 341 | col = max(col,c*( dif + spe + fre * 0.2)); 342 | } 343 | { 344 | ivec2 rr=ivec2(6,0); 345 | int rnd=int(loadval(ivec2(0,1)).y); 346 | vec3 lig = normalize(vec3(p.x, p.y, 0.0) - vec3(vec2(0.,0.03)+get_posidx(ivec2(rr.x+rnd-5*(rnd/5),rr.y+rnd/5)), -.50)); 347 | float dif = clamp(dot(nor, lig), 0.0, 1.0); 348 | float spea=clamp(dot(reflect(rd, nor), lig), 0.0, 1.0); 349 | float spe = pow(spea, 128.0); 350 | float fre = 1.0 - dot(-rd, nor); 351 | vec3 c=mix(2.*(colhl2)*(0.2+0.8*SS(0.3,0.,length(lig.xy))),tile_col.rgb,+tile_col.a)*SS(1.,0.,iTime-loadval(ivec2(0,1)).z); 352 | col = max(col,c*( dif + spe + fre * 0.2)); 353 | } 354 | //col=mix_alpha(vec4(col,1.),tile_col).rgb; 355 | col += (rand(p)-.5)*.057; 356 | return vec4(col,1.); 357 | } 358 | 359 | vec4 draw_it(vec2 fragCoord){ 360 | vec2 uv = (fragCoord.xy) / iResolution.y - res/2.0; 361 | uv*=global_zoom; 362 | vec4 col=vec4(0.); 363 | col=draw_bg(uv); 364 | col.rgb+=float(PrintInt((uv+vec2(-0.68,0.43)*global_zoom)*6.,int(max(loadval(ivec2(3,1)).x,0.)),3))*redd.rrg*0.35; 365 | return col; 366 | } 367 | 368 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 369 | { 370 | vec2 uv = fragCoord/iResolution.xy; 371 | fragColor = draw_it(fragCoord); 372 | 373 | } 374 | 375 | 376 | -------------------------------------------------------------------------------- /example_fbo/shaders/yariv_pack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_fbo/shaders/yariv_pack -------------------------------------------------------------------------------- /example_fbo/shaders/yariv_to_hex.py: -------------------------------------------------------------------------------- 1 | import struct 2 | import os 3 | import sys 4 | import subprocess 5 | 6 | 7 | if len(sys.argv) != 2: 8 | print('Usage: python %s filename \n output is *.spv *.yariv and *.hex file \n' % sys.argv[0]) 9 | quit() 10 | 11 | inputfilepath = sys.argv[1] 12 | outputname = os.path.basename(inputfilepath) 13 | outdir = os.path.dirname(inputfilepath) 14 | ginfile = os.path.basename(inputfilepath) 15 | ooutdir = os.path.join(outdir,"bin"); 16 | 17 | spirvcompiler = 'glslangValidator' 18 | if os.name == 'nt': 19 | spirvcompiler += ".exe" 20 | 21 | yariv_pack = './yariv_pack' 22 | if os.name == 'nt': 23 | spirvcompiler += ".exe" 24 | 25 | if not os.path.isdir(ooutdir): 26 | os.mkdir(ooutdir, 0o0755 ); 27 | 28 | subprocess.call([spirvcompiler,'-V100',inputfilepath,'-o',os.path.join(ooutdir,ginfile) + '.spv']) 29 | 30 | subprocess.call([yariv_pack,os.path.join(ooutdir,ginfile) + '.spv']) 31 | 32 | infile = open(os.path.join(ooutdir,ginfile) + '.yariv', 'rb') 33 | outfilepath = os.path.join(ooutdir,outputname + '.hex') 34 | outfile = open(outfilepath, 'w') 35 | 36 | 37 | lineno = 1 38 | while 1 : 39 | b = infile.read(1) 40 | if len(b) == 0 : 41 | break 42 | d, = struct.unpack('B', b) 43 | outfile.write(hex(d) + ',') 44 | if lineno % 20 == 0: 45 | outfile.write('\n') 46 | lineno = lineno + 1 47 | -------------------------------------------------------------------------------- /example_game/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12) 2 | 3 | project("example_game") 4 | 5 | OPTION(USE_WAYLAND_LINUX "use Wayland for Linux" OFF) 6 | OPTION(GEN_WAYLAND_HEADERS "using wayland-scanner" OFF) 7 | 8 | find_package(Vulkan REQUIRED) 9 | if(NOT Vulkan_FOUND) 10 | MESSAGE("ERROR: Vulkan not found") 11 | endif(NOT Vulkan_FOUND) 12 | set(Vulkan_LIBRARY) 13 | 14 | set(Wayland_client "") 15 | IF (NOT WIN32) 16 | if(USE_WAYLAND_LINUX) 17 | set(WAYLAND_INCLUDE_DIR "/usr/include/wayland") 18 | MESSAGE(STATUS " Wayland include path ${WAYLAND_INCLUDE_DIR}") 19 | include_directories(${WAYLAND_INCLUDE_DIR}) 20 | if(GEN_WAYLAND_HEADERS) 21 | find_program(PKG_CONFIG pkg-config) 22 | if (NOT PKG_CONFIG) 23 | MESSAGE(FATAL_ERROR "pkg-config binary not found") 24 | endif () 25 | find_program(WAYLAND_SCANNER wayland-scanner) 26 | if (NOT WAYLAND_SCANNER) 27 | MESSAGE(FATAL_ERROR "wayland-scanner binary not found") 28 | endif () 29 | if(PKG_CONFIG AND WAYLAND_SCANNER) 30 | set(Wayland_client "${CMAKE_BINARY_DIR}/xdg-shell-client-protocol.c") 31 | execute_process(COMMAND ${PKG_CONFIG} --variable=pkgdatadir wayland-protocols OUTPUT_VARIABLE protocol_dir OUTPUT_STRIP_TRAILING_WHITESPACE) 32 | execute_process(COMMAND ${WAYLAND_SCANNER} client-header ${protocol_dir}/stable/xdg-shell/xdg-shell.xml xdg-shell-client-protocol.h 33 | COMMAND ${WAYLAND_SCANNER} private-code ${protocol_dir}/stable/xdg-shell/xdg-shell.xml xdg-shell-client-protocol.c) 34 | include_directories(${CMAKE_BINARY_DIR}) 35 | endif () 36 | else () 37 | MESSAGE(STATUS "using wayland headers from wayland_xdg folder") 38 | set(Wayland_client "../wayland_xdg/xdg-shell-client-protocol.c") 39 | include_directories("../wayland_xdg") 40 | endif () 41 | endif () 42 | endif () 43 | 44 | if (Vulkan_FOUND) 45 | MESSAGE(STATUS " [Found Vulkan library]") 46 | MESSAGE(STATUS " Vulkan include directory:" ${Vulkan_INCLUDE_DIR}) 47 | FOREACH(item ${Vulkan_LIBRARIES}) 48 | MESSAGE(STATUS " using lib: " ${item}) 49 | ENDFOREACH() 50 | include_directories(${Vulkan_INCLUDE_DIR}) 51 | endif() 52 | 53 | set(SOURCES 54 | "main.c" 55 | "../vk_utils/vk_utils.c" 56 | "../vk_utils/vk_error_print.c" 57 | "../vk_utils/vk_render_helper.c" 58 | ${Wayland_client} 59 | ) 60 | 61 | add_executable( 62 | Vkexample_game 63 | ${SOURCES} 64 | ) 65 | 66 | if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") 67 | 68 | add_definitions(-DVK_USE_PLATFORM_WIN32_KHR -DYARIV_SHADER ) 69 | target_link_libraries(Vkexample_game ${Vulkan_LIBRARY}) 70 | elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") 71 | if(USE_WAYLAND_LINUX) 72 | add_definitions(-DVK_USE_PLATFORM_WAYLAND_KHR -DYARIV_SHADER -O2 -s -fdata-sections -ffunction-sections -Wl,--gc-sections) 73 | target_link_libraries(Vkexample_game m wayland-client ${Vulkan_LIBRARY}) 74 | else() 75 | add_definitions(-DVK_USE_PLATFORM_XCB_KHR -DYARIV_SHADER -O2 -s -fdata-sections -ffunction-sections -Wl,--gc-sections) 76 | target_link_libraries(Vkexample_game m xcb ${Vulkan_LIBRARY}) 77 | endif() 78 | else() 79 | message(WARNING "Unknown compiler '${CMAKE_C_COMPILER_ID}'!") 80 | endif() 81 | -------------------------------------------------------------------------------- /example_game/engine.h: -------------------------------------------------------------------------------- 1 | // Danil, 2020 Vulkan shader launcher, self https://github.com/danilw/vulkan-shader-launcher 2 | 3 | #include 4 | 5 | struct update_vals { 6 | float u_mouse[2]; 7 | float p_pos[200][2]; 8 | float p_time[200]; 9 | bool p_isl[200]; 10 | int p_id[200]; 11 | float FPS; 12 | float u_time; 13 | float obj_size[4][2]; 14 | float u_hpdata[4]; 15 | float u_valt[2]; 16 | float u_dataxx[4]; 17 | float ishit; 18 | }; 19 | 20 | bool m_left=false; 21 | bool m_right=false; 22 | bool m_left_c=false; 23 | bool m_right_c=false; 24 | 25 | static struct update_vals uniform_vals; //game data 26 | 27 | void init_game_vals(){ 28 | uniform_vals.u_hpdata[0]=0.; //7 29 | uniform_vals.u_hpdata[1]=0.; //6 30 | uniform_vals.u_hpdata[2]=0.; //6 31 | uniform_vals.u_dataxx[1]=-100; 32 | } 33 | 34 | //---------------------------- 35 | //objects 36 | #define background 0 37 | #define box 1 38 | #define character 2 39 | #define debug 3 40 | 41 | #define spawn 0 42 | #define walk 1 43 | #define att 2 44 | void init_size(){ 45 | uniform_vals.obj_size[background][0]=16./9.; 46 | uniform_vals.obj_size[background][1]=1.; 47 | uniform_vals.obj_size[debug][0]=0.3; 48 | uniform_vals.obj_size[debug][1]=0.3; 49 | uniform_vals.obj_size[box][0]=.5; 50 | uniform_vals.obj_size[box][1]=.5; 51 | uniform_vals.obj_size[character][0]=10.; 52 | uniform_vals.obj_size[character][1]=10.; 53 | } 54 | 55 | 56 | //particles 57 | 58 | void gen_pos(){ 59 | for(int i=0;i<200;i++){ 60 | uniform_vals.p_pos[i][0]=(float)i/200.; 61 | uniform_vals.p_pos[i][1]=(float)i/400.; 62 | uniform_vals.p_id[i]=box; 63 | uniform_vals.p_time[i]=0.; 64 | uniform_vals.p_isl[i]=false; 65 | } 66 | } 67 | 68 | void update_mouse(bool left, bool right){ 69 | m_left=left; 70 | m_right=right; 71 | } 72 | 73 | void update_time(float time){ 74 | uniform_vals.u_time=time; 75 | } 76 | 77 | static bool ehx=false; 78 | static bool ehx2=false; 79 | static float lspwn=0.; 80 | void update_pos(){ 81 | float mpi=3.1415926; 82 | float timerx=(uniform_vals.u_time-4.)/50.>0.?(uniform_vals.u_time-4.)/50.:0.; 83 | timerx=timerx>1.?1.:timerx; 84 | float tevx=1.-0.9*timerx; 85 | for (int i=0.;i<20;i++){ 86 | if(uniform_vals.p_isl[i]){ 87 | if(ehx2)if((uniform_vals.p_pos[i][0]<-0.67+0.06)&&(uniform_vals.p_pos[i][0]>-0.67-0.06))uniform_vals.p_isl[i]=false; 88 | if(ehx)if(uniform_vals.p_pos[i][1]>-0.3+0.42)uniform_vals.p_isl[i]=false; 89 | if(uniform_vals.p_pos[i][1]>-0.3+0.5){if(uniform_vals.p_pos[i][0]<-0.67+0.06) 90 | uniform_vals.p_pos[i][0]=-0.67+0.165*sin(-mpi/2.+(uniform_vals.u_time-uniform_vals.p_time[i])*(2.5)); 91 | else uniform_vals.p_pos[i][0]+=0.01; 92 | } 93 | else 94 | uniform_vals.p_pos[i][0]=-0.67+0.165*sin(-mpi/2.+(uniform_vals.u_time-uniform_vals.p_time[i])*2.5); 95 | if(uniform_vals.p_pos[i][1]<-0.3+0.5) 96 | uniform_vals.p_pos[i][1]=-0.04+0.26*sin(-mpi/2.+(uniform_vals.u_time-uniform_vals.p_time[i])*(.5+0.5*(1.-tevx))); 97 | 98 | if(uniform_vals.p_pos[i][0]>0.45){uniform_vals.p_isl[i]=false;uniform_vals.u_dataxx[1]=uniform_vals.u_time;uniform_vals.u_hpdata[0]+=1;if(uniform_vals.u_hpdata[0]>7.)uniform_vals.u_hpdata[0]=0.;} 99 | }else{ 100 | if((uniform_vals.u_time-4.>0.)&&(!ehx2)){ 101 | if((uniform_vals.u_time-4.)-lspwn>tevx*2.){ 102 | lspwn=(uniform_vals.u_time-4.); 103 | uniform_vals.p_isl[i]=true; 104 | uniform_vals.p_pos[i][0]=-0.67-0.165; 105 | uniform_vals.p_pos[i][1]=-0.04-0.26; 106 | uniform_vals.p_time[i]=uniform_vals.u_time; 107 | } 108 | } 109 | } 110 | } 111 | } 112 | 113 | static float cltime=0.; 114 | static float cltime2=-100.; 115 | 116 | void update_char_anim(){ 117 | update_pos(); 118 | uniform_vals.u_dataxx[0]=uniform_vals.u_time-cltime2; 119 | float itm=(uniform_vals.u_time-4.>0.?uniform_vals.u_time-4.:0.); 120 | if(itm<=3.)m_right=m_left=false; 121 | if(itm<=1.){ 122 | uniform_vals.u_valt[0]=itm; 123 | uniform_vals.u_valt[1]=spawn; 124 | return; 125 | } 126 | if(itm<=3.){ 127 | uniform_vals.u_valt[0]=itm; 128 | uniform_vals.u_valt[1]=walk; 129 | return; 130 | } 131 | if(m_left&&(!m_left_c)){ 132 | m_left_c=true; 133 | m_left=false; 134 | uniform_vals.u_hpdata[1]=6.; 135 | cltime=uniform_vals.u_time; 136 | } 137 | if(m_right&&(!m_right_c)){ 138 | m_right_c=true; 139 | m_right=false; 140 | uniform_vals.u_hpdata[2]=6.; 141 | cltime2=uniform_vals.u_time; 142 | } 143 | ehx2=false; 144 | if(m_right_c){ 145 | uniform_vals.u_hpdata[2]=6.-(int)(((uniform_vals.u_time-ceil(cltime2)))*1.); 146 | if((uniform_vals.u_time-ceil(cltime2)>1.))ehx2=false; 147 | else ehx2=true; 148 | if((uniform_vals.u_time-ceil(cltime2)>6.)){ 149 | uniform_vals.u_hpdata[2]=0.; 150 | m_right_c=false; 151 | } 152 | } 153 | if(m_left_c){ 154 | bool tv=((uniform_vals.u_time-ceil(cltime))>0.); 155 | itm=((tv)&&(uniform_vals.u_time-ceil(cltime)<=9.))?uniform_vals.u_time-ceil(cltime):itm; 156 | uniform_vals.u_valt[0]=itm; 157 | uniform_vals.u_valt[1]=((tv)&&(itm<=9.))?att:walk; 158 | ehx=((tv)&&(itm<=3.8)&&(itm>=2.)); 159 | if((tv)&&(uniform_vals.u_time-ceil(cltime)>8.)){ 160 | uniform_vals.u_hpdata[1]=6.-(int)(((uniform_vals.u_time-ceil(cltime))-8.)*3.); 161 | if(uniform_vals.u_hpdata[1]<=0.){ 162 | uniform_vals.u_hpdata[1]=0.; 163 | ehx=false; 164 | m_left_c=false;} 165 | } 166 | return; 167 | } 168 | uniform_vals.u_valt[0]=itm; 169 | uniform_vals.u_valt[1]=walk; 170 | return; 171 | } 172 | 173 | void engine_init(){ 174 | init_size(); 175 | init_game_vals(); 176 | gen_pos(); 177 | } 178 | 179 | //---------------------------- 180 | -------------------------------------------------------------------------------- /example_game/shaders/build_shaders.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | glslangValidator -V100 src/main.vert -o spv/main.vert.spv 4 | glslangValidator -V100 src/main.frag -o spv/main.frag.spv 5 | -------------------------------------------------------------------------------- /example_game/shaders/build_shaders_yariv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #build yariv first and put yariv_pack binary to this folder 4 | 5 | python yariv_to_hex.py src/main.vert 6 | python yariv_to_hex.py src/main.frag 7 | -------------------------------------------------------------------------------- /example_game/shaders/spv/main.frag.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_game/shaders/spv/main.frag.spv -------------------------------------------------------------------------------- /example_game/shaders/spv/main.vert.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_game/shaders/spv/main.vert.spv -------------------------------------------------------------------------------- /example_game/shaders/src/bin/main.frag.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_game/shaders/src/bin/main.frag.spv -------------------------------------------------------------------------------- /example_game/shaders/src/bin/main.frag.yariv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_game/shaders/src/bin/main.frag.yariv -------------------------------------------------------------------------------- /example_game/shaders/src/bin/main.vert.hex: -------------------------------------------------------------------------------- 1 | 0x1,0x0,0x8a,0x80,0x20,0x21,0xfd,0x3,0x1,0xf8,0x3,0x3,0x0,0x47,0x4c,0x53,0x4c,0x2e,0x73,0x74, 2 | 0x64,0x2e,0x34,0x35,0x30,0x0,0x0,0x0,0x0,0xf9,0x3,0x0,0x1,0xf,0x4,0x0,0x4,0xed,0xc2,0xa5, 3 | 0xf3,0x6,0x0,0xd,0x12,0x1d,0xe,0x14,0x0,0xb,0x0,0xe,0x0,0x1,0xb,0x1,0xe,0x0,0x2,0xb, 4 | 0x3,0xe,0x0,0x3,0xb,0x4,0x8,0x0,0x2,0x7d,0xe,0x0,0x7d,0x16,0x0,0xfe,0x3,0x2,0x21,0x0, 5 | 0x3,0x2,0x16,0x6,0x20,0x17,0x7,0x6,0x4,0x15,0x8,0x20,0x0,0x2b,0x7,0x27,0x1,0x1c,0xa,0x6, 6 | 0x9,0x1e,0x4,0xb,0x7,0x6,0xa,0xa,0x20,0xc,0x3,0xb,0x3b,0xb,0x8,0x3,0x15,0xe,0x20,0x1, 7 | 0x2b,0xd,0x4,0x0,0x17,0x10,0x6,0x3,0x20,0x11,0x1,0x10,0x3b,0x10,0x6,0x1,0x27,0x5,0x4,0x0, 8 | 0x0,0x80,0x3f,0x20,0x19,0x3,0x7,0x17,0x1b,0x6,0x2,0x20,0x1c,0x3,0x1b,0x3b,0x1b,0x12,0x3,0x36, 9 | 0x1,0x31,0x0,0x3,0x0,0x2,0x3d,0xf,0x1c,0x1a,0x45,0x5,0x4,0x0,0x79,0x5,0x2,0x3,0x7a,0x5, 10 | 0x2,0x5,0x50,0x4,0x6,0x2,0x3,0x1,0x0,0x5,0x10,0x18,0x4,0xd,0xf,0x3e,0x0,0x3,0x10,0x18, 11 | 0x8,0xd,0xf,0x3d,0x6,0x2,0x0,0x3a,0x1a,0x2,0x0,0x1,0x3e,0x5,0x0,0x7e,0x38, -------------------------------------------------------------------------------- /example_game/shaders/src/bin/main.vert.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_game/shaders/src/bin/main.vert.spv -------------------------------------------------------------------------------- /example_game/shaders/src/bin/main.vert.yariv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_game/shaders/src/bin/main.vert.yariv -------------------------------------------------------------------------------- /example_game/shaders/src/main.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #extension GL_ARB_separate_shader_objects: enable 4 | #extension GL_ARB_shading_language_420pack: enable 5 | #extension GL_GOOGLE_include_directive : enable 6 | 7 | layout (location = 0) in vec2 frag_pos; 8 | 9 | layout (push_constant) uniform push_constants // <128bytes 10 | { 11 | vec4 u_Mouse; 12 | //vec4 u_Date; 13 | vec4 u_dataxx; 14 | vec4 hpdata; 15 | vec2 draw_id; 16 | vec2 draw_pos_g; 17 | vec2 u_valt; 18 | vec2 utmp; 19 | //bvec2 u_Mouse_lr; 20 | vec2 u_Resolution; 21 | bool u_debugdraw; 22 | int pCustom; 23 | float u_Time; 24 | //float u_TimeDelta; 25 | //int u_Frame; 26 | float FPS; 27 | } constants; 28 | 29 | vec3 iResolution=vec3(constants.u_Resolution,1.); 30 | float iTime=constants.u_Time; 31 | //float iTimeDelta=constants.u_TimeDelta; 32 | //int iFrame=constants.u_Frame; 33 | vec4 iMouse=constants.u_Mouse; 34 | //vec4 iDate=constants.u_Date; 35 | bool is_debugdraw=constants.u_debugdraw; 36 | bool is_pause=bool(constants.pCustom-(constants.pCustom/10)*10); 37 | bool main_image_srgb=bool((constants.pCustom/10)*10-(constants.pCustom/100)*100); 38 | vec2 draw_id=constants.draw_id; 39 | vec2 draw_pos_g=constants.draw_pos_g; 40 | float FPS=constants.FPS; 41 | vec4 hpdata=constants.hpdata; 42 | vec2 u_valt=constants.u_valt; 43 | vec4 u_dataxx=constants.u_dataxx; 44 | 45 | layout (location = 0) out vec4 out_color; 46 | 47 | #include "main_image.glsl" 48 | 49 | void main() 50 | { 51 | vec4 uFragColor=vec4(0.); 52 | vec2 fragCoord=gl_FragCoord.xy; 53 | fragCoord.y=iResolution.y-fragCoord.y; // shadertoy v(y)-flip main_image 54 | 55 | mainImage(uFragColor,fragCoord); 56 | out_color=uFragColor; 57 | if(main_image_srgb)out_color.rgb = ((exp2(out_color.rgb)-1.0)-out_color.rgb*0.693147)*3.258891; 58 | } 59 | -------------------------------------------------------------------------------- /example_game/shaders/src/main.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #extension GL_ARB_separate_shader_objects: enable 4 | #extension GL_ARB_shading_language_420pack: enable 5 | 6 | layout (location = 0) in vec3 in_pos; 7 | layout (location = 0) out vec2 frag_pos; 8 | 9 | void main() 10 | { 11 | gl_Position = vec4(in_pos.xyz, 1); 12 | frag_pos = gl_Position.xy; 13 | } 14 | -------------------------------------------------------------------------------- /example_game/shaders/yariv_pack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_game/shaders/yariv_pack -------------------------------------------------------------------------------- /example_game/shaders/yariv_to_hex.py: -------------------------------------------------------------------------------- 1 | import struct 2 | import os 3 | import sys 4 | import subprocess 5 | 6 | 7 | if len(sys.argv) != 2: 8 | print('Usage: python %s filename \n output is *.spv *.yariv and *.hex file \n' % sys.argv[0]) 9 | quit() 10 | 11 | inputfilepath = sys.argv[1] 12 | outputname = os.path.basename(inputfilepath) 13 | outdir = os.path.dirname(inputfilepath) 14 | ginfile = os.path.basename(inputfilepath) 15 | ooutdir = os.path.join(outdir,"bin"); 16 | 17 | spirvcompiler = 'glslangValidator' 18 | if os.name == 'nt': 19 | spirvcompiler += ".exe" 20 | 21 | yariv_pack = './yariv_pack' 22 | if os.name == 'nt': 23 | spirvcompiler += ".exe" 24 | 25 | if not os.path.isdir(ooutdir): 26 | os.mkdir(ooutdir, 0o0755 ); 27 | 28 | subprocess.call([spirvcompiler,'-V100',inputfilepath,'-o',os.path.join(ooutdir,ginfile) + '.spv']) 29 | 30 | subprocess.call([yariv_pack,os.path.join(ooutdir,ginfile) + '.spv']) 31 | 32 | infile = open(os.path.join(ooutdir,ginfile) + '.yariv', 'rb') 33 | outfilepath = os.path.join(ooutdir,outputname + '.hex') 34 | outfile = open(outfilepath, 'w') 35 | 36 | 37 | lineno = 1 38 | while 1 : 39 | b = infile.read(1) 40 | if len(b) == 0 : 41 | break 42 | d, = struct.unpack('B', b) 43 | outfile.write(hex(d) + ',') 44 | if lineno % 20 == 0: 45 | outfile.write('\n') 46 | lineno = lineno + 1 47 | -------------------------------------------------------------------------------- /example_images/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12) 2 | 3 | project("example_images") 4 | 5 | OPTION(USE_WAYLAND_LINUX "use Wayland for Linux" OFF) 6 | OPTION(GEN_WAYLAND_HEADERS "using wayland-scanner" OFF) 7 | 8 | find_package(Vulkan REQUIRED) 9 | if(NOT Vulkan_FOUND) 10 | MESSAGE("ERROR: Vulkan not found") 11 | endif(NOT Vulkan_FOUND) 12 | set(Vulkan_LIBRARY) 13 | 14 | set(Wayland_client "") 15 | IF (NOT WIN32) 16 | if(USE_WAYLAND_LINUX) 17 | set(WAYLAND_INCLUDE_DIR "/usr/include/wayland") 18 | MESSAGE(STATUS " Wayland include path ${WAYLAND_INCLUDE_DIR}") 19 | include_directories(${WAYLAND_INCLUDE_DIR}) 20 | if(GEN_WAYLAND_HEADERS) 21 | find_program(PKG_CONFIG pkg-config) 22 | if (NOT PKG_CONFIG) 23 | MESSAGE(FATAL_ERROR "pkg-config binary not found") 24 | endif () 25 | find_program(WAYLAND_SCANNER wayland-scanner) 26 | if (NOT WAYLAND_SCANNER) 27 | MESSAGE(FATAL_ERROR "wayland-scanner binary not found") 28 | endif () 29 | if(PKG_CONFIG AND WAYLAND_SCANNER) 30 | set(Wayland_client "${CMAKE_BINARY_DIR}/xdg-shell-client-protocol.c") 31 | execute_process(COMMAND ${PKG_CONFIG} --variable=pkgdatadir wayland-protocols OUTPUT_VARIABLE protocol_dir OUTPUT_STRIP_TRAILING_WHITESPACE) 32 | execute_process(COMMAND ${WAYLAND_SCANNER} client-header ${protocol_dir}/stable/xdg-shell/xdg-shell.xml xdg-shell-client-protocol.h 33 | COMMAND ${WAYLAND_SCANNER} private-code ${protocol_dir}/stable/xdg-shell/xdg-shell.xml xdg-shell-client-protocol.c) 34 | include_directories(${CMAKE_BINARY_DIR}) 35 | endif () 36 | else () 37 | MESSAGE(STATUS "using wayland headers from wayland_xdg folder") 38 | set(Wayland_client "../wayland_xdg/xdg-shell-client-protocol.c") 39 | include_directories("../wayland_xdg") 40 | endif () 41 | endif () 42 | endif () 43 | 44 | if (Vulkan_FOUND) 45 | MESSAGE(STATUS " [Found Vulkan library]") 46 | MESSAGE(STATUS " Vulkan include directory:" ${Vulkan_INCLUDE_DIR}) 47 | FOREACH(item ${Vulkan_LIBRARIES}) 48 | MESSAGE(STATUS " using lib: " ${item}) 49 | ENDFOREACH() 50 | include_directories(${Vulkan_INCLUDE_DIR}) 51 | endif() 52 | 53 | set(SOURCES 54 | "main.c" 55 | "../vk_utils/vk_utils.c" 56 | "../vk_utils/vk_error_print.c" 57 | "../vk_utils/vk_render_helper.c" 58 | ${Wayland_client} 59 | ) 60 | 61 | add_executable( 62 | Vkexample_img 63 | ${SOURCES} 64 | ) 65 | 66 | 67 | add_custom_command(TARGET Vkexample_img POST_BUILD 68 | COMMAND ${CMAKE_COMMAND} -E copy_directory 69 | ${CMAKE_SOURCE_DIR}/shaders/spv $/shaders/spv) 70 | add_custom_command(TARGET Vkexample_img POST_BUILD 71 | COMMAND ${CMAKE_COMMAND} -E copy_directory 72 | ${CMAKE_SOURCE_DIR}/textures $/textures) 73 | 74 | if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") 75 | 76 | add_definitions(-DVK_USE_PLATFORM_WIN32_KHR ) 77 | target_link_libraries(Vkexample_img ${Vulkan_LIBRARY}) 78 | elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") 79 | if(USE_WAYLAND_LINUX) 80 | add_definitions(-DVK_USE_PLATFORM_WAYLAND_KHR -O2 -s -fdata-sections -ffunction-sections -Wl,--gc-sections) 81 | target_link_libraries(Vkexample_img m wayland-client ${Vulkan_LIBRARY}) 82 | else() 83 | add_definitions(-DVK_USE_PLATFORM_XCB_KHR -O2 -s -fdata-sections -ffunction-sections -Wl,--gc-sections) 84 | target_link_libraries(Vkexample_img m xcb ${Vulkan_LIBRARY}) 85 | endif() 86 | else() 87 | message(WARNING "Unknown compiler '${CMAKE_C_COMPILER_ID}'!") 88 | endif() 89 | -------------------------------------------------------------------------------- /example_images/shaders/build_shaders.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | glslangValidator -V100 src/main.vert -o spv/main.vert.spv 4 | glslangValidator -V100 src/main.frag -o spv/main.frag.spv 5 | -------------------------------------------------------------------------------- /example_images/shaders/spv/main.frag.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_images/shaders/spv/main.frag.spv -------------------------------------------------------------------------------- /example_images/shaders/spv/main.vert.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_images/shaders/spv/main.vert.spv -------------------------------------------------------------------------------- /example_images/shaders/src/main.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #extension GL_ARB_separate_shader_objects: enable 4 | #extension GL_ARB_shading_language_420pack: enable 5 | #extension GL_GOOGLE_include_directive : enable 6 | 7 | layout (location = 0) in vec2 frag_pos; 8 | 9 | layout (set = 0, binding = 0) uniform sampler2D iChannel0; 10 | layout (set = 0, binding = 1) uniform sampler2D iChannel1; 11 | 12 | layout (push_constant) uniform push_constants 13 | { 14 | vec4 u_Mouse; 15 | vec4 u_Date; 16 | bvec2 u_Mouse_lr; //is mouse left[0], right[1] clicked 17 | vec2 u_Resolution; 18 | bool u_debugdraw; 19 | int pCustom; 20 | float u_Time; 21 | float u_TimeDelta; 22 | int u_Frame; 23 | } constants; 24 | 25 | vec3 iResolution=vec3(constants.u_Resolution,1.); 26 | float iTime=constants.u_Time; 27 | float iTimeDelta=constants.u_TimeDelta; 28 | int iFrame=constants.u_Frame; 29 | vec4 iMouse=constants.u_Mouse; 30 | vec4 iDate=constants.u_Date; 31 | bool is_debugdraw=constants.u_debugdraw; 32 | bool is_pause=bool(constants.pCustom-(constants.pCustom/10)*10); 33 | bool main_image_srgb=bool((constants.pCustom/10)*10-(constants.pCustom/100)*100); 34 | 35 | layout (location = 0) out vec4 out_color; 36 | 37 | #include "main_image.glsl" 38 | 39 | void main() 40 | { 41 | vec4 uFragColor=vec4(0.); 42 | vec2 fragCoord=gl_FragCoord.xy; 43 | fragCoord.y=iResolution.y-fragCoord.y; // shadertoy v(y)-flip main_image 44 | 45 | mainImage(uFragColor,fragCoord); 46 | out_color=uFragColor; 47 | if(main_image_srgb)out_color.rgb = ((exp2(out_color.rgb)-1.0)-out_color.rgb*0.693147)*3.258891; 48 | } 49 | -------------------------------------------------------------------------------- /example_images/shaders/src/main.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #extension GL_ARB_separate_shader_objects: enable 4 | #extension GL_ARB_shading_language_420pack: enable 5 | 6 | layout (location = 0) in vec3 in_pos; 7 | layout (location = 0) out vec2 frag_pos; 8 | 9 | void main() 10 | { 11 | gl_Position = vec4(in_pos.xyz, 1); 12 | frag_pos = gl_Position.xy; 13 | } 14 | -------------------------------------------------------------------------------- /example_images/shaders/src/main_image.glsl: -------------------------------------------------------------------------------- 1 | /*void mainImage( out vec4 fragColor, in vec2 fragCoord ) 2 | { 3 | vec2 uv = fragCoord/iResolution.xy; 4 | vec2 ouv=uv*2.; 5 | uv=fract(uv*2.); 6 | vec3 col=vec3(0.); 7 | if(ouv.x<1.) 8 | col = texture(iChannel0,uv).rgb; 9 | else 10 | col = texture(iChannel1,uv).rgb; 11 | fragColor = vec4(col,1.0); 12 | }*/ 13 | 14 | // using https://www.shadertoy.com/view/lsfGWn 15 | #define ANIMATE_NOISE 16 | 17 | float nrand( vec2 n ) { 18 | return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453); 19 | } 20 | 21 | vec2 rot2d( vec2 p, float a ) { 22 | vec2 sc = vec2(sin(a),cos(a)); 23 | return vec2( dot( p, vec2(sc.y, -sc.x) ), dot( p, sc.xy ) ); 24 | } 25 | 26 | const int NUM_TAPS = 27; 27 | const float rcp_maxdist = 1.0 / 4.22244; 28 | 29 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 30 | { 31 | 32 | vec2 uv = fragCoord.xy / iResolution.xy; 33 | uv.y = 1.0-uv.y; 34 | 35 | float max_siz; 36 | if ( iMouse.z > 0.5 ) 37 | max_siz = 32.0 * (1.0-iMouse.x / iResolution.x); // * (0.5+0.5*sin(iTime)); 38 | else 39 | max_siz = 32.0 * (0.5+0.5*sin(2.0*uv.x + iTime)); 40 | 41 | //fragColor = vec4( vec3(max_siz), 1.0 ); 42 | //return; 43 | 44 | //note: for samples-positions see 45 | // https://github.com/GPUOpen-Effects/ShadowFX/blob/master/amd_shadowfx/src/Shaders/ 46 | 47 | vec2 fTaps_Poisson[NUM_TAPS]; 48 | fTaps_Poisson[0] = rcp_maxdist * vec2( -0.8835609, 2.523391 ); 49 | fTaps_Poisson[1] = rcp_maxdist * vec2( -1.387375, 1.056318 ); 50 | fTaps_Poisson[2] = rcp_maxdist * vec2( -2.854452, 1.313645 ); 51 | fTaps_Poisson[3] = rcp_maxdist * vec2( 0.6326182, 1.14569 ); 52 | fTaps_Poisson[4] = rcp_maxdist * vec2( 1.331515, 3.637297 ); 53 | fTaps_Poisson[5] = rcp_maxdist * vec2( -2.175307, 3.885795 ); 54 | fTaps_Poisson[6] = rcp_maxdist * vec2( -0.5396664, 4.1938 ); 55 | fTaps_Poisson[7] = rcp_maxdist * vec2( -0.6708734, -0.36875 ); 56 | fTaps_Poisson[8] = rcp_maxdist * vec2( -2.083908, -0.6921188 ); 57 | fTaps_Poisson[9] = rcp_maxdist * vec2( -3.219028, 2.85465 ); 58 | fTaps_Poisson[10] = rcp_maxdist * vec2( -1.863933, -2.742254 ); 59 | fTaps_Poisson[11] = rcp_maxdist * vec2( -4.125739, -1.283028 ); 60 | fTaps_Poisson[12] = rcp_maxdist * vec2( -3.376766, -2.81844 ); 61 | fTaps_Poisson[13] = rcp_maxdist * vec2( -3.974553, 0.5459405 ); 62 | fTaps_Poisson[14] = rcp_maxdist * vec2( 3.102514, 1.717692 ); 63 | fTaps_Poisson[15] = rcp_maxdist * vec2( 2.951887, 3.186624 ); 64 | fTaps_Poisson[16] = rcp_maxdist * vec2( 1.33941, -0.166395 ); 65 | fTaps_Poisson[17] = rcp_maxdist * vec2( 2.814727, -0.3216669 ); 66 | fTaps_Poisson[18] = rcp_maxdist * vec2( 0.7786853, -2.235639 ); 67 | fTaps_Poisson[19] = rcp_maxdist * vec2( -0.7396695, -1.702466 ); 68 | fTaps_Poisson[20] = rcp_maxdist * vec2( 0.4621856, -3.62525 ); 69 | fTaps_Poisson[21] = rcp_maxdist * vec2( 4.181541, 0.5883132 ); 70 | fTaps_Poisson[22] = rcp_maxdist * vec2( 4.22244, -1.11029 ); 71 | fTaps_Poisson[23] = rcp_maxdist * vec2( 2.116917, -1.789436 ); 72 | fTaps_Poisson[24] = rcp_maxdist * vec2( 1.915774, -3.425885 ); 73 | fTaps_Poisson[25] = rcp_maxdist * vec2( 3.142686, -2.656329 ); 74 | fTaps_Poisson[26] = rcp_maxdist * vec2( -1.108632, -4.023479 ); 75 | 76 | 77 | if ( uv.y > 0.5 ) 78 | { 79 | vec2 ouv=uv*2.; 80 | uv=fract(uv*2.); 81 | vec3 col=vec3(0.); 82 | if(ouv.x<1.) 83 | fragColor = texture(iChannel0,uv, log2(max_siz) ); 84 | else 85 | fragColor = texture(iChannel1,uv, log2(max_siz) ); 86 | } 87 | else 88 | { 89 | vec4 sum = vec4(0); 90 | vec2 seed = uv; 91 | #if defined( ANIMATE_NOISE ) 92 | seed += fract( iTime ); 93 | #endif 94 | float rnd = 6.28 * nrand( seed ); 95 | 96 | vec4 basis = vec4( rot2d(vec2(1,0),rnd), rot2d(vec2(0,1),rnd) ); 97 | for (int i=0; i < NUM_TAPS; i++) 98 | { 99 | vec2 ofs = fTaps_Poisson[i]; ofs = vec2(dot(ofs,basis.xz),dot(ofs,basis.yw) ); 100 | //vec2 ofs = rot2d( fTaps_Poisson[i], rnd ); 101 | vec2 texcoord = uv + max_siz * ofs / iResolution.xy; 102 | vec2 ouv=texcoord*2.; 103 | texcoord=fract(texcoord*2.); 104 | vec3 col=vec3(0.); 105 | if(ouv.x<1.) 106 | sum += texture(iChannel0, texcoord, -10.0); 107 | else 108 | sum += texture(iChannel1, texcoord, -10.0); 109 | } 110 | 111 | fragColor = sum / vec4(NUM_TAPS); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /example_images/textures/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_images/textures/1.jpg -------------------------------------------------------------------------------- /example_images/textures/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_images/textures/2.png -------------------------------------------------------------------------------- /example_minimal/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12) 2 | 3 | project("example_minimal") 4 | 5 | OPTION(USE_WAYLAND_LINUX "use Wayland for Linux" OFF) 6 | OPTION(GEN_WAYLAND_HEADERS "using wayland-scanner" OFF) 7 | 8 | find_package(Vulkan REQUIRED) 9 | if(NOT Vulkan_FOUND) 10 | MESSAGE("ERROR: Vulkan not found") 11 | endif(NOT Vulkan_FOUND) 12 | set(Vulkan_LIBRARY) 13 | 14 | set(Wayland_client "") 15 | IF (NOT WIN32) 16 | if(USE_WAYLAND_LINUX) 17 | set(WAYLAND_INCLUDE_DIR "/usr/include/wayland") 18 | MESSAGE(STATUS " Wayland include path ${WAYLAND_INCLUDE_DIR}") 19 | include_directories(${WAYLAND_INCLUDE_DIR}) 20 | if(GEN_WAYLAND_HEADERS) 21 | find_program(PKG_CONFIG pkg-config) 22 | if (NOT PKG_CONFIG) 23 | MESSAGE(FATAL_ERROR "pkg-config binary not found") 24 | endif () 25 | find_program(WAYLAND_SCANNER wayland-scanner) 26 | if (NOT WAYLAND_SCANNER) 27 | MESSAGE(FATAL_ERROR "wayland-scanner binary not found") 28 | endif () 29 | if(PKG_CONFIG AND WAYLAND_SCANNER) 30 | set(Wayland_client "${CMAKE_BINARY_DIR}/xdg-shell-client-protocol.c") 31 | execute_process(COMMAND ${PKG_CONFIG} --variable=pkgdatadir wayland-protocols OUTPUT_VARIABLE protocol_dir OUTPUT_STRIP_TRAILING_WHITESPACE) 32 | execute_process(COMMAND ${WAYLAND_SCANNER} client-header ${protocol_dir}/stable/xdg-shell/xdg-shell.xml xdg-shell-client-protocol.h 33 | COMMAND ${WAYLAND_SCANNER} private-code ${protocol_dir}/stable/xdg-shell/xdg-shell.xml xdg-shell-client-protocol.c) 34 | include_directories(${CMAKE_BINARY_DIR}) 35 | endif () 36 | else () 37 | MESSAGE(STATUS "using wayland headers from wayland_xdg folder") 38 | set(Wayland_client "../wayland_xdg/xdg-shell-client-protocol.c") 39 | include_directories("../wayland_xdg") 40 | endif () 41 | endif () 42 | endif () 43 | 44 | if (Vulkan_FOUND) 45 | MESSAGE(STATUS " [Found Vulkan library]") 46 | MESSAGE(STATUS " Vulkan include directory:" ${Vulkan_INCLUDE_DIR}) 47 | FOREACH(item ${Vulkan_LIBRARIES}) 48 | MESSAGE(STATUS " using lib: " ${item}) 49 | ENDFOREACH() 50 | include_directories(${Vulkan_INCLUDE_DIR}) 51 | endif() 52 | 53 | set(SOURCES 54 | "main.c" 55 | "../vk_utils/vk_utils.c" 56 | "../vk_utils/vk_error_print.c" 57 | "../vk_utils/vk_render_helper.c" 58 | ${Wayland_client} 59 | ) 60 | 61 | add_executable( 62 | Vkexample 63 | ${SOURCES} 64 | ) 65 | 66 | 67 | add_custom_command(TARGET Vkexample POST_BUILD 68 | COMMAND ${CMAKE_COMMAND} -E copy_directory 69 | ${CMAKE_SOURCE_DIR}/shaders/spv $/shaders/spv) 70 | 71 | if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") 72 | 73 | add_definitions(-DVK_USE_PLATFORM_WIN32_KHR ) 74 | target_link_libraries(Vkexample ${Vulkan_LIBRARY}) 75 | elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") 76 | if(USE_WAYLAND_LINUX) 77 | add_definitions(-DVK_USE_PLATFORM_WAYLAND_KHR -O2 -s -fdata-sections -ffunction-sections -Wl,--gc-sections) 78 | target_link_libraries(Vkexample m wayland-client ${Vulkan_LIBRARY}) 79 | else() 80 | add_definitions(-DVK_USE_PLATFORM_XCB_KHR -O2 -s -fdata-sections -ffunction-sections -Wl,--gc-sections) 81 | target_link_libraries(Vkexample m xcb ${Vulkan_LIBRARY}) 82 | endif() 83 | else() 84 | message(WARNING "Unknown compiler '${CMAKE_C_COMPILER_ID}'!") 85 | endif() 86 | -------------------------------------------------------------------------------- /example_minimal/debug.h: -------------------------------------------------------------------------------- 1 | void print_surface_capabilities(struct vk_swapchain *swapchain) 2 | { 3 | const char *transforms[] = { 4 | "IDENTITY", 5 | "ROTATE_90", 6 | "ROTATE_180", 7 | "ROTATE_270", 8 | "HORIZONTAL_MIRROR", 9 | "HORIZONTAL_MIRROR_ROTATE_90", 10 | "HORIZONTAL_MIRROR_ROTATE_180", 11 | "HORIZONTAL_MIRROR_ROTATE_270", 12 | "INHERIT", 13 | }; 14 | const char *alphas[] = { 15 | "OPAQUE", 16 | "PRE_MULTIPLIED", 17 | "POST_MULTIPLIED", 18 | "INHERIT", 19 | }; 20 | const char *image_usages[] = { 21 | "TRANSFER_SRC", 22 | "TRANSFER_DST", 23 | "SAMPLED", 24 | "STORAGE", 25 | "COLOR_ATTACHMENT", 26 | "DEPTH_STENCIL_ATTACHMENT", 27 | "TRANSIENT_ATTACHMENT", 28 | "INPUT_ATTACHMENT", 29 | }; 30 | const char *present_modes[] = { 31 | "IMMEDIATE", 32 | "MAILBOX", 33 | "FIFO", 34 | "FIFO_RELAXED", 35 | }; 36 | VkSurfaceCapabilitiesKHR *caps = &swapchain->surface_caps; 37 | 38 | printf( "Surface capabilities:\n" 39 | " - image count in range [%u, %u]\n" 40 | " - image extent between (%u, %u) and (%u, %u) (current: (%u, %u))\n" 41 | " - stereoscopic possible? %s\n" 42 | " - supported transforms:\n", 43 | caps->minImageCount, 44 | caps->maxImageCount, 45 | caps->minImageExtent.width, 46 | caps->minImageExtent.height, 47 | caps->maxImageExtent.width, 48 | caps->maxImageExtent.height, 49 | caps->currentExtent.width, 50 | caps->currentExtent.height, 51 | caps->maxImageArrayLayers > 1?"Yes":"No"); 52 | 53 | for (size_t i = 0; i < sizeof transforms / sizeof *transforms; ++i) 54 | if ((caps->supportedTransforms & 1 << i)) 55 | printf(" * %s%s\n", transforms[i], caps->currentTransform == 1 << i?" (current)":""); 56 | if (caps->supportedTransforms >= 1 << sizeof transforms / sizeof *transforms) 57 | printf(" * ...%s\n", caps->currentTransform >= 1 << sizeof transforms / sizeof *transforms?" (current)":""); 58 | 59 | printf(" - supported alpha composition:\n"); 60 | for (size_t i = 0; i < sizeof alphas / sizeof *alphas; ++i) 61 | if ((caps->supportedCompositeAlpha & 1 << i)) 62 | printf(" * %s\n", alphas[i]); 63 | if (caps->supportedCompositeAlpha >= 1 << sizeof alphas / sizeof *alphas) 64 | printf(" * ...\n"); 65 | 66 | printf(" - supported image usages:\n"); 67 | for (size_t i = 0; i < sizeof image_usages / sizeof *image_usages; ++i) 68 | if ((caps->supportedUsageFlags & 1 << i)) 69 | printf(" * %s\n", image_usages[i]); 70 | if (caps->supportedUsageFlags >= 1 << sizeof image_usages / sizeof *image_usages) 71 | printf(" * ...\n"); 72 | printf(" - supported present modes:\n"); 73 | for (int i = 0; i < swapchain->present_modes_count; ++i) 74 | if (swapchain->present_modes[i] >= sizeof present_modes / sizeof *present_modes) 75 | printf(" * \n", swapchain->present_modes[i]); 76 | else 77 | printf(" * %s\n", present_modes[swapchain->present_modes[i]]); 78 | } 79 | 80 | void print_present_mode(VkPresentModeKHR present_mode) 81 | { 82 | printf("Using present mode: %s\n", present_mode == VK_PRESENT_MODE_IMMEDIATE_KHR ? "VK_PRESENT_MODE_IMMEDIATE_KHR" : 83 | present_mode == VK_PRESENT_MODE_MAILBOX_KHR ? "VK_PRESENT_MODE_MAILBOX_KHR" : 84 | present_mode == VK_PRESENT_MODE_FIFO_KHR ? "VK_PRESENT_MODE_FIFO_KHR" : 85 | present_mode == VK_PRESENT_MODE_FIFO_RELAXED_KHR ? "VK_PRESENT_MODE_FIFO_RELAXED_KHR" : "nan"); 86 | } 87 | 88 | void print_vkinfo(struct vk_physical_device **phy_dev, struct vk_swapchain **swapchains, uint32_t dev_count, VkPresentModeKHR present_mode){ 89 | for (uint32_t i = 0; i < dev_count; ++i) 90 | { 91 | struct vk_physical_device *dev = phy_dev[i]; 92 | VkPhysicalDeviceProperties *pr = &dev->properties; 93 | 94 | printf(" - %s: %s (id: 0x%04X) from vendor 0x%04X [driver version: 0x%04X, API version: 0x%04X]\n", 95 | vk_VkPhysicalDeviceType_string(pr->deviceType), pr->deviceName, 96 | pr->deviceID, pr->vendorID, pr->driverVersion, pr->apiVersion); 97 | if (dev->queue_families_incomplete) 98 | { 99 | printf(" (INFO)vkGetPhysicalDeviceQueueFamilyProperties return more then %u members.\n", dev->queue_family_count); 100 | } 101 | else 102 | printf(" The device supports the following %u queue famil%s:\n", dev->queue_family_count, dev->queue_family_count == 1?"y":"ies"); 103 | 104 | for (uint32_t j = 0; j < dev->queue_family_count; ++j) 105 | { 106 | VkQueueFamilyProperties *qf = &dev->queue_families[j]; 107 | 108 | printf(" * %u queue%s with the following capabilit%s:\n", qf->queueCount, qf->queueCount == 1?"":"s", 109 | qf->queueFlags && (qf->queueFlags & (qf->queueFlags - 1)) == 0?"y":"ies"); 110 | if (qf->queueFlags == 0) 111 | printf(" None\n"); 112 | if ((qf->queueFlags & VK_QUEUE_GRAPHICS_BIT)) 113 | printf(" Graphics\n"); 114 | if ((qf->queueFlags & VK_QUEUE_COMPUTE_BIT)) 115 | printf(" Compute\n"); 116 | if ((qf->queueFlags & VK_QUEUE_TRANSFER_BIT)) 117 | printf(" Transfer\n"); 118 | if ((qf->queueFlags & VK_QUEUE_SPARSE_BINDING_BIT)) 119 | printf(" Sparse binding\n"); 120 | } 121 | 122 | printf(" The device supports memories of the following types:\n"); 123 | for (uint32_t j = 0; j < dev->memories.memoryTypeCount; ++j) 124 | { 125 | printf(" *"); 126 | if (dev->memories.memoryTypes[j].propertyFlags == 0) 127 | printf(" "); 128 | if ((dev->memories.memoryTypes[j].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) 129 | printf(" device-local"); 130 | if ((dev->memories.memoryTypes[j].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) 131 | printf(" host-visible"); 132 | if ((dev->memories.memoryTypes[j].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) 133 | printf(" host-coherent"); 134 | if ((dev->memories.memoryTypes[j].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT)) 135 | printf(" host-cached"); 136 | if ((dev->memories.memoryTypes[j].propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)) 137 | printf(" lazy"); 138 | printf(": Available in Heap of size %luMB\n", dev->memories.memoryHeaps[dev->memories.memoryTypes[j].heapIndex].size / (1024 * 1024)); 139 | } 140 | print_surface_capabilities(swapchains[i]); 141 | print_present_mode(present_mode); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /example_minimal/shaders/build_shaders.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | glslangValidator -V100 src/main.vert -o spv/main.vert.spv 4 | glslangValidator -V100 src/main.frag -o spv/main.frag.spv 5 | -------------------------------------------------------------------------------- /example_minimal/shaders/spv/main.frag.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_minimal/shaders/spv/main.frag.spv -------------------------------------------------------------------------------- /example_minimal/shaders/spv/main.vert.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danilw/vulkan-shader-launcher/f0734161a285bcf4fb9bdbc9e69459f4431065bc/example_minimal/shaders/spv/main.vert.spv -------------------------------------------------------------------------------- /example_minimal/shaders/src/main.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #extension GL_ARB_separate_shader_objects: enable 4 | #extension GL_ARB_shading_language_420pack: enable 5 | #extension GL_GOOGLE_include_directive : enable 6 | 7 | layout (location = 0) in vec2 frag_pos; 8 | 9 | layout (push_constant) uniform push_constants 10 | { 11 | vec4 u_Mouse; 12 | vec4 u_Date; 13 | bvec2 u_Mouse_lr; //is mouse left[0], right[1] clicked 14 | vec2 u_Resolution; 15 | bool u_debugdraw; 16 | int pCustom; 17 | float u_Time; 18 | float u_TimeDelta; 19 | int u_Frame; 20 | } constants; 21 | 22 | vec3 iResolution=vec3(constants.u_Resolution,1.); 23 | float iTime=constants.u_Time; 24 | float iTimeDelta=constants.u_TimeDelta; 25 | int iFrame=constants.u_Frame; 26 | vec4 iMouse=constants.u_Mouse; 27 | vec4 iDate=constants.u_Date; 28 | bool is_debugdraw=constants.u_debugdraw; 29 | bool is_pause=bool(constants.pCustom-(constants.pCustom/10)*10); 30 | bool main_image_srgb=bool((constants.pCustom/10)*10-(constants.pCustom/100)*100); 31 | 32 | layout (location = 0) out vec4 out_color; 33 | 34 | #include "main_image.glsl" 35 | 36 | void main() 37 | { 38 | vec4 uFragColor=vec4(0.); 39 | vec2 fragCoord=gl_FragCoord.xy; 40 | fragCoord.y=iResolution.y-fragCoord.y; // shadertoy v(y)-flip main_image 41 | 42 | mainImage(uFragColor,fragCoord); 43 | out_color=uFragColor; 44 | if(main_image_srgb)out_color.rgb = ((exp2(out_color.rgb)-1.0)-out_color.rgb*0.693147)*3.258891; 45 | } 46 | -------------------------------------------------------------------------------- /example_minimal/shaders/src/main.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #extension GL_ARB_separate_shader_objects: enable 4 | #extension GL_ARB_shading_language_420pack: enable 5 | 6 | layout (location = 0) in vec3 in_pos; 7 | layout (location = 0) out vec2 frag_pos; 8 | 9 | void main() 10 | { 11 | gl_Position = vec4(in_pos.xyz, 1); 12 | frag_pos = gl_Position.xy; 13 | } 14 | -------------------------------------------------------------------------------- /example_minimal/shaders/src/main_image.glsl: -------------------------------------------------------------------------------- 1 | //base on my shader https://www.shadertoy.com/view/lttfR8 2 | 3 | // added debugdraw and pause effect, space pause, 1(keyboard) debugdraw 4 | // 2(key) enable/diable fps lock(nvidia bug) 5 | 6 | 7 | 8 | #define MD(a) mat2(cos(a), -sin(a), sin(a), cos(a)) 9 | 10 | #define PI (4.0 * atan(1.0)) 11 | #define TWO_PI PI*2. 12 | 13 | const vec3 green_ = vec3(0x58, 0x8b, 0x8c) / float(0xff); 14 | const vec3 green2 = vec3(0x22, 0x2e, 0x2a) / float(0xff); 15 | const vec3 white_ = vec3(0xe3, 0xe4, 0xdf) / float(0xff); 16 | const vec3 black_ = vec3(0x84, 0x82, 0x85) / float(0xff); 17 | 18 | vec3 background_col(vec2 p){ 19 | if(p.y>0.35) return smoothstep(0.55,0.4,p.y)*green_; 20 | return white_; 21 | } 22 | 23 | vec3 background_black(vec2 p){ 24 | return smoothstep(0.,-0.5,p.y)*black_;; 25 | } 26 | 27 | float xRandom(float x) { 28 | return fract(dot(sin(x * 591.32 ), cos(x * 391.32 ))); 29 | } 30 | 31 | //using http://www.iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm 32 | float sdLine( in vec2 p, in vec2 a, in vec2 b ) 33 | { 34 | vec2 pa = p-a, ba = b-a; 35 | float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); 36 | return length( pa - ba*h ); 37 | } 38 | 39 | float sdCircle( vec2 p, float r ) 40 | { 41 | return length(p) - r; 42 | } 43 | 44 | float sdBox( in vec2 p, in vec2 b ) 45 | { 46 | vec2 d = abs(p)-b; 47 | return length(max(d,vec2(0))) + min(max(d.x,d.y),0.0); 48 | } 49 | 50 | //layer 1 51 | float l1(vec2 p){ 52 | vec2 res = vec2(16./9.,1.); 53 | vec2 op=p; 54 | p=vec2((mod(floor(op.y/(1.))*.689+op.x,res.x/2.)-res.x/1.9),mod(op.y,1.)-1./2.); 55 | float d; 56 | d=smoothstep(0.005,0.01,sdLine(p,vec2(-res.x/2.,-0.5),vec2(-res.x/2.+0.2,0.5))); 57 | d=min(d,smoothstep(0.005,0.01,sdLine(p,vec2(-res.x/2.+0.3,-0.5),vec2(-res.x/2.+0.5,0.5)))); 58 | d=min(d,smoothstep(0.0,0.008,sdLine(p,vec2(-res.x/2.+0.325,-0.5),vec2(-res.x/2.+0.525,0.5)))); 59 | p=vec2(mod(op.x,res.x),mod(floor(op.x/(res.x))*0.25+op.y,0.4)-0.4*1.5); 60 | d=min(d,smoothstep(0.005,0.01,sdLine(p,vec2(-res.x,-0.),vec2(res.x,-0.5)))); 61 | return d; 62 | } 63 | 64 | //layer 2 65 | float l2(vec2 p){ 66 | vec2 op=p; 67 | float d; 68 | p.x=mod(p.x,0.5)-0.5/2.; 69 | p.y+=-0.051; 70 | d=smoothstep(0.025,0.03,sdLine(p,vec2(0.,0.3),vec2(-0.4,0.6))); 71 | d=min(d,smoothstep(0.015,0.02,sdLine(p,vec2(0.,0.3),vec2(0.4,0.6)))); 72 | d=min(d,smoothstep(0.015,0.02,sdLine(p,vec2(-0.02,0.34),vec2(0.38,0.64)))); 73 | p=op; 74 | d*=step(0.4,p.y); 75 | 76 | p.x=mod(p.x+0.35,0.7)-0.7/2.; 77 | d=max(d,smoothstep(0.01,0.005,sdCircle(p,0.28))); 78 | 79 | //p=op; 80 | 81 | d=min(d,smoothstep(0.005,0.01,sdCircle(p,0.123))); 82 | 83 | vec2 res = iResolution.xy / iResolution.y; 84 | //fan speed 85 | //p*=MD(mod(iTime*8.*(0.5-xRandom(floor((op.x+(0.35))/0.7))),TWO_PI)); 86 | p*=MD(mod(iTime*3.*((1.+0.2*floor(mod(((op.x+(0.35))/(0.7)),3.)))*.5- 87 | (1.-0.2*floor(mod(((op.x+(0.35))/(0.7)),5.)))* 88 | min(clamp(floor(mod(((op.x+(0.35*3.))/(0.7*3.)),2.))- 89 | floor(mod(((op.x+(0.35))/(0.7)),2.)),-1.,1.), 90 | floor(mod(((op.x+(0.35*3.))/(0.7*3.)),2.)))), 91 | TWO_PI)); 92 | float a = atan(p.x,p.y); 93 | float r = length(p); 94 | p = vec2(a/(TWO_PI),r); 95 | p = (1.0 * p) - vec2(0.5,0.42); 96 | p.xy=p.yx; 97 | p.y=mod(p.y,0.142)-0.142/2.; 98 | d=min(d,smoothstep(0.007,0.01, 99 | sdBox(p+vec2(0.142+0.068,0.), //circle radius 0.123+fan borders=0.142 100 | vec2(0.068,0.025)))); 101 | d=min(d,smoothstep(0.005,0.01,sdBox(p+vec2(0.242+0.068,0.),vec2(0.068,0.0125)))); 102 | 103 | return d; 104 | } 105 | 106 | //layer 3 107 | float l3(vec2 p){ 108 | float d; 109 | d=smoothstep(0.005,0.0,abs(p.y+0.38)); 110 | p.x=mod(p.x,0.025)-0.025/2.; 111 | if(p.y<-0.38) 112 | d=max(d,smoothstep(0.005,0.0,abs(p.x))); 113 | return d; 114 | } 115 | 116 | vec3 map_bg(vec2 p){ 117 | p.x+=iTime/15.; //scroll speed 118 | vec2 op=p; 119 | float d=l1(p); 120 | vec3 col; 121 | p=(op+1.)*MD(-.32); 122 | d=min(d,l1(p)); 123 | p=op; 124 | col=d*background_col(p); 125 | d=min(d,l2(p)); 126 | col=mix(col,background_black(p),1.-d); 127 | p=op; 128 | p.x+=iTime/60.; //scroll speed 2 129 | d=l3(p); 130 | col=mix(col,green2,d); 131 | return col; 132 | } 133 | 134 | void maindraw( out vec4 fragColor, in vec2 fragCoord ) 135 | { 136 | vec2 res = iResolution.xy / iResolution.y; 137 | vec2 uv = (fragCoord.xy) / iResolution.y - res/2.0; 138 | //uv*=2.0; 139 | vec3 col; 140 | 141 | col = map_bg(uv); 142 | 143 | // Output to screen 144 | fragColor = vec4(col,1.0); 145 | } 146 | 147 | 148 | int PrintInt( in vec2 uv, in int value, const int maxDigits ); 149 | 150 | void debugdraw( out vec4 fragColor, in vec2 fragCoord ) 151 | { 152 | fragColor=vec4(0.); 153 | vec2 res=(iResolution.xy / iResolution.y); 154 | vec2 uv = (fragCoord.xy) / iResolution.y - res/2.0; 155 | vec2 ouv=uv; 156 | uv.x+=0.6; 157 | uv.y+=-0.3; 158 | 159 | int d=0; 160 | uv*=12.; 161 | d+=PrintInt(uv,int(iResolution.x),4); 162 | uv.y+=0.2*7.; 163 | d+=PrintInt(uv,int(iResolution.y),4); 164 | uv.y+=0.2*7.; 165 | d+=PrintInt(uv,int(iMouse.x),4); 166 | uv.y+=0.2*7.; 167 | d+=PrintInt(uv,int(iMouse.y),4); 168 | uv.y+=0.2*7.; 169 | d+=PrintInt(uv,(int(iMouse.z)<0?9000+abs(int(iMouse.z)):int(iMouse.z)),4); 170 | uv.y+=0.2*7.; 171 | d+=PrintInt(uv,(int(iMouse.w)<0?9000+abs(int(iMouse.w)):int(iMouse.w)),4); 172 | uv.y+=0.2*7.; 173 | 174 | uv=ouv; 175 | uv.x+=0.2; 176 | uv.y+=-0.3; 177 | 178 | uv*=12.; 179 | d+=PrintInt(uv,int(iDate.x),4); 180 | uv.y+=0.2*7.; 181 | d+=PrintInt(uv,int(iDate.y),4); 182 | uv.y+=0.2*7.; 183 | d+=PrintInt(uv,int(iDate.z),4); 184 | uv.y+=0.2*7.; 185 | d+=PrintInt(uv,int(iDate.w/3600.),4); 186 | uv.y+=0.2*7.; 187 | d+=PrintInt(uv,int(mod(iDate.w/60.,60.)),4); 188 | uv.y+=0.2*7.; 189 | d+=PrintInt(uv,int(mod(iDate.w,60.)),4); 190 | uv.y+=0.2*7.; 191 | fragColor=vec4(vec3(d),1.); 192 | 193 | uv=ouv; 194 | uv.x+=-0.2; 195 | uv.y+=-0.3; 196 | 197 | uv*=12.; 198 | d+=PrintInt(uv,iFrame,4); 199 | uv.y+=0.2*7.; 200 | d+=PrintInt(uv,int(iTime*10.),4); 201 | uv.y+=0.2*7.; 202 | d+=PrintInt(uv,int(1./iTimeDelta),4); 203 | uv.y+=0.2*7.; 204 | fragColor=vec4(vec3(d),1.); 205 | 206 | } 207 | 208 | 209 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 210 | { 211 | vec4 ocol=vec4(0.); 212 | maindraw(ocol,fragCoord); 213 | if(is_debugdraw){ 214 | vec4 tcol=vec4(0.); 215 | debugdraw(tcol,fragCoord); 216 | ocol=mix(ocol,tcol,tcol.r*0.85); 217 | } 218 | if(is_pause){ 219 | ocol=vec4(vec3(dot(ocol.rgb,vec3(1.))/3.),1.); 220 | ocol.r*=1.5; 221 | } 222 | fragColor=ocol; 223 | } 224 | 225 | //https://www.shadertoy.com/view/ldsyz4 226 | // The MIT License 227 | // Copyright © 2017 Inigo Quilez 228 | // Digit data by P_Malin (https://www.shadertoy.com/view/4sf3RN) 229 | const int[] font = int[](0x75557, 0x22222, 0x74717, 0x74747, 0x11574, 0x71747, 0x71757, 0x74444, 0x75757, 0x75747); 230 | const int[] powers = int[](1, 10, 100, 1000, 10000, 100000, 1000000); 231 | 232 | int PrintInt( in vec2 uv, in int value, const int maxDigits ) 233 | { 234 | if( abs(uv.y-0.5)<0.5 ) 235 | { 236 | int iu = int(floor(uv.x)); 237 | if( iu>=0 && iu> (p.x+p.y*4)) & 1; 243 | } 244 | } 245 | return 0; 246 | } 247 | -------------------------------------------------------------------------------- /os_utils/os_win_utils.h: -------------------------------------------------------------------------------- 1 | 2 | void process_msg(MSG *msg, bool *done){ 3 | static bool mouse_click[2]={false, false}; //click once control 4 | if (msg->message == WM_QUIT) 5 | { 6 | *done = true; 7 | } 8 | else { 9 | TranslateMessage(msg); 10 | DispatchMessage(msg); 11 | } 12 | if (msg->message == WM_KEYDOWN) { 13 | switch (msg->wParam) 14 | { 15 | case VK_SPACE: 16 | os_window.app_data.pause = !os_window.app_data.pause; 17 | break; 18 | case 0x31: // 1 19 | os_window.app_data.drawdebug = !os_window.app_data.drawdebug; 20 | break; 21 | case 0x32: // 2 22 | os_window.fps_lock = !os_window.fps_lock; 23 | break; 24 | default: break; 25 | } 26 | } 27 | 28 | if (msg->message == WM_MOUSEMOVE) { 29 | os_window.app_data.iMouse[0] = (int)LOWORD(msg->lParam); 30 | os_window.app_data.iMouse[1] = os_window.app_data.iResolution[1] - (int)HIWORD(msg->lParam); 31 | switch (msg->wParam) 32 | { 33 | case WM_LBUTTONDOWN:os_window.app_data.iMouse_click[0] = true; break; 34 | case WM_MBUTTONDOWN:break; 35 | case WM_RBUTTONDOWN:os_window.app_data.iMouse_click[1] = true; break; 36 | } 37 | switch (msg->wParam) 38 | { 39 | case WM_LBUTTONUP:os_window.app_data.iMouse_click[0] = false; break; 40 | case WM_MBUTTONUP:break; 41 | case WM_RBUTTONUP:os_window.app_data.iMouse_click[1] = false; break; 42 | } 43 | } 44 | else { 45 | 46 | switch (msg->message) 47 | { 48 | case WM_LBUTTONDOWN:os_window.app_data.iMouse_click[0] = true; break; 49 | case WM_MBUTTONDOWN:break; 50 | case WM_RBUTTONDOWN:os_window.app_data.iMouse_click[1] = true; break; 51 | } 52 | switch (msg->message) 53 | { 54 | case WM_LBUTTONUP:os_window.app_data.iMouse_click[0] = false; break; 55 | case WM_MBUTTONUP:break; 56 | case WM_RBUTTONUP:os_window.app_data.iMouse_click[1] = false; break; 57 | } 58 | } 59 | if(!os_window.app_data.iMouse_click[0]&&(!mouse_click[0])){ 60 | 61 | }else{ 62 | if(os_window.app_data.iMouse_click[0]&&(!mouse_click[0])){ 63 | mouse_click[0]=true; 64 | os_window.app_data.iMouse_lclick[0]=os_window.app_data.iMouse[0]; 65 | os_window.app_data.iMouse_lclick[1]=os_window.app_data.iMouse[1]; 66 | }else{ 67 | if(!os_window.app_data.iMouse_click[0]&&(mouse_click[0])){ 68 | mouse_click[0]=false; 69 | os_window.app_data.iMouse_lclick[0]=-abs(os_window.app_data.iMouse_lclick[0]); 70 | os_window.app_data.iMouse_lclick[1]=-abs(os_window.app_data.iMouse_lclick[1]); 71 | } 72 | } 73 | } 74 | if(!os_window.app_data.iMouse_click[1]&&(!mouse_click[1])){ 75 | 76 | }else{ 77 | if(os_window.app_data.iMouse_click[1]&&(!mouse_click[1])){ 78 | mouse_click[1]=true; 79 | os_window.app_data.iMouse_rclick[0]=os_window.app_data.iMouse[0]; 80 | os_window.app_data.iMouse_rclick[1]=os_window.app_data.iMouse[1]; 81 | }else{ 82 | if(!os_window.app_data.iMouse_click[1]&&(mouse_click[1])){ 83 | mouse_click[1]=false; 84 | os_window.app_data.iMouse_rclick[0]=-abs(os_window.app_data.iMouse_rclick[0]); 85 | os_window.app_data.iMouse_rclick[1]=-abs(os_window.app_data.iMouse_rclick[1]); 86 | } 87 | } 88 | } 89 | 90 | } 91 | 92 | LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 93 | switch (uMsg) { 94 | case WM_CLOSE: 95 | PostQuitMessage(0); 96 | break; 97 | case WM_PAINT: 98 | if((!os_window.is_minimized)&&(!os_window.resize_event)){ 99 | if(!os_window.app_data.quit){ 100 | os_window.app_data.quit=!render_loop_draw(&phy_dev, &dev, &swapchain, &os_window); 101 | } 102 | else PostQuitMessage(0); 103 | }else{ 104 | if((!os_window.is_minimized)&&os_window.resize_event){ 105 | on_window_resize(&phy_dev, &dev, &essentials, &swapchain, &render_data, &os_window); //execute draw or resize per frame, not together 106 | } 107 | } 108 | 109 | if(os_window.is_minimized){ //I do not delete everything on minimize, only stop rendering 110 | sleep_ms(10); 111 | } 112 | break; 113 | case WM_GETMINMAXINFO: 114 | ((MINMAXINFO *)lParam)->ptMinTrackSize = os_window.minsize; 115 | return 0; 116 | case WM_SIZE: 117 | if (wParam != SIZE_MINIMIZED) { 118 | int tsize[2]={0}; 119 | tsize[0] = lParam & 0xffff; 120 | tsize[1] = (lParam & 0xffff0000) >> 16; 121 | os_window.is_minimized = false; 122 | if((tsize[0]!=os_window.app_data.iResolution[0])||(tsize[1]!=os_window.app_data.iResolution[1])){ 123 | os_window.app_data.iResolution[0]=tsize[0]; 124 | os_window.app_data.iResolution[1]=tsize[1]; 125 | if((os_window.app_data.iResolution[0]==0)||(os_window.app_data.iResolution[1]==0)){ 126 | os_window.is_minimized = true; 127 | }else{ 128 | os_window.resize_event=true; 129 | } 130 | } 131 | } 132 | else{ 133 | if (wParam == SIZE_MINIMIZED){ 134 | os_window.is_minimized = true; 135 | } 136 | } 137 | break; 138 | default: 139 | break; 140 | } 141 | return (DefWindowProc(hWnd, uMsg, wParam, lParam)); 142 | } 143 | 144 | static void app_create_window(struct app_os_window *os_window) { 145 | WNDCLASSEX win_class; 146 | 147 | win_class.cbSize = sizeof(WNDCLASSEX); 148 | win_class.style = CS_HREDRAW | CS_VREDRAW; 149 | win_class.lpfnWndProc = WndProc; 150 | win_class.cbClsExtra = 0; 151 | win_class.cbWndExtra = 0; 152 | win_class.hInstance = os_window->connection; 153 | win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION); 154 | win_class.hCursor = LoadCursor(NULL, IDC_ARROW); 155 | win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 156 | win_class.lpszMenuName = NULL; 157 | win_class.lpszClassName = os_window->name; 158 | win_class.hIconSm = LoadIcon(NULL, IDI_WINLOGO); 159 | if (!RegisterClassEx(&win_class)) { 160 | printf("Unexpected error trying to start the application!\n"); 161 | fflush(stdout); 162 | exit(1); 163 | } 164 | RECT wr = { 0, 0, os_window->app_data.iResolution[0], os_window->app_data.iResolution[1] }; 165 | AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); 166 | os_window->window = CreateWindowEx(0, 167 | os_window->name, // class name 168 | os_window->name, // app name 169 | WS_OVERLAPPEDWINDOW | // window style 170 | WS_VISIBLE | WS_SYSMENU, 171 | 100, 100, // x/y coords 172 | wr.right - wr.left, // width 173 | wr.bottom - wr.top, // height 174 | NULL, // handle to parent 175 | NULL, // handle to menu 176 | os_window->connection, // hInstance 177 | NULL); // no extra parameters 178 | if (!os_window->window) { 179 | printf("Cannot create a window in which to draw!\n"); 180 | fflush(stdout); 181 | exit(1); 182 | } 183 | os_window->minsize.x = GetSystemMetrics(SM_CXMINTRACK); 184 | os_window->minsize.y = GetSystemMetrics(SM_CYMINTRACK) + 1; 185 | } 186 | 187 | #include 188 | static void SetStdOutToNewConsole() 189 | { 190 | static bool once=false; 191 | if(once)return; 192 | once=true; 193 | AllocConsole(); 194 | HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); 195 | int fileDescriptor = _open_osfhandle((intptr_t)consoleHandle, _A_SYSTEM); 196 | FILE *fp = _fdopen( fileDescriptor, "w" ); 197 | *stdout = *fp; 198 | setvbuf( stdout, NULL, _IONBF, 0 ); 199 | SetConsoleTitle((LPCSTR)"Debug Output"); 200 | CONSOLE_SCREEN_BUFFER_INFO csbi; 201 | if ( GetConsoleScreenBufferInfo(consoleHandle, &csbi) ) 202 | { 203 | COORD bufferSize; 204 | bufferSize.X = csbi.dwSize.X; 205 | bufferSize.Y = 9999; 206 | SetConsoleScreenBufferSize(consoleHandle, bufferSize); 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /os_utils/utils.h: -------------------------------------------------------------------------------- 1 | 2 | struct my_time_struct{ 3 | int msec; 4 | int sec; 5 | int min; 6 | int hour; 7 | int day; 8 | int month; 9 | int year; 10 | }; 11 | 12 | #if defined(_WIN32) 13 | 14 | #include 15 | #define CLOCK_MONOTONIC_RAW 0 16 | #define BILLION (1E9) 17 | 18 | int clock_gettime(int dummy, struct timespec *ct) 19 | { 20 | static BOOL g_first_time = 1; 21 | static LARGE_INTEGER g_counts_per_sec; 22 | LARGE_INTEGER count; 23 | if (g_first_time) 24 | { 25 | g_first_time = 0; 26 | if (0 == QueryPerformanceFrequency(&g_counts_per_sec)) 27 | { 28 | g_counts_per_sec.QuadPart = 0; 29 | } 30 | } 31 | if ((NULL == ct) || (g_counts_per_sec.QuadPart <= 0) || 32 | (0 == QueryPerformanceCounter(&count))) 33 | { 34 | return -1; 35 | } 36 | ct->tv_sec = count.QuadPart / g_counts_per_sec.QuadPart; 37 | ct->tv_nsec = ((count.QuadPart % g_counts_per_sec.QuadPart) * BILLION) / g_counts_per_sec.QuadPart; 38 | 39 | return 0; 40 | } 41 | 42 | void get_local_time(struct my_time_struct *my_time){ 43 | SYSTEMTIME lt = {0}; 44 | GetLocalTime(<); 45 | my_time->msec=lt.wMilliseconds; 46 | my_time->sec=lt.wSecond; 47 | my_time->min=lt.wMinute; 48 | my_time->hour=lt.wHour; 49 | my_time->day=lt.wDay; 50 | my_time->month=lt.wMonth; 51 | my_time->year=lt.wYear; 52 | } 53 | 54 | 55 | #else 56 | 57 | #include 58 | 59 | void get_local_time(struct my_time_struct *my_time){ 60 | struct timeval te; 61 | gettimeofday(&te, NULL); 62 | time_t T= time(NULL); 63 | struct tm tm = *localtime(&T); 64 | long long milliseconds = te.tv_sec*1000LL + te.tv_usec/1000; 65 | my_time->msec=(int)(milliseconds%(1000)); 66 | my_time->sec=tm.tm_sec; 67 | my_time->min=tm.tm_min; 68 | my_time->hour=tm.tm_hour; 69 | my_time->day=tm.tm_mday; 70 | my_time->month=tm.tm_mon+1; 71 | my_time->year=tm.tm_year+1900; 72 | return; 73 | } 74 | 75 | #endif 76 | 77 | double get_time_ticks(){ 78 | struct timespec ts; 79 | clock_gettime(CLOCK_MONOTONIC_RAW, &ts); 80 | double ticks = (ts.tv_sec * 1000) + (ts.tv_nsec) / 1000000.0; 81 | return ticks; 82 | } 83 | 84 | //return total time of pause pressed 85 | float pres_pause(bool pause){ 86 | static bool lpause=false; 87 | static float pause_time=0; 88 | static double before_time=0; 89 | double now_time = get_time_ticks(); 90 | if(pause&&(!lpause)){ 91 | lpause=true; 92 | before_time=now_time; 93 | } 94 | else{ 95 | if(!pause&&(lpause)){ 96 | lpause=false; 97 | pause_time+=(float)(now_time-before_time)/1000.; 98 | } 99 | } 100 | return pause_time; 101 | } 102 | 103 | float update_fps_delta(){ 104 | static double before_time=0; 105 | if((int)before_time==0)before_time=get_time_ticks(); 106 | 107 | double now_time = get_time_ticks(); 108 | 109 | if ((long)before_time==(long)now_time) { //this happend on IMMEDIATE and MAILBOX 110 | return 1.0/9999.0; 111 | } 112 | double tdelta=(now_time-before_time); 113 | if(tdelta<=0)tdelta=1; 114 | float delta=(float)tdelta/1000.0; 115 | if(delta>1){ 116 | delta=1; 117 | } 118 | if(delta<=0){ 119 | delta=1.0/9999.0; 120 | } 121 | before_time=now_time; 122 | return delta; 123 | } 124 | 125 | // cross-platform sleep function 126 | void sleep_ms(int milliseconds) 127 | { 128 | #ifdef WIN32 129 | Sleep(milliseconds); 130 | #else 131 | struct timespec ts; 132 | ts.tv_sec = milliseconds / 1000; 133 | ts.tv_nsec = (milliseconds % 1000) * 1000000; 134 | nanosleep(&ts, NULL); 135 | #endif 136 | } 137 | 138 | void FPS_LOCK(int fps){ 139 | static double before_time=0; 140 | if(before_time==0)before_time=get_time_ticks(); 141 | double now_time=get_time_ticks(); 142 | if(before_time==now_time)return; 143 | if(fps<=0)fps=1; 144 | double wdelta=((double)(1.0/(double)fps)*(double)1000.0); 145 | double tdelta=(now_time-before_time); 146 | if(tdelta<=0)tdelta=1; 147 | double rdelta=wdelta-tdelta; 148 | if(rdelta<=0){ 149 | before_time=now_time; 150 | return; 151 | } 152 | sleep_ms((int)rdelta); 153 | before_time=get_time_ticks(); 154 | 155 | return; 156 | 157 | } 158 | 159 | 160 | -------------------------------------------------------------------------------- /os_utils/wayland_utils.h: -------------------------------------------------------------------------------- 1 | 2 | // from https://wayland-book.com/seat/example.html 3 | 4 | // used stable xdg-shell 5 | 6 | // Wayland does not have stable "decoration" support, xdg-decoration not supported 7 | // zxdg_toplevel_decoration_v1 is unstable 8 | // https://wayland-book.com/xdg-shell-in-depth/interactive.html 9 | 10 | #include 11 | 12 | static void xdg_wm_base_ping(void *data, struct xdg_wm_base *shell, uint32_t serial) 13 | { 14 | xdg_wm_base_pong(shell, serial); 15 | } 16 | 17 | static const struct xdg_wm_base_listener xdg_wm_base_listener = {xdg_wm_base_ping,}; 18 | 19 | static void seatCapabilities(struct wl_seat *seat, uint32_t caps, struct app_os_window *os_window); 20 | static void seatCapabilitiesCb(void *data, struct wl_seat *seat, uint32_t caps) 21 | { 22 | struct app_os_window *os_window = (struct app_os_window *) data; 23 | seatCapabilities(seat, caps, os_window); 24 | } 25 | 26 | void registryGlobal(struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version, struct app_os_window *os_window) 27 | { 28 | if (strcmp(interface, "wl_compositor") == 0) { 29 | os_window->compositor = (struct wl_compositor *) wl_registry_bind(registry, name, &wl_compositor_interface, 3); 30 | } 31 | else if (strcmp(interface, "xdg_wm_base") == 0) 32 | { 33 | os_window->shell = (struct xdg_wm_base *) wl_registry_bind(registry, name, &xdg_wm_base_interface, 1); 34 | xdg_wm_base_add_listener(os_window->shell, &xdg_wm_base_listener, NULL); 35 | } 36 | else if (strcmp(interface, "wl_seat") == 0) 37 | { 38 | os_window->seat = (struct wl_seat *) wl_registry_bind(registry, name, &wl_seat_interface, 1); 39 | static const struct wl_seat_listener seat_listener ={ seatCapabilitiesCb, }; 40 | wl_seat_add_listener(os_window->seat, &seat_listener, os_window); 41 | } 42 | } 43 | 44 | static void setSize(int width, int height, struct app_os_window *os_window) 45 | { 46 | if (width <= 0 || height <= 0){ 47 | os_window->is_minimized = true; 48 | }else 49 | { 50 | os_window->is_minimized = false; 51 | if ((os_window->app_data.iResolution[0] != width) || (os_window->app_data.iResolution[1] != height)) { 52 | os_window->is_minimized = false; 53 | os_window->app_data.iResolution[0] = width; 54 | os_window->app_data.iResolution[1] = height; 55 | if((os_window->app_data.iResolution[0]<=1)||(os_window->app_data.iResolution[1]<=1)){ 56 | os_window->is_minimized = true; 57 | } 58 | } 59 | } 60 | } 61 | 62 | static void xdg_surface_handle_configure(void *data, struct xdg_surface *surface, uint32_t serial) 63 | { 64 | struct app_os_window *os_window = (struct app_os_window *) data; 65 | xdg_surface_ack_configure(surface, serial); 66 | os_window->configured = true; 67 | } 68 | 69 | static const struct xdg_surface_listener xdg_surface_listener = {xdg_surface_handle_configure,}; 70 | 71 | static void xdg_toplevel_handle_configure(void *data, struct xdg_toplevel *toplevel, int32_t width, int32_t height, struct wl_array *states) 72 | { 73 | struct app_os_window *os_window = (struct app_os_window *) data; 74 | 75 | setSize(width, height, os_window); 76 | } 77 | 78 | static void xdg_toplevel_handle_close(void *data, struct xdg_toplevel *xdg_toplevel) 79 | { 80 | struct app_os_window *os_window = (struct app_os_window *) data; 81 | os_window->app_data.quit = true; 82 | } 83 | 84 | static const struct xdg_toplevel_listener xdg_toplevel_listener = {xdg_toplevel_handle_configure, xdg_toplevel_handle_close,}; 85 | 86 | static void registryGlobalCb(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) 87 | { 88 | struct app_os_window *os_window = (struct app_os_window *) data; 89 | registryGlobal(registry, name, interface, version, os_window); 90 | } 91 | 92 | static void pointerEnterCb(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy){} 93 | 94 | static void pointerLeaveCb(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface){} 95 | 96 | static void pointerMotion(struct wl_pointer *pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy, struct app_os_window *os_window) 97 | { 98 | os_window->app_data.iMouse[0]=wl_fixed_to_int(sx); 99 | os_window->app_data.iMouse[1]=os_window->app_data.iResolution[1] - wl_fixed_to_int(sy); 100 | } 101 | 102 | static void pointerMotionCb(void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy) 103 | { 104 | struct app_os_window *os_window = (struct app_os_window *) data; 105 | pointerMotion(pointer, time, sx, sy, os_window); 106 | } 107 | 108 | static void pointerButton(struct wl_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state, struct app_os_window *os_window) 109 | { 110 | switch (button) 111 | { 112 | case BTN_LEFT: 113 | os_window->app_data.iMouse_click[0] = state; 114 | if(state){ 115 | os_window->app_data.iMouse_lclick[0] = os_window->app_data.iMouse[0]; 116 | os_window->app_data.iMouse_lclick[1] = os_window->app_data.iResolution[1] - os_window->app_data.iMouse[1]; 117 | }else{ 118 | os_window->app_data.iMouse_lclick[0] = -os_window->app_data.iMouse_lclick[0]; 119 | os_window->app_data.iMouse_lclick[1] = -os_window->app_data.iMouse_lclick[1]; 120 | } 121 | break; 122 | case BTN_MIDDLE: 123 | break; 124 | case BTN_RIGHT: 125 | os_window->app_data.iMouse_click[1] = state; 126 | if(state){ 127 | os_window->app_data.iMouse_rclick[0] = os_window->app_data.iMouse[0]; 128 | os_window->app_data.iMouse_rclick[1] = os_window->app_data.iResolution[1] - os_window->app_data.iMouse[1]; 129 | }else{ 130 | os_window->app_data.iMouse_rclick[0] = -os_window->app_data.iMouse_rclick[0]; 131 | os_window->app_data.iMouse_rclick[1] = -os_window->app_data.iMouse_rclick[1]; 132 | } 133 | break; 134 | } 135 | } 136 | 137 | static void pointerButtonCb(void *data, struct wl_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) 138 | { 139 | struct app_os_window *os_window = (struct app_os_window *) data; 140 | pointerButton(pointer, serial, time, button, state, os_window); 141 | } 142 | 143 | static void pointerAxis(struct wl_pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t value, struct app_os_window *os_window) 144 | { 145 | float d = wl_fixed_to_double(value); 146 | switch (axis) 147 | { 148 | case REL_X: 149 | //printf("mouse wheel %f\n",d); 150 | break; 151 | } 152 | } 153 | 154 | static void pointerAxisCb(void *data, struct wl_pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t value) 155 | { 156 | struct app_os_window *os_window = (struct app_os_window *) data; 157 | pointerAxis(pointer, time, axis, value, os_window); 158 | } 159 | 160 | static void keyboardKeymapCb(void *data, struct wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size){} 161 | 162 | static void keyboardEnterCb(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys){} 163 | 164 | static void keyboardLeaveCb(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface){} 165 | 166 | static void keyboardKey(struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state, struct app_os_window *os_window) 167 | { 168 | switch (key) 169 | { 170 | case KEY_ESC: // Escape 171 | if(state)os_window->app_data.quit = true; 172 | break; 173 | case KEY_LEFT: // left arrow key 174 | break; 175 | case KEY_RIGHT: // right arrow key 176 | break; 177 | case KEY_SPACE: // space bar 178 | if(state)os_window->app_data.pause = !os_window->app_data.pause; 179 | break; 180 | case KEY_1: //1 181 | if(state)os_window->app_data.drawdebug = !os_window->app_data.drawdebug; 182 | break; 183 | case KEY_2: //2 184 | if(state)os_window->fps_lock = !os_window->fps_lock; 185 | break; 186 | case KEY_F: //Wayland resize event or just resize to resolution 187 | if(state){ 188 | os_window->resize_event = true; 189 | static bool switch_res=true; 190 | if(switch_res){ 191 | switch_res=false; 192 | os_window->app_data.iResolution[0]=1920; 193 | os_window->app_data.iResolution[1]=1080; 194 | }else{ 195 | switch_res=true; 196 | os_window->app_data.iResolution[0]=1280; 197 | os_window->app_data.iResolution[1]=720; 198 | } 199 | } 200 | break; 201 | } 202 | 203 | //if (state) 204 | //keyPressed(key); 205 | } 206 | 207 | static void keyboardKeyCb(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) 208 | { 209 | struct app_os_window *os_window = (struct app_os_window *) data; 210 | keyboardKey(keyboard, serial, time, key, state, os_window); 211 | } 212 | 213 | static void keyboardModifiersCb(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group){} 214 | 215 | static void seatCapabilities(struct wl_seat *seat, uint32_t caps, struct app_os_window *os_window) 216 | { 217 | if ((caps & WL_SEAT_CAPABILITY_POINTER) && !os_window->pointer) 218 | { 219 | os_window->pointer = wl_seat_get_pointer(seat); 220 | static const struct wl_pointer_listener pointer_listener ={ pointerEnterCb, pointerLeaveCb, pointerMotionCb, pointerButtonCb, pointerAxisCb, }; 221 | wl_pointer_add_listener(os_window->pointer, &pointer_listener, os_window); 222 | } 223 | else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && os_window->pointer) 224 | { 225 | wl_pointer_destroy(os_window->pointer); 226 | os_window->pointer = NULL; 227 | } 228 | 229 | if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !os_window->keyboard) 230 | { 231 | os_window->keyboard = wl_seat_get_keyboard(seat); 232 | static const struct wl_keyboard_listener keyboard_listener = { keyboardKeymapCb, keyboardEnterCb, keyboardLeaveCb, keyboardKeyCb, keyboardModifiersCb, }; 233 | wl_keyboard_add_listener(os_window->keyboard, &keyboard_listener, os_window); 234 | } 235 | else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && os_window->keyboard) 236 | { 237 | wl_keyboard_destroy(os_window->keyboard); 238 | os_window->keyboard = NULL; 239 | } 240 | } 241 | 242 | 243 | 244 | static void registryGlobalRemoveCb(void *data, struct wl_registry *registry, uint32_t name){} 245 | 246 | void initWaylandConnection(struct app_os_window *os_window) 247 | { 248 | os_window->display = wl_display_connect(NULL); 249 | if (!os_window->display) 250 | { 251 | printf("Could not connect to Wayland display!\n"); 252 | fflush(stdout); 253 | exit(1); 254 | } 255 | 256 | os_window->registry = wl_display_get_registry(os_window->display); 257 | if (!os_window->registry) 258 | { 259 | printf("Could not get Wayland registry!\n"); 260 | fflush(stdout); 261 | exit(1); 262 | } 263 | 264 | static const struct wl_registry_listener registry_listener = { registryGlobalCb, registryGlobalRemoveCb }; 265 | wl_registry_add_listener(os_window->registry, ®istry_listener, os_window); 266 | wl_display_dispatch(os_window->display); 267 | wl_display_roundtrip(os_window->display); 268 | if (!os_window->compositor || !os_window->shell || !os_window->seat) 269 | { 270 | printf("Could not bind Wayland protocols!\n"); 271 | fflush(stdout); 272 | exit(1); 273 | } 274 | } 275 | 276 | static void setupWindow(struct app_os_window *os_window) 277 | { 278 | os_window->surface = wl_compositor_create_surface(os_window->compositor); 279 | os_window->xdg_surface = xdg_wm_base_get_xdg_surface(os_window->shell, os_window->surface); 280 | 281 | xdg_surface_add_listener(os_window->xdg_surface, &xdg_surface_listener, os_window); 282 | os_window->xdg_toplevel = xdg_surface_get_toplevel(os_window->xdg_surface); 283 | xdg_toplevel_add_listener(os_window->xdg_toplevel, &xdg_toplevel_listener, os_window); 284 | 285 | xdg_toplevel_set_title(os_window->xdg_toplevel, os_window->name); 286 | wl_surface_commit(os_window->surface); 287 | } 288 | -------------------------------------------------------------------------------- /os_utils/xcb_x11_utils.h: -------------------------------------------------------------------------------- 1 | 2 | static void print_modifiers(uint32_t mask) 3 | { 4 | const char **mod, *mods[] = { 5 | "Shift", "Lock", "Ctrl", "Alt", 6 | "Mod2", "Mod3", "Mod4", "Mod5", 7 | "Button1", "Button2", "Button3", "Button4", "Button5" 8 | }; 9 | printf("Modifier mask: "); 10 | for (mod = mods; mask; mask >>= 1, mod++) 11 | if (mask & 1) 12 | printf("%s ", *mod); 13 | putchar('\n'); 14 | } 15 | 16 | static void app_handle_xcb_event(struct app_os_window *os_window, const xcb_generic_event_t *event) { 17 | uint8_t event_code = event->response_type & 0x7f; 18 | switch (event_code) { 19 | case XCB_EXPOSE: 20 | break; 21 | case XCB_CLIENT_MESSAGE: 22 | if ((*(xcb_client_message_event_t *)event).data.data32[0] == (*os_window->atom_wm_delete_window).atom) { 23 | os_window->app_data.quit = true; 24 | } 25 | break; 26 | case XCB_KEY_RELEASE: { 27 | const xcb_key_release_event_t *key = (const xcb_key_release_event_t *)event; 28 | switch (key->detail) { 29 | case 0x9: // Escape 30 | os_window->app_data.quit = true; 31 | break; 32 | case 0x71: // left arrow key 33 | break; 34 | case 0x72: // right arrow key 35 | break; 36 | case 0x41: // space bar 37 | os_window->app_data.pause = !os_window->app_data.pause; 38 | break; 39 | case 0xa: //1 40 | os_window->app_data.drawdebug = !os_window->app_data.drawdebug; 41 | break; 42 | case 0xb: //2 43 | os_window->fps_lock = !os_window->fps_lock; 44 | break; 45 | } 46 | } break; 47 | case XCB_MOTION_NOTIFY: { 48 | const xcb_motion_notify_event_t *ev = (const xcb_motion_notify_event_t *)event; 49 | //printf ("Mouse moved in window %ld, at coordinates (%d,%d)\n",ev->event, ev->event_x, ev->event_y); 50 | os_window->app_data.iMouse[0] = ev->event_x; 51 | os_window->app_data.iMouse[1] = os_window->app_data.iResolution[1] - ev->event_y; 52 | } break; 53 | case XCB_BUTTON_PRESS: { 54 | const xcb_button_press_event_t *ev = (const xcb_button_press_event_t *)event; 55 | //print_modifiers(ev->state); 56 | switch (ev->detail) { 57 | case 1: 58 | os_window->app_data.iMouse_click[0] = true; 59 | os_window->app_data.iMouse_lclick[0] = ev->event_x; 60 | os_window->app_data.iMouse_lclick[1] = os_window->app_data.iResolution[1] - ev->event_y; 61 | break; 62 | case 3: 63 | os_window->app_data.iMouse_click[1] = true; 64 | os_window->app_data.iMouse_rclick[0] = ev->event_x; 65 | os_window->app_data.iMouse_rclick[1] = os_window->app_data.iResolution[1] - ev->event_y; 66 | break; 67 | case 4: 68 | /*printf ("Wheel Button up in window %ld, at coordinates (%d,%d)\n", 69 | ev->event, ev->event_x, ev->event_y);*/ 70 | break; 71 | case 5: 72 | /*printf ("Wheel Button down in window %ld, at coordinates (%d,%d)\n", 73 | ev->event, ev->event_x, ev->event_y);*/ 74 | break; 75 | //default: 76 | /*printf ("Button %d pressed in window %ld, at coordinates (%d,%d)\n", 77 | ev->detail, ev->event, ev->event_x, ev->event_y);*/ 78 | } 79 | } break; 80 | case XCB_BUTTON_RELEASE: { 81 | const xcb_button_release_event_t *ev = (const xcb_button_release_event_t *)event; 82 | switch (ev->detail) { 83 | case 1: 84 | os_window->app_data.iMouse_click[0] = false; 85 | os_window->app_data.iMouse_lclick[0] = -os_window->app_data.iMouse_lclick[0]; 86 | os_window->app_data.iMouse_lclick[1] = -os_window->app_data.iMouse_lclick[1]; 87 | break; 88 | case 3: 89 | os_window->app_data.iMouse_click[1] = false; 90 | os_window->app_data.iMouse_rclick[0] = -os_window->app_data.iMouse_rclick[0]; 91 | os_window->app_data.iMouse_rclick[1] = -os_window->app_data.iMouse_rclick[1]; 92 | break; 93 | } 94 | /*print_modifiers(ev->state); 95 | 96 | printf ("Button %d released in window %ld, at coordinates (%d,%d)\n", 97 | ev->detail, ev->event, ev->event_x, ev->event_y);*/ 98 | } break; 99 | 100 | case XCB_CONFIGURE_NOTIFY: { 101 | const xcb_configure_notify_event_t *cfg = (const xcb_configure_notify_event_t *)event; 102 | if ((os_window->app_data.iResolution[0] != cfg->width) || (os_window->app_data.iResolution[1] != cfg->height)) { 103 | os_window->is_minimized = false; 104 | os_window->app_data.iResolution[0] = cfg->width; 105 | os_window->app_data.iResolution[1] = cfg->height; 106 | if((os_window->app_data.iResolution[0]==0)||(os_window->app_data.iResolution[1]==0)){ 107 | os_window->is_minimized = true; 108 | }else{ 109 | os_window->resize_event=true; 110 | } 111 | } 112 | } break; 113 | default: 114 | break; 115 | } 116 | } 117 | 118 | static void app_init_connection(struct app_os_window *os_window) { 119 | const xcb_setup_t *setup; 120 | xcb_screen_iterator_t iter; 121 | int scr; 122 | 123 | const char *display_envar = getenv("DISPLAY"); 124 | if (display_envar == NULL || display_envar[0] == '\0') { 125 | printf("Environment variable DISPLAY requires a valid value.\nExiting ...\n"); 126 | fflush(stdout); 127 | exit(1); 128 | } 129 | 130 | os_window->connection = xcb_connect(NULL, &scr); 131 | if (xcb_connection_has_error(os_window->connection) > 0) { 132 | printf("Cannot find a compatible Vulkan installable client driver (ICD).\nExiting ...\n"); 133 | fflush(stdout); 134 | exit(1); 135 | } 136 | 137 | setup = xcb_get_setup(os_window->connection); 138 | iter = xcb_setup_roots_iterator(setup); 139 | while (scr-- > 0) xcb_screen_next(&iter); 140 | 141 | os_window->screen = iter.data; 142 | } 143 | 144 | static void app_create_xcb_window(struct app_os_window *os_window) { 145 | uint32_t value_mask, value_list[32]; 146 | 147 | os_window->xcb_window = xcb_generate_id(os_window->connection); 148 | 149 | value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; 150 | value_list[0] = os_window->screen->black_pixel; 151 | 152 | value_list[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION | 153 | XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_STRUCTURE_NOTIFY; 154 | 155 | xcb_create_window(os_window->connection, XCB_COPY_FROM_PARENT, os_window->xcb_window, os_window->screen->root, 0, 0, os_window->app_data.iResolution[0], os_window->app_data.iResolution[1], 156 | 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, os_window->screen->root_visual, value_mask, value_list); 157 | 158 | xcb_intern_atom_cookie_t cookie = xcb_intern_atom(os_window->connection, 1, 12, "WM_PROTOCOLS"); 159 | xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(os_window->connection, cookie, 0); 160 | 161 | xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(os_window->connection, 0, 16, "WM_DELETE_WINDOW"); 162 | os_window->atom_wm_delete_window = xcb_intern_atom_reply(os_window->connection, cookie2, 0); 163 | 164 | xcb_change_property (os_window->connection, XCB_PROP_MODE_REPLACE, os_window->xcb_window, 165 | XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, 166 | strlen (os_window->name), os_window->name); 167 | 168 | xcb_change_property (os_window->connection, XCB_PROP_MODE_REPLACE, os_window->xcb_window, 169 | XCB_ATOM_WM_ICON_NAME, XCB_ATOM_STRING, 8, 170 | strlen(os_window->name), os_window->name); 171 | 172 | xcb_change_property(os_window->connection, XCB_PROP_MODE_REPLACE, os_window->xcb_window, (*reply).atom, 4, 32, 1, 173 | &(*os_window->atom_wm_delete_window).atom); 174 | free(reply); 175 | 176 | xcb_map_window(os_window->connection, os_window->xcb_window); 177 | 178 | const uint32_t coords[] = { 100, 100 }; 179 | xcb_configure_window(os_window->connection, os_window->xcb_window, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, coords); 180 | xcb_flush(os_window->connection); 181 | } 182 | -------------------------------------------------------------------------------- /use_validation_layer/VK_validation.cmd: -------------------------------------------------------------------------------- 1 | set VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation 2 | Vk_app.exe -------------------------------------------------------------------------------- /use_validation_layer/VK_validation.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ## this script DOES NOT WORK in the Ubuntu 21.04, copy paste these commands to the console 4 | ## and launch Vulkan app manually from console to have Validation layers work 5 | 6 | ## path example /home/user/vulkan_sdk/1.3.216.0 7 | VULKAN_SDK="/home/danil/Documents/git/vulkan_sdk/1.3.216.0" 8 | VK_APP=$1 9 | 10 | . $VULKAN_SDK"/setup-env.sh" 11 | 12 | export VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation 13 | ./$VK_APP 14 | -------------------------------------------------------------------------------- /use_validation_layer/vk_layer_settings.txt: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # from /config/vk_layer_settings.txt 3 | ################################################################################ 4 | 5 | # VK_LAYER_KHRONOS_validation Settings 6 | khronos_validation.debug_action = VK_DBG_LAYER_ACTION_LOG_MSG 7 | khronos_validation.report_flags = error,warn,perf 8 | khronos_validation.log_filename = vk_layer_log.txt 9 | -------------------------------------------------------------------------------- /vk_utils/vk_error_print.c: -------------------------------------------------------------------------------- 1 | 2 | // Danil, 2020 Vulkan shader launcher, self https://github.com/danilw/vulkan-shader-launcher 3 | // The MIT License 4 | 5 | #include "vk_error_print.h" 6 | 7 | void vk_error_data_set_vkresult(struct vk_error_data *error, VkResult vkresult, const char *file, unsigned int line) 8 | { 9 | if (vkresult == 0) 10 | return; 11 | 12 | if (error->type != VK_ERROR_SUCCESS && !(error->type == VK_ERROR_VKRESULT_WARNING && vkresult < 0)) 13 | return; 14 | 15 | *error = (struct vk_error_data){ 16 | .type = vkresult < 0?VK_ERROR_VKRESULT:VK_ERROR_VKRESULT_WARNING, 17 | .vkresult = vkresult, 18 | .file = file, 19 | .line = line, 20 | }; 21 | } 22 | 23 | void vk_error_data_set_errno(struct vk_error_data *error, int err_no, const char *file, unsigned int line) 24 | { 25 | if (err_no == 0) 26 | return; 27 | 28 | if (error->type != VK_ERROR_SUCCESS && error->type != VK_ERROR_VKRESULT_WARNING) 29 | return; 30 | 31 | *error = (struct vk_error_data){ 32 | .type = VK_ERROR_ERRNO, 33 | .err_no = err_no, 34 | .file = file, 35 | .line = line, 36 | }; 37 | } 38 | 39 | bool vk_error_data_merge(struct vk_error_data *error, struct vk_error_data *other) 40 | { 41 | if (other->type == VK_ERROR_SUCCESS) 42 | return false; 43 | 44 | if (error->type != VK_ERROR_SUCCESS && !(error->type == VK_ERROR_VKRESULT_WARNING && (other->type == VK_ERROR_VKRESULT || other->type == VK_ERROR_ERRNO))) 45 | return false; 46 | 47 | *error = *other; 48 | return true; 49 | } 50 | 51 | bool vk_error_is_success(struct vk_error *error) 52 | { 53 | return error->error.type == VK_ERROR_SUCCESS; 54 | } 55 | 56 | bool vk_error_is_warning(struct vk_error *error) 57 | { 58 | return error->error.type == VK_ERROR_VKRESULT_WARNING; 59 | } 60 | 61 | bool vk_error_is_error(struct vk_error *error) 62 | { 63 | return !vk_error_is_success(error) && !vk_error_is_warning(error); 64 | } 65 | 66 | static const char *VkResult_string(VkResult res) 67 | { 68 | switch (res) 69 | { 70 | case VK_SUCCESS: 71 | return "Success"; 72 | case VK_NOT_READY: 73 | return "Not ready"; 74 | case VK_TIMEOUT: 75 | return "Timeout"; 76 | case VK_EVENT_SET: 77 | return "Event set"; 78 | case VK_EVENT_RESET: 79 | return "Event reset"; 80 | case VK_INCOMPLETE: 81 | return "Incomplete"; 82 | case VK_ERROR_OUT_OF_HOST_MEMORY: 83 | return "Out of host memory"; 84 | case VK_ERROR_OUT_OF_DEVICE_MEMORY: 85 | return "Out of device memory"; 86 | case VK_ERROR_INITIALIZATION_FAILED: 87 | return "Initialization failed"; 88 | case VK_ERROR_DEVICE_LOST: 89 | return "Device lost"; 90 | case VK_ERROR_MEMORY_MAP_FAILED: 91 | return "Memory map failed"; 92 | case VK_ERROR_LAYER_NOT_PRESENT: 93 | return "Layer not present"; 94 | case VK_ERROR_EXTENSION_NOT_PRESENT: 95 | return "Extension not present"; 96 | case VK_ERROR_FEATURE_NOT_PRESENT: 97 | return "Feature not present"; 98 | case VK_ERROR_INCOMPATIBLE_DRIVER: 99 | return "Incompatible driver"; 100 | case VK_ERROR_TOO_MANY_OBJECTS: 101 | return "Too many objects"; 102 | case VK_ERROR_FORMAT_NOT_SUPPORTED: 103 | return "Format not supported"; 104 | case VK_ERROR_SURFACE_LOST_KHR: 105 | return "Surface lost"; 106 | case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: 107 | return "Native window is in use"; 108 | case VK_SUBOPTIMAL_KHR: 109 | return "Suboptimal"; 110 | case VK_ERROR_OUT_OF_DATE_KHR: 111 | return "Surface is out of date"; 112 | case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: 113 | return "Incompatible display"; 114 | case VK_ERROR_VALIDATION_FAILED_EXT: 115 | return "Validation failed"; 116 | default: 117 | return "Unrecognized error"; 118 | } 119 | } 120 | 121 | #if defined(VK_USE_PLATFORM_WIN32_KHR) 122 | void win_error(char *iout, char *iout2){ 123 | int msgboxID = MessageBox( 124 | NULL, 125 | (LPCSTR)iout, 126 | (LPCSTR)iout2, 127 | MB_ICONHAND | MB_DEFBUTTON1 128 | ); 129 | } 130 | 131 | #endif 132 | 133 | void print_error(FILE *fout, struct vk_error_data *error_data, const char *prefix) 134 | { 135 | #if defined(VK_USE_PLATFORM_WIN32_KHR) 136 | char iout[512]={0}; 137 | char iout2[512]={0}; 138 | 139 | fprintf(fout, "%s:%u: %s", error_data->file, error_data->line, prefix); 140 | sprintf(iout, "%s:%u: %s", error_data->file, error_data->line, prefix); 141 | switch (error_data->type) 142 | { 143 | case VK_ERROR_VKRESULT_WARNING: 144 | case VK_ERROR_VKRESULT: 145 | fprintf(fout, "%s (VkResult %d)\n", VkResult_string(error_data->vkresult), error_data->vkresult); 146 | sprintf(iout2, "%s (VkResult %d)\n", VkResult_string(error_data->vkresult), error_data->vkresult); 147 | break; 148 | case VK_ERROR_ERRNO: 149 | fprintf(fout, "%s (errno %d)\n", strerror(error_data->err_no), error_data->err_no); 150 | sprintf(iout2, "%s (errno %d)\n", strerror(error_data->err_no), error_data->err_no); 151 | break; 152 | default: 153 | fprintf(fout, "\n"); 154 | sprintf(iout2, "\n"); 155 | break; 156 | } 157 | win_error((char*)&iout2,(char*)&iout); 158 | 159 | #elif defined(VK_USE_PLATFORM_XCB_KHR)||defined(VK_USE_PLATFORM_WAYLAND_KHR) 160 | fprintf(fout, "%s:%u: %s", error_data->file, error_data->line, prefix); 161 | switch (error_data->type) 162 | { 163 | case VK_ERROR_VKRESULT_WARNING: 164 | case VK_ERROR_VKRESULT: 165 | fprintf(fout, "%s (VkResult %d)\n", VkResult_string(error_data->vkresult), error_data->vkresult); 166 | break; 167 | case VK_ERROR_ERRNO: 168 | fprintf(fout, "%s (errno %d)\n", strerror(error_data->err_no), error_data->err_no); 169 | break; 170 | default: 171 | fprintf(fout, "\n"); 172 | break; 173 | } 174 | #endif 175 | } 176 | 177 | void vk_error_fprintf(FILE *fout, struct vk_error *error, const char *fmt, ...) 178 | { 179 | if (error->error.type == VK_ERROR_SUCCESS) 180 | return; 181 | 182 | va_list args; 183 | va_start(args, fmt); 184 | vfprintf(fout, fmt, args); 185 | va_end(args); 186 | 187 | print_error(fout, &error->error, ""); 188 | if (error->sub_error.type != VK_ERROR_SUCCESS) 189 | print_error(fout, &error->sub_error, " Resulting from this error: "); 190 | } 191 | 192 | 193 | /* The following functions get a readable string out of the Vulkan standard enums */ 194 | const char *vk_VkPhysicalDeviceType_string(VkPhysicalDeviceType type) 195 | { 196 | switch (type) 197 | { 198 | case VK_PHYSICAL_DEVICE_TYPE_OTHER: 199 | return "Neither GPU nor CPU"; 200 | case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: 201 | return "Integrated GPU"; 202 | case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: 203 | return "Discrete GPU"; 204 | case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: 205 | return "Virtual GPU"; 206 | case VK_PHYSICAL_DEVICE_TYPE_CPU: 207 | return "CPU"; 208 | default: 209 | return "Unrecognized device type"; 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /vk_utils/vk_error_print.h: -------------------------------------------------------------------------------- 1 | 2 | // Danil, 2020 Vulkan shader launcher, self https://github.com/danilw/vulkan-shader-launcher 3 | // The MIT License 4 | 5 | #ifndef vk_utils_printf_H 6 | #define vk_utils_printf_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #ifdef _GNUC 16 | #define ATTR_UNUSED __attribute__((format(printf, 3, 4))) 17 | #else 18 | #define ATTR_UNUSED 19 | #endif 20 | 21 | enum vk_error_type 22 | { 23 | VK_ERROR_SUCCESS = 0, 24 | VK_ERROR_VKRESULT, 25 | VK_ERROR_VKRESULT_WARNING, /* VK_INCOMPLETE for example */ 26 | VK_ERROR_ERRNO, 27 | }; 28 | 29 | typedef struct vk_error_data 30 | { 31 | enum vk_error_type type; 32 | union { 33 | VkResult vkresult; 34 | int err_no; 35 | }; 36 | const char *file; 37 | unsigned int line; 38 | } vk_error_data; 39 | 40 | typedef struct vk_error 41 | { 42 | struct vk_error_data error; 43 | struct vk_error_data sub_error; /* 44 | * Used in cases where error is e.g. "VK_INCOMPLETE", and it is due to 45 | * another error. 46 | */ 47 | } vk_error; 48 | 49 | #define VK_ERROR_NONE (struct vk_error){ .error = { .type = VK_ERROR_SUCCESS,}, .sub_error = { .type = VK_ERROR_SUCCESS,}, } 50 | 51 | #define vk_error_set_vkresult(es, e) vk_error_data_set_vkresult(&(es)->error, (e), __FILE__, __LINE__) 52 | #define vk_error_set_errno(es, e) vk_error_data_set_errno (&(es)->error, (e), __FILE__, __LINE__) 53 | #define vk_error_sub_set_vkresult(es, e) vk_error_data_set_vkresult(&(es)->sub_error, (e), __FILE__, __LINE__) 54 | #define vk_error_sub_set_errno(es, e) vk_error_data_set_errno (&(es)->sub_error, (e), __FILE__, __LINE__) 55 | #define vk_error_merge(es, os) \ 56 | do { \ 57 | if (vk_error_data_merge(&(es)->error, &(os)->error)) \ 58 | (es)->sub_error = (os)->sub_error; \ 59 | } while (0) 60 | #define vk_error_sub_merge(es, os) vk_error_data_merge(&(es)->sub_error, &(os)->error) 61 | 62 | void vk_error_data_set_vkresult(struct vk_error_data *error, VkResult vkresult, const char *file, unsigned int line); 63 | void vk_error_data_set_errno(struct vk_error_data *error, int err_no, const char *file, unsigned int line); 64 | bool vk_error_data_merge(struct vk_error_data *error, struct vk_error_data *other); 65 | 66 | bool vk_error_is_success(struct vk_error *error); 67 | bool vk_error_is_warning(struct vk_error *error); 68 | bool vk_error_is_error(struct vk_error *error); 69 | #if defined(VK_USE_PLATFORM_WIN32_KHR) 70 | void win_error(char *iout, char *iout2); 71 | #endif 72 | #define vk_error_printf(es, ...) vk_error_fprintf(stdout, (es), __VA_ARGS__) 73 | void vk_error_fprintf(FILE *fout, struct vk_error *error, const char *fmt, ...) ATTR_UNUSED; 74 | 75 | 76 | const char *vk_VkPhysicalDeviceType_string(VkPhysicalDeviceType type); 77 | 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /vk_utils/vk_render_helper.c: -------------------------------------------------------------------------------- 1 | 2 | // Danil, 2020 Vulkan shader launcher, self https://github.com/danilw/vulkan-shader-launcher 3 | // The MIT License 4 | 5 | #include "vk_render_helper.h" 6 | 7 | int vk_render_get_essentials(struct vk_render_essentials *essentials, struct vk_physical_device *phy_dev, 8 | struct vk_device *dev, struct vk_swapchain *swapchain) 9 | { 10 | vk_error retval = VK_ERROR_NONE; 11 | VkResult res; 12 | 13 | essentials->images = vk_get_swapchain_images(dev, swapchain, &essentials->image_count); 14 | if (essentials->images == NULL) 15 | return -1; 16 | 17 | uint32_t *presentable_queues = NULL; 18 | uint32_t presentable_queue_count = 0; 19 | 20 | retval = vk_get_presentable_queues(phy_dev, dev, swapchain->surface, &presentable_queues, &presentable_queue_count); 21 | if (!vk_error_is_success(&retval) || presentable_queue_count == 0) 22 | { 23 | printf("No presentable queue families! What kind of graphics card is this!\n"); 24 | return -1; 25 | } 26 | 27 | essentials->present_queue = dev->command_pools[presentable_queues[0]].queues[0]; 28 | essentials->cmd_buffer = dev->command_pools[presentable_queues[0]].buffers[0]; 29 | free(presentable_queues); 30 | 31 | VkSemaphoreCreateInfo sem_info = { 32 | .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, 33 | }; 34 | 35 | res = vkCreateSemaphore(dev->device, &sem_info, NULL, &essentials->sem_post_acquire); 36 | vk_error_set_vkresult(&retval, res); 37 | if (res) 38 | { 39 | vk_error_printf(&retval, "Failed to create post-acquire semaphore\n"); 40 | return -1; 41 | } 42 | 43 | res = vkCreateSemaphore(dev->device, &sem_info, NULL, &essentials->sem_pre_submit); 44 | vk_error_set_vkresult(&retval, res); 45 | if (res) 46 | { 47 | vk_error_printf(&retval, "Failed to create pre-submit semaphore\n"); 48 | return -1; 49 | } 50 | 51 | VkFenceCreateInfo fence_info = { 52 | .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, 53 | }; 54 | 55 | res = vkCreateFence(dev->device, &fence_info, NULL, &essentials->exec_fence); 56 | vk_error_set_vkresult(&retval, res); 57 | if (res) 58 | { 59 | vk_error_printf(&retval, "Failed to create fence\n"); 60 | return -1; 61 | } 62 | 63 | essentials->first_render = true; 64 | 65 | return 0; 66 | } 67 | 68 | void vk_render_cleanup_essentials(struct vk_render_essentials *essentials, struct vk_device *dev) 69 | { 70 | vkDeviceWaitIdle(dev->device); 71 | 72 | vkDestroySemaphore(dev->device, essentials->sem_post_acquire, NULL); 73 | vkDestroySemaphore(dev->device, essentials->sem_pre_submit, NULL); 74 | vkDestroyFence(dev->device, essentials->exec_fence, NULL); 75 | free(essentials->images); 76 | } 77 | 78 | VkResult vk_render_start(struct vk_render_essentials *essentials, struct vk_device *dev, 79 | struct vk_swapchain *swapchain, VkImageLayout to_layout, uint32_t *image_index) 80 | { 81 | vk_error retval = VK_ERROR_NONE; 82 | VkResult res; 83 | 84 | res = vkAcquireNextImageKHR(dev->device, swapchain->swapchain, 1000000000, essentials->sem_post_acquire, NULL, image_index); 85 | vk_error_set_vkresult(&retval, res); 86 | if (res == VK_TIMEOUT) 87 | { 88 | printf("A whole second and no image. I give up.\n"); 89 | return res; 90 | } 91 | else if (res == VK_SUBOPTIMAL_KHR) { 92 | printf("presentation is suboptimal.\n"); 93 | } 94 | else if (res == VK_ERROR_OUT_OF_DATE_KHR) { 95 | // this is not error, this is resize event for AMD hardware 96 | return res; 97 | } 98 | else if (res < 0) 99 | { 100 | vk_error_printf(&retval, "Couldn't acquire image\n"); 101 | return res; 102 | } 103 | 104 | if (!essentials->first_render) 105 | { 106 | res = vkWaitForFences(dev->device, 1, &essentials->exec_fence, true, 1000000000); 107 | vk_error_set_vkresult(&retval, res); 108 | if (res) 109 | { 110 | vk_error_printf(&retval, "Wait for fence failed\n"); 111 | return res; 112 | } 113 | } 114 | essentials->first_render = false; 115 | 116 | vkResetCommandBuffer(essentials->cmd_buffer, 0); 117 | VkCommandBufferBeginInfo begin_info = { 118 | .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 119 | .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, 120 | }; 121 | res = vkBeginCommandBuffer(essentials->cmd_buffer, &begin_info); 122 | vk_error_set_vkresult(&retval, res); 123 | if (res) 124 | { 125 | vk_error_printf(&retval, "Couldn't even begin recording a command buffer\n"); 126 | return res; 127 | } 128 | 129 | VkImageMemoryBarrier image_barrier = { 130 | .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 131 | .srcAccessMask = VK_ACCESS_MEMORY_READ_BIT, 132 | .dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, 133 | .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, 134 | .newLayout = to_layout, 135 | .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, 136 | .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, 137 | .image = essentials->images[*image_index], 138 | .subresourceRange = { 139 | .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 140 | .baseMipLevel = 0, 141 | .levelCount = 1, 142 | .baseArrayLayer = 0, 143 | .layerCount = 1, 144 | }, 145 | }; 146 | 147 | vkCmdPipelineBarrier(essentials->cmd_buffer, 148 | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 149 | VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 150 | 0, 151 | 0, NULL, 152 | 0, NULL, 153 | 1, &image_barrier); 154 | 155 | return 0; 156 | } 157 | 158 | 159 | static vk_error fill_object(struct vk_device *dev, VkDeviceMemory to, void *from, size_t size, const char *object, const char *name) 160 | { 161 | void *mem = NULL; 162 | vk_error retval = VK_ERROR_NONE; 163 | VkResult res; 164 | 165 | res = vkMapMemory(dev->device, to, 0, size, 0, &mem); 166 | vk_error_set_vkresult(&retval, res); 167 | if (res) 168 | { 169 | vk_error_printf(&retval, "Failed to map memory of the %s %s\n", name, object); 170 | return retval; 171 | } 172 | 173 | memcpy(mem, from, size); 174 | 175 | vkUnmapMemory(dev->device, to); 176 | 177 | return retval; 178 | } 179 | 180 | vk_error vk_render_fill_buffer(struct vk_device *dev, struct vk_buffer *to, void *from, size_t size, const char *name) 181 | { 182 | return fill_object(dev, to->buffer_mem, from, size, "buffer", name); 183 | } 184 | 185 | vk_error vk_render_fill_image(struct vk_device *dev, struct vk_image *to, void *from, size_t size, const char *name) 186 | { 187 | return fill_object(dev, to->image_mem, from, size, "image", name); 188 | } 189 | 190 | static vk_error copy_object_start(struct vk_device *dev, struct vk_render_essentials *essentials, const char *object, const char *name) 191 | { 192 | vk_error retval = VK_ERROR_NONE; 193 | VkResult res; 194 | 195 | vkResetCommandBuffer(essentials->cmd_buffer, 0); 196 | VkCommandBufferBeginInfo begin_info = { 197 | .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 198 | .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, 199 | }; 200 | res = vkBeginCommandBuffer(essentials->cmd_buffer, &begin_info); 201 | vk_error_set_vkresult(&retval, res); 202 | if (res) 203 | vk_error_printf(&retval, "Couldn't begin recording a command buffer to copy the %s %s\n", name, object); 204 | 205 | return retval; 206 | } 207 | 208 | static vk_error copy_object_end(struct vk_device *dev, struct vk_render_essentials *essentials) 209 | { 210 | vk_error retval = VK_ERROR_NONE; 211 | VkResult res; 212 | 213 | vkEndCommandBuffer(essentials->cmd_buffer); 214 | 215 | res = vkResetFences(dev->device, 1, &essentials->exec_fence); 216 | vk_error_set_vkresult(&retval, res); 217 | if (res) 218 | { 219 | vk_error_printf(&retval, "Failed to reset fence\n"); 220 | return retval; 221 | } 222 | 223 | VkSubmitInfo submit_info = { 224 | .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, 225 | .commandBufferCount = 1, 226 | .pCommandBuffers = &essentials->cmd_buffer, 227 | }; 228 | 229 | vkQueueSubmit(essentials->present_queue, 1, &submit_info, essentials->exec_fence); 230 | res = vkWaitForFences(dev->device, 1, &essentials->exec_fence, true, 1000000000); 231 | vk_error_set_vkresult(&retval, res); 232 | 233 | return retval; 234 | } 235 | 236 | vk_error vk_render_copy_buffer(struct vk_device *dev, struct vk_render_essentials *essentials, 237 | struct vk_buffer *to, struct vk_buffer *from, size_t size, const char *name) 238 | { 239 | vk_error retval = VK_ERROR_NONE; 240 | 241 | retval = copy_object_start(dev, essentials, "buffer", name); 242 | if (!vk_error_is_success(&retval)) 243 | return retval; 244 | 245 | VkBufferCopy copy_region = { 246 | .srcOffset = 0, 247 | .dstOffset = 0, 248 | .size = size, 249 | }; 250 | vkCmdCopyBuffer(essentials->cmd_buffer, from->buffer, to->buffer, 1, ©_region); 251 | 252 | return copy_object_end(dev, essentials); 253 | } 254 | 255 | vk_error vk_render_copy_image(struct vk_device *dev, struct vk_render_essentials *essentials, 256 | struct vk_image *to, VkImageLayout to_layout, struct vk_image *from, VkImageLayout from_layout, 257 | VkImageCopy *region, const char *name) 258 | { 259 | vk_error retval = VK_ERROR_NONE; 260 | 261 | retval = copy_object_start(dev, essentials, "image", name); 262 | if (!vk_error_is_success(&retval)) 263 | return retval; 264 | 265 | vkCmdCopyImage(essentials->cmd_buffer, from->image, from_layout, to->image, to_layout, 1, region); 266 | 267 | return copy_object_end(dev, essentials); 268 | } 269 | 270 | vk_error vk_render_copy_buffer_to_image(struct vk_device *dev, struct vk_render_essentials *essentials, 271 | struct vk_image *to, VkImageLayout to_layout, struct vk_buffer *from, 272 | VkBufferImageCopy *region, const char *name) 273 | { 274 | vk_error retval = VK_ERROR_NONE; 275 | 276 | retval = copy_object_start(dev, essentials, "image", name); 277 | if (!vk_error_is_success(&retval)) 278 | return retval; 279 | 280 | vkCmdCopyBufferToImage(essentials->cmd_buffer, from->buffer, to->image, to_layout, 1, region); 281 | 282 | return copy_object_end(dev, essentials); 283 | } 284 | 285 | vk_error vk_render_copy_image_to_buffer(struct vk_device *dev, struct vk_render_essentials *essentials, 286 | struct vk_buffer *to, struct vk_image *from, VkImageLayout from_layout, 287 | VkBufferImageCopy *region, const char *name) 288 | { 289 | vk_error retval = VK_ERROR_NONE; 290 | 291 | retval = copy_object_start(dev, essentials, "buffer", name); 292 | if (!vk_error_is_success(&retval)) 293 | return retval; 294 | 295 | vkCmdCopyImageToBuffer(essentials->cmd_buffer, from->image, from_layout, to->buffer, 1, region); 296 | 297 | return copy_object_end(dev, essentials); 298 | } 299 | 300 | vk_error vk_render_transition_images(struct vk_device *dev, struct vk_render_essentials *essentials, 301 | struct vk_image *images, uint32_t image_count, 302 | VkImageLayout from, VkImageLayout to, VkImageAspectFlags aspect, const char *name) 303 | { 304 | vk_error retval = VK_ERROR_NONE; 305 | VkResult res; 306 | 307 | vkResetCommandBuffer(essentials->cmd_buffer, 0); 308 | VkCommandBufferBeginInfo begin_info = { 309 | .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 310 | .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, 311 | }; 312 | res = vkBeginCommandBuffer(essentials->cmd_buffer, &begin_info); 313 | vk_error_set_vkresult(&retval, res); 314 | if (res) 315 | { 316 | vk_error_printf(&retval, "Couldn't begin recording a command buffer to transition the %s image\n", name); 317 | return retval; 318 | } 319 | 320 | VkImageMemoryBarrier image_barrier = { 321 | .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 322 | .srcAccessMask = 0, 323 | .dstAccessMask = 0, 324 | .oldLayout = from, 325 | .newLayout = to, 326 | .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, 327 | .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, 328 | .subresourceRange = { 329 | .aspectMask = aspect, 330 | .baseMipLevel = 0, 331 | .levelCount = VK_REMAINING_MIP_LEVELS, 332 | .baseArrayLayer = 0, 333 | .layerCount = VK_REMAINING_ARRAY_LAYERS, 334 | }, 335 | }; 336 | 337 | for (uint32_t i = 0; i < image_count; ++i) 338 | { 339 | image_barrier.image = images[i].image; 340 | vkCmdPipelineBarrier(essentials->cmd_buffer, 341 | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 342 | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 343 | 0, 344 | 0, NULL, 345 | 0, NULL, 346 | 1, &image_barrier); 347 | } 348 | 349 | vkEndCommandBuffer(essentials->cmd_buffer); 350 | 351 | res = vkResetFences(dev->device, 1, &essentials->exec_fence); 352 | vk_error_set_vkresult(&retval, res); 353 | if (res) 354 | { 355 | vk_error_printf(&retval, "Failed to reset fence\n"); 356 | return retval; 357 | } 358 | 359 | VkSubmitInfo submit_info = { 360 | .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, 361 | .commandBufferCount = 1, 362 | .pCommandBuffers = &essentials->cmd_buffer, 363 | }; 364 | 365 | vkQueueSubmit(essentials->present_queue, 1, &submit_info, essentials->exec_fence); 366 | res = vkWaitForFences(dev->device, 1, &essentials->exec_fence, true, 1000000000); 367 | vk_error_set_vkresult(&retval, res); 368 | 369 | return retval; 370 | } 371 | 372 | 373 | static vk_error create_staging_buffer(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_render_essentials *essentials, 374 | struct vk_buffer *staging, uint8_t *contents, size_t size, const char *name) 375 | { 376 | vk_error retval = VK_ERROR_NONE; 377 | 378 | *staging = (struct vk_buffer){ 379 | .size = size, 380 | .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, 381 | .host_visible = true, 382 | }; 383 | 384 | retval = vk_create_buffers(phy_dev, dev, staging, 1); 385 | if (!vk_error_is_success(&retval)) 386 | { 387 | vk_error_printf(&retval, "Failed to create staging %s buffer\n", name); 388 | return retval; 389 | } 390 | 391 | char staging_name[50]; 392 | snprintf(staging_name, 50, "staging %s", name); 393 | retval = vk_render_fill_buffer(dev, staging, contents, size, staging_name); 394 | 395 | return retval; 396 | } 397 | 398 | vk_error vk_render_transition_images_mipmaps(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_render_essentials *essentials, 399 | struct vk_image *image, VkImageAspectFlags aspect, const char *name) 400 | { 401 | vk_error retval = VK_ERROR_NONE; 402 | VkResult res; 403 | 404 | VkFormatProperties formatProperties; 405 | vkGetPhysicalDeviceFormatProperties(phy_dev->physical_device, image->format, &formatProperties); 406 | 407 | if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) { 408 | printf("texture image format does not support linear blitting! %s image\n", name); 409 | retval.error.type=VK_ERROR_ERRNO; 410 | return retval; 411 | } 412 | 413 | vkResetCommandBuffer(essentials->cmd_buffer, 0); 414 | VkCommandBufferBeginInfo begin_info = { 415 | .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 416 | .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, 417 | }; 418 | res = vkBeginCommandBuffer(essentials->cmd_buffer, &begin_info); 419 | vk_error_set_vkresult(&retval, res); 420 | if (res) 421 | { 422 | vk_error_printf(&retval, "Couldn't begin recording a command buffer to transition the %s image\n", name); 423 | return retval; 424 | } 425 | 426 | int32_t mipWidth = image->extent.width; 427 | int32_t mipHeight = image->extent.height; 428 | uint32_t mipLevels = (int)(log(MAX(image->extent.width, image->extent.height))/log(2)) + 1; 429 | 430 | VkImageMemoryBarrier image_barrier = { 431 | .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 432 | .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, 433 | .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, 434 | .image = image->image, 435 | .subresourceRange = { 436 | .aspectMask = aspect, 437 | .levelCount = 1, 438 | .baseArrayLayer = 0, 439 | .layerCount = 1, 440 | }, 441 | }; 442 | 443 | for (uint32_t i = 1; i < mipLevels; i++) { 444 | image_barrier.subresourceRange.baseMipLevel = i - 1; 445 | image_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 446 | image_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 447 | image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 448 | image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; 449 | 450 | vkCmdPipelineBarrier(essentials->cmd_buffer, 451 | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 452 | 0, NULL, 453 | 0, NULL, 454 | 1, &image_barrier); 455 | 456 | VkImageBlit blit = {0}; 457 | blit.srcOffsets[0] = (struct VkOffset3D){.x=0, .y=0, .z=0}; 458 | blit.srcOffsets[1] = (struct VkOffset3D){.x=mipWidth, .y=mipHeight, .z=1}; 459 | blit.srcSubresource.aspectMask = aspect; 460 | blit.srcSubresource.mipLevel = i - 1; 461 | blit.srcSubresource.baseArrayLayer = 0; 462 | blit.srcSubresource.layerCount = 1; 463 | blit.dstOffsets[0] = (struct VkOffset3D){.x=0, .y=0, .z=0}; 464 | blit.dstOffsets[1] = (struct VkOffset3D){.x=(mipWidth > 1 ? mipWidth / 2 : 1), .y=(mipHeight > 1 ? mipHeight / 2 : 1), .z=1 }; 465 | blit.dstSubresource.aspectMask = aspect; 466 | blit.dstSubresource.mipLevel = i; 467 | blit.dstSubresource.baseArrayLayer = 0; 468 | blit.dstSubresource.layerCount = 1; 469 | 470 | vkCmdBlitImage(essentials->cmd_buffer, 471 | image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 472 | image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 473 | 1, &blit, 474 | VK_FILTER_LINEAR); 475 | 476 | image_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 477 | image_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 478 | image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; 479 | image_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 480 | 481 | vkCmdPipelineBarrier(essentials->cmd_buffer, 482 | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 483 | 0, NULL, 484 | 0, NULL, 485 | 1, &image_barrier); 486 | 487 | if (mipWidth > 1) mipWidth /= 2; 488 | if (mipHeight > 1) mipHeight /= 2; 489 | } 490 | 491 | image_barrier.subresourceRange.baseMipLevel = mipLevels - 1; 492 | image_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 493 | image_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 494 | image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 495 | image_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 496 | 497 | vkCmdPipelineBarrier(essentials->cmd_buffer, 498 | VK_PIPELINE_STAGE_TRANSFER_BIT, 499 | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 500 | 0, 501 | 0, NULL, 502 | 0, NULL, 503 | 1, &image_barrier); 504 | 505 | vkEndCommandBuffer(essentials->cmd_buffer); 506 | 507 | res = vkResetFences(dev->device, 1, &essentials->exec_fence); 508 | vk_error_set_vkresult(&retval, res); 509 | if (res) 510 | { 511 | vk_error_printf(&retval, "Failed to reset fence\n"); 512 | return retval; 513 | } 514 | 515 | VkSubmitInfo submit_info = { 516 | .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, 517 | .commandBufferCount = 1, 518 | .pCommandBuffers = &essentials->cmd_buffer, 519 | }; 520 | 521 | vkQueueSubmit(essentials->present_queue, 1, &submit_info, essentials->exec_fence); 522 | res = vkWaitForFences(dev->device, 1, &essentials->exec_fence, true, 1000000000); 523 | vk_error_set_vkresult(&retval, res); 524 | 525 | return retval; 526 | } 527 | 528 | vk_error vk_render_init_texture(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_render_essentials *essentials, 529 | struct vk_image *image, VkImageLayout layout, uint8_t *contents, const char *name) 530 | { 531 | vk_error retval = VK_ERROR_NONE; 532 | 533 | struct vk_buffer staging; 534 | retval = create_staging_buffer(phy_dev, dev, essentials, &staging, contents, image->extent.width * image->extent.height * 4, name); 535 | if (!vk_error_is_success(&retval)) 536 | return retval; 537 | 538 | retval = vk_render_transition_images(dev, essentials, image, 1, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT, name); 539 | if (!vk_error_is_success(&retval)) 540 | return retval; 541 | 542 | VkBufferImageCopy image_copy = { 543 | .imageSubresource = { 544 | .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 545 | .layerCount = 1, 546 | }, 547 | .imageExtent = { 548 | .width = image->extent.width, 549 | .height = image->extent.height, 550 | .depth = 1, 551 | }, 552 | }; 553 | 554 | retval = vk_render_copy_buffer_to_image(dev, essentials, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &staging, &image_copy, name); 555 | if (!vk_error_is_success(&retval)) 556 | return retval; 557 | 558 | if(image->mipmaps) 559 | { 560 | retval = vk_render_transition_images_mipmaps(phy_dev, dev, essentials, image, VK_IMAGE_ASPECT_COLOR_BIT, name); 561 | if (retval.error.type==VK_ERROR_ERRNO) 562 | retval = vk_render_transition_images(dev, essentials, image, 1, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, layout, VK_IMAGE_ASPECT_COLOR_BIT, name); 563 | } 564 | else 565 | retval = vk_render_transition_images(dev, essentials, image, 1, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, layout, VK_IMAGE_ASPECT_COLOR_BIT, name); 566 | 567 | vk_free_buffers(dev, &staging, 1); 568 | return retval; 569 | } 570 | 571 | vk_error vk_render_init_buffer(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_render_essentials *essentials, 572 | struct vk_buffer *buffer, void *contents, const char *name) 573 | { 574 | vk_error retval = VK_ERROR_NONE; 575 | 576 | struct vk_buffer staging; 577 | retval = create_staging_buffer(phy_dev, dev, essentials, &staging, contents, buffer->size, name); 578 | if (!vk_error_is_success(&retval)) 579 | return retval; 580 | 581 | retval = vk_render_copy_buffer(dev, essentials, buffer, &staging, buffer->size, name); 582 | 583 | vk_free_buffers(dev, &staging, 1); 584 | return retval; 585 | } 586 | 587 | 588 | int vk_render_finish(struct vk_render_essentials *essentials, struct vk_device *dev, 589 | struct vk_swapchain *swapchain, VkImageLayout from_layout, uint32_t image_index, 590 | VkSemaphore wait_sem, VkSemaphore signal_sem) 591 | { 592 | vk_error retval = VK_ERROR_NONE; 593 | VkResult res; 594 | 595 | VkImageMemoryBarrier image_barrier = { 596 | .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 597 | .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, 598 | .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT, 599 | .oldLayout = from_layout, 600 | .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, 601 | .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, 602 | .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, 603 | .image = essentials->images[image_index], 604 | .subresourceRange = { 605 | .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 606 | .baseMipLevel = 0, 607 | .levelCount = 1, 608 | .baseArrayLayer = 0, 609 | .layerCount = 1, 610 | }, 611 | }; 612 | 613 | vkCmdPipelineBarrier(essentials->cmd_buffer, 614 | VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 615 | VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 616 | 0, 617 | 0, NULL, 618 | 0, NULL, 619 | 1, &image_barrier); 620 | 621 | vkEndCommandBuffer(essentials->cmd_buffer); 622 | 623 | res = vkResetFences(dev->device, 1, &essentials->exec_fence); 624 | vk_error_set_vkresult(&retval, res); 625 | if (res) 626 | { 627 | vk_error_printf(&retval, "Failed to reset fence\n"); 628 | return res; 629 | } 630 | 631 | VkSemaphore wait_sems[2] = {essentials->sem_post_acquire, wait_sem}; 632 | VkSemaphore signal_sems[2] = {essentials->sem_pre_submit, signal_sem}; 633 | VkPipelineStageFlags wait_sem_stages[2] = {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT}; 634 | VkSubmitInfo submit_info = { 635 | .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, 636 | .waitSemaphoreCount = wait_sem?2:1, 637 | .pWaitSemaphores = wait_sems, 638 | .pWaitDstStageMask = wait_sem_stages, 639 | .commandBufferCount = 1, 640 | .pCommandBuffers = &essentials->cmd_buffer, 641 | .signalSemaphoreCount = signal_sem?2:1, 642 | .pSignalSemaphores = signal_sems, 643 | }; 644 | vkQueueSubmit(essentials->present_queue, 1, &submit_info, essentials->exec_fence); 645 | 646 | VkPresentInfoKHR present_info = { 647 | .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, 648 | .waitSemaphoreCount = 1, 649 | .pWaitSemaphores = &essentials->sem_pre_submit, 650 | .swapchainCount = 1, 651 | .pSwapchains = &swapchain->swapchain, 652 | .pImageIndices = &image_index, 653 | }; 654 | res = vkQueuePresentKHR(essentials->present_queue, &present_info); 655 | 656 | if (res == VK_ERROR_OUT_OF_DATE_KHR) { 657 | return VK_ERROR_OUT_OF_DATE_KHR; 658 | } else if (res == VK_SUBOPTIMAL_KHR) { 659 | return 0; 660 | } else if (res == VK_ERROR_SURFACE_LOST_KHR) { 661 | return VK_ERROR_SURFACE_LOST_KHR; 662 | } else { 663 | vk_error_set_vkresult(&retval, res); 664 | if (res < 0) 665 | { 666 | vk_error_printf(&retval, "Failed to queue image for presentation\n"); 667 | return -1; 668 | } 669 | } 670 | 671 | return 0; 672 | } 673 | 674 | -------------------------------------------------------------------------------- /vk_utils/vk_render_helper.h: -------------------------------------------------------------------------------- 1 | 2 | // Danil, 2020 Vulkan shader launcher, self https://github.com/danilw/vulkan-shader-launcher 3 | // The MIT License 4 | 5 | #ifndef vk_render_helper_H 6 | #define vk_render_helper_H 7 | 8 | #include "vk_utils.h" 9 | 10 | int vk_render_get_essentials(struct vk_render_essentials *essentials, struct vk_physical_device *phy_dev, 11 | struct vk_device *dev, struct vk_swapchain *swapchain); 12 | void vk_render_cleanup_essentials(struct vk_render_essentials *essentials, struct vk_device *dev); 13 | 14 | /* 15 | * Acquire an image from the swapchain, reset the command buffer, start recording, perform layout transition from 16 | * undefined to to_layout. 17 | */ 18 | VkResult vk_render_start(struct vk_render_essentials *essentials, struct vk_device *dev, 19 | struct vk_swapchain *swapchain, VkImageLayout to_layout, uint32_t *image_index); 20 | 21 | 22 | /* Fill the contents of a host-visible buffer/image with arbitrary data */ 23 | vk_error vk_render_fill_buffer(struct vk_device *dev, struct vk_buffer *to, void *from, size_t size, const char *name); 24 | vk_error vk_render_fill_image(struct vk_device *dev, struct vk_image *to, void *from, size_t size, const char *name); 25 | 26 | /* 27 | * Copy a buffer/image to another, for example from a host-visible one to a device-local one. This uses a command 28 | * buffer, submits it, and waits for it to finish, so it's not supposed to be used while recording a command buffer. 29 | */ 30 | vk_error vk_render_copy_buffer(struct vk_device *dev, struct vk_render_essentials *essentials, 31 | struct vk_buffer *to, struct vk_buffer *from, size_t size, const char *name); 32 | vk_error vk_render_copy_image(struct vk_device *dev, struct vk_render_essentials *essentials, 33 | struct vk_image *to, VkImageLayout to_layout, struct vk_image *from, VkImageLayout from_layout, 34 | VkImageCopy *region, const char *name); 35 | vk_error vk_render_copy_buffer_to_image(struct vk_device *dev, struct vk_render_essentials *essentials, 36 | struct vk_image *to, VkImageLayout to_layout, struct vk_buffer *from, 37 | VkBufferImageCopy *region, const char *name); 38 | vk_error vk_render_copy_image_to_buffer(struct vk_device *dev, struct vk_render_essentials *essentials, 39 | struct vk_buffer *to, struct vk_image *from, VkImageLayout from_layout, 40 | VkBufferImageCopy *region, const char *name); 41 | 42 | /* 43 | * 44 | * Transition an image to a new layout. This uses a command buffer, submits it, and waits for it to finish, so it's 45 | * not supposed to be used while recording a command buffer. 46 | */ 47 | vk_error vk_render_transition_images(struct vk_device *dev, struct vk_render_essentials *essentials, 48 | struct vk_image *images, uint32_t image_count, 49 | VkImageLayout from, VkImageLayout to, VkImageAspectFlags aspect, const char *name); 50 | 51 | vk_error vk_render_transition_images_mipmaps(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_render_essentials *essentials, 52 | struct vk_image *image, VkImageAspectFlags aspect, const char *name); 53 | 54 | /* 55 | * Create a texture image. This uses a command buffer, submits it, and waits for it to finish, 56 | * so it's not supposed to be used while recording a command buffer. It creates and destroys a staging buffer in the 57 | * process. In the end, it transitions the image to the desired layout. 58 | */ 59 | vk_error vk_render_init_texture(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_render_essentials *essentials, 60 | struct vk_image *image, VkImageLayout layout, uint8_t *contents, const char *name); 61 | 62 | /* 63 | * Copy over arbitrary data to the buffer. This uses a command buffer, submits it, and waits for it to finish, so it's 64 | * not supposed to be used while recording a command buffer. It creates and destroys a staging buffer in the process. 65 | */ 66 | vk_error vk_render_init_buffer(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_render_essentials *essentials, 67 | struct vk_buffer *buffer, void *contents, const char *name); 68 | 69 | 70 | /* 71 | * allow additional wait and signal semaphores so the submission will be 72 | * synchronized with off-screen renders as well. 73 | */ 74 | int vk_render_finish(struct vk_render_essentials *essentials, struct vk_device *dev, 75 | struct vk_swapchain *swapchain, VkImageLayout from_layout, uint32_t image_index, 76 | VkSemaphore wait_sem, VkSemaphore signal_sem); 77 | 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /vk_utils/vk_struct.h: -------------------------------------------------------------------------------- 1 | 2 | // Danil, 2020 Vulkan shader launcher, self https://github.com/danilw/vulkan-shader-launcher 3 | // The MIT License 4 | 5 | #ifndef vk_struct_H 6 | #define vk_struct_H 7 | 8 | #define VK_MAX_QUEUE_FAMILY 10 9 | 10 | struct vk_physical_device 11 | { 12 | VkPhysicalDevice physical_device; 13 | VkPhysicalDeviceProperties properties; 14 | VkPhysicalDeviceFeatures features; 15 | VkPhysicalDeviceMemoryProperties memories; 16 | 17 | VkQueueFamilyProperties queue_families[VK_MAX_QUEUE_FAMILY]; 18 | uint32_t queue_family_count; 19 | bool queue_families_incomplete; 20 | }; 21 | 22 | struct vk_commands 23 | { 24 | VkQueueFlags qflags; 25 | 26 | VkCommandPool pool; 27 | VkQueue *queues; 28 | uint32_t queue_count; 29 | VkCommandBuffer *buffers; 30 | uint32_t buffer_count; 31 | }; 32 | 33 | struct vk_device 34 | { 35 | VkDevice device; 36 | struct vk_commands *command_pools; 37 | uint32_t command_pool_count; 38 | }; 39 | 40 | #define VK_MAX_PRESENT_MODES 4 41 | 42 | struct vk_swapchain 43 | { 44 | VkSurfaceKHR surface; 45 | VkSwapchainKHR swapchain; 46 | VkSurfaceFormatKHR surface_format; 47 | VkSurfaceCapabilitiesKHR surface_caps; 48 | VkPresentModeKHR present_modes[VK_MAX_PRESENT_MODES]; 49 | uint32_t present_modes_count; 50 | }; 51 | 52 | struct vk_image 53 | { 54 | VkFormat format; 55 | VkExtent2D extent; 56 | VkImageUsageFlagBits usage; 57 | VkShaderStageFlagBits stage; 58 | bool make_view; 59 | bool will_be_initialized; 60 | bool host_visible; 61 | bool multisample; 62 | uint32_t *sharing_queues; 63 | uint32_t sharing_queue_count; 64 | VkImage image; 65 | VkDeviceMemory image_mem; 66 | VkImageView view; 67 | VkSampler sampler; 68 | bool anisotropyEnable; 69 | VkSamplerAddressMode repeat_mode; 70 | bool mipmaps; 71 | }; 72 | 73 | struct vk_buffer 74 | { 75 | VkFormat format; 76 | uint32_t size; 77 | VkBufferUsageFlagBits usage; 78 | VkShaderStageFlagBits stage; 79 | bool make_view; 80 | bool host_visible; 81 | uint32_t *sharing_queues; 82 | uint32_t sharing_queue_count; 83 | VkBuffer buffer; 84 | VkDeviceMemory buffer_mem; 85 | VkBufferView view; 86 | }; 87 | 88 | struct vk_shader 89 | { 90 | const char *spirv_file; 91 | VkShaderStageFlagBits stage; 92 | VkShaderModule shader; 93 | }; 94 | 95 | struct vk_graphics_buffers 96 | { 97 | VkExtent2D surface_size; 98 | VkImage swapchain_image; 99 | VkImageView color_view; 100 | struct vk_image depth; 101 | VkFramebuffer framebuffer; 102 | }; 103 | 104 | struct vk_render_essentials 105 | { 106 | VkImage *images; 107 | uint32_t image_count; 108 | VkQueue present_queue; 109 | VkCommandBuffer cmd_buffer; 110 | 111 | VkSemaphore sem_post_acquire; 112 | VkSemaphore sem_pre_submit; 113 | 114 | VkFence exec_fence; 115 | bool first_render; 116 | }; 117 | 118 | struct vk_resources 119 | { 120 | struct vk_image *images; 121 | uint32_t image_count; 122 | struct vk_buffer *buffers; 123 | uint32_t buffer_count; 124 | struct vk_shader *shaders; 125 | uint32_t shader_count; 126 | VkPushConstantRange *push_constants; 127 | uint32_t push_constant_count; 128 | VkRenderPass render_pass; 129 | }; 130 | 131 | struct vk_layout 132 | { 133 | struct vk_resources *resources; 134 | VkDescriptorSetLayout set_layout; 135 | VkPipelineLayout pipeline_layout; 136 | }; 137 | 138 | struct vk_pipeline 139 | { 140 | struct vk_layout *layout; 141 | VkPipelineVertexInputStateCreateInfo vertex_input_state; 142 | VkPipelineInputAssemblyStateCreateInfo input_assembly_state; 143 | VkPipelineTessellationStateCreateInfo tessellation_state; 144 | size_t thread_count; 145 | VkPipeline pipeline; 146 | VkDescriptorPool set_pool; 147 | }; 148 | 149 | enum vk_render_pass_load_op 150 | { 151 | VK_C_CLEAR = 0, 152 | VK_KEEP = 1, 153 | }; 154 | 155 | enum vk_make_depth_buffer 156 | { 157 | VK_WITHOUT_DEPTH = 0, 158 | VK_WITH_DEPTH = 1, 159 | }; 160 | 161 | struct vk_offscreen_buffers 162 | { 163 | VkExtent2D surface_size; 164 | struct vk_image color; 165 | struct vk_image depth; 166 | VkFramebuffer framebuffer; 167 | }; 168 | 169 | 170 | struct app_data_struct{ 171 | int iResolution[2]; //resolution 172 | int iMouse[2]; //mouse in window, it always updated (not like iMouse on shadertoy) 173 | int iMouse_lclick[2]; //mouse left click pos (its -[last pos] when left mosue not clicked) 174 | int iMouse_rclick[2]; //mouse right click pos (its -[last pos] when right mosue not clicked) 175 | bool iMouse_click[2]; //is mouse button clicked(left/right) 176 | float iTime; //time 177 | float iTimeDelta; //time delta 178 | int iFrame; //frames 179 | 180 | bool pause; //pause clicked 181 | bool quit; //quit clicked/happend 182 | bool drawdebug; //draw debug info, key press 183 | }; 184 | 185 | #define APP_NAME_STR_LEN 80 186 | struct app_os_window { 187 | #if defined(VK_USE_PLATFORM_WIN32_KHR) 188 | HINSTANCE connection; 189 | HWND window; 190 | POINT minsize; 191 | #elif defined(VK_USE_PLATFORM_XCB_KHR) 192 | Display *display; 193 | xcb_connection_t *connection; 194 | xcb_screen_t *screen; 195 | xcb_window_t xcb_window; 196 | xcb_intern_atom_reply_t *atom_wm_delete_window; 197 | #elif defined(VK_USE_PLATFORM_WAYLAND_KHR) 198 | struct wl_display *display; 199 | struct wl_registry *registry; 200 | struct wl_compositor *compositor; 201 | struct wl_surface *surface; 202 | struct xdg_wm_base *shell; 203 | struct wl_seat *seat; 204 | struct wl_pointer *pointer; 205 | struct wl_keyboard *keyboard; 206 | struct xdg_surface *xdg_surface; 207 | struct xdg_toplevel *xdg_toplevel; 208 | bool configured; 209 | #endif 210 | char name[APP_NAME_STR_LEN]; 211 | 212 | bool prepared; // is vk setup prepared 213 | 214 | bool is_minimized; //window controled events 215 | bool resize_event; //window controled events 216 | 217 | bool fps_lock; //key pressed event 218 | 219 | bool reload_shaders_on_resize; //launch option 220 | bool print_debug; //launch option 221 | 222 | VkPresentModeKHR present_mode; 223 | struct app_data_struct app_data; 224 | }; 225 | 226 | 227 | #endif 228 | -------------------------------------------------------------------------------- /vk_utils/vk_utils.h: -------------------------------------------------------------------------------- 1 | 2 | // Danil, 2020 Vulkan shader launcher, self https://github.com/danilw/vulkan-shader-launcher 3 | // The MIT License 4 | 5 | #ifndef vk_utils_H 6 | #define vk_utils_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "vk_error_print.h" 18 | #if defined(VK_USE_PLATFORM_XCB_KHR) 19 | #include 20 | #include 21 | #elif defined(VK_USE_PLATFORM_WAYLAND_KHR) 22 | #include 23 | #include 24 | #include "xdg-shell-client-protocol.h" 25 | #endif 26 | #include "vk_struct.h" 27 | 28 | #ifdef YARIV_SHADER 29 | #include "../yariv/yariv.h" 30 | #endif 31 | 32 | #define MAX(x, y) (((x) > (y)) ? (x) : (y)) 33 | #define MIN(x, y) (((x) < (y)) ? (x) : (y)) 34 | 35 | void vk_exit(VkInstance vk); 36 | 37 | vk_error vk_enumerate_devices(VkInstance vk,VkSurfaceKHR *surface, struct vk_physical_device *devs, uint32_t *idx, bool use_idx); 38 | 39 | vk_error vk_get_commands(struct vk_physical_device *phy_dev, struct vk_device *dev, VkDeviceQueueCreateInfo queue_info[], uint32_t queue_info_count, uint32_t create_count); 40 | 41 | void vk_cleanup(struct vk_device *dev); 42 | 43 | vk_error vk_load_shader(struct vk_device *dev, const uint32_t *code, VkShaderModule *shader, size_t size); 44 | #ifdef YARIV_SHADER 45 | vk_error vk_load_shader_yariv(struct vk_device *dev, const uint32_t *yariv_code, VkShaderModule *shader, size_t in_yariv_size); 46 | #endif 47 | vk_error vk_load_shader_spirv_file(struct vk_device *dev, const char *spirv_file, VkShaderModule *shader); 48 | void vk_free_shader(struct vk_device *dev, VkShaderModule shader); 49 | 50 | uint32_t vk_find_suitable_memory(struct vk_physical_device *phy_dev, struct vk_device *dev, 51 | VkMemoryRequirements *mem_req, VkMemoryPropertyFlags properties); 52 | 53 | vk_error vk_init_ext(VkInstance *vk, const char *ext_names[], uint32_t ext_count); 54 | vk_error vk_get_dev_ext(struct vk_physical_device *phy_dev, struct vk_device *dev, VkQueueFlags qflags, 55 | VkDeviceQueueCreateInfo queue_info[], uint32_t *queue_info_count, 56 | const char *ext_names[], uint32_t ext_count); 57 | 58 | static inline vk_error vk_init(VkInstance *vk) 59 | { 60 | const char *extension_names[] = { 61 | VK_KHR_SURFACE_EXTENSION_NAME, 62 | #if defined(VK_USE_PLATFORM_WIN32_KHR) 63 | VK_KHR_WIN32_SURFACE_EXTENSION_NAME, 64 | #elif defined(VK_USE_PLATFORM_XCB_KHR) 65 | VK_KHR_XCB_SURFACE_EXTENSION_NAME, 66 | #elif defined(VK_USE_PLATFORM_WAYLAND_KHR) 67 | VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, 68 | #endif 69 | }; 70 | return vk_init_ext(vk, extension_names, sizeof extension_names / sizeof *extension_names); 71 | } 72 | static inline vk_error vk_get_dev(struct vk_physical_device *phy_dev, struct vk_device *dev, VkQueueFlags qflags, 73 | VkDeviceQueueCreateInfo queue_info[], uint32_t *queue_info_count) 74 | { 75 | const char *extension_names[] = { 76 | VK_KHR_SWAPCHAIN_EXTENSION_NAME, 77 | }; 78 | return vk_get_dev_ext(phy_dev, dev, qflags, queue_info, queue_info_count, extension_names, 79 | sizeof extension_names / sizeof *extension_names); 80 | } 81 | 82 | // gcc 11 has Wstringop-overflow warning here, but this is GCC bug look like 83 | // look https://stackoverflow.com/questions/69426070/gcc-11-order-of-arguments-triggers-false-positive-wstringop-overflow-is-this-bu 84 | static vk_error vk_setup(struct vk_physical_device *phy_dev, struct vk_device *dev, VkQueueFlags qflags, uint32_t create_count) 85 | { 86 | VkDeviceQueueCreateInfo queue_info[VK_MAX_QUEUE_FAMILY]; 87 | uint32_t queue_info_count = 0; 88 | 89 | queue_info_count = phy_dev->queue_family_count; 90 | vk_error res = vk_get_dev(phy_dev, dev, qflags, queue_info, &queue_info_count); 91 | if (vk_error_is_success(&res)) 92 | { 93 | if(create_count<=queue_info[0].queueCount)create_count=0; //0=create one cmd_buffer per Queue 94 | res = vk_get_commands(phy_dev, dev, queue_info, queue_info_count, create_count); 95 | } 96 | return res; 97 | 98 | } 99 | 100 | vk_error vk_create_surface(VkInstance vk, VkSurfaceKHR *surface, struct app_os_window *os_window); 101 | 102 | vk_error vk_get_swapchain(VkInstance vk, struct vk_physical_device *phy_dev, struct vk_device *dev, 103 | struct vk_swapchain *swapchain, struct app_os_window *os_window, uint32_t thread_count, VkPresentModeKHR *present_mode); 104 | void vk_free_swapchain(VkInstance vk, struct vk_device *dev, struct vk_swapchain *swapchain); 105 | 106 | VkImage *vk_get_swapchain_images(struct vk_device *dev, struct vk_swapchain *swapchain, uint32_t *count); 107 | 108 | vk_error vk_create_images(struct vk_physical_device *phy_dev, struct vk_device *dev, 109 | struct vk_image *images, uint32_t image_count); 110 | vk_error vk_create_buffers(struct vk_physical_device *phy_dev, struct vk_device *dev, 111 | struct vk_buffer *buffers, uint32_t buffer_count); 112 | vk_error vk_load_shaders(struct vk_device *dev, 113 | struct vk_shader *shaders, uint32_t shader_count); 114 | vk_error vk_get_presentable_queues(struct vk_physical_device *phy_dev, struct vk_device *dev, 115 | VkSurfaceKHR surface, uint32_t **presentable_queues, uint32_t *presentable_queue_count); 116 | VkFormat vk_get_supported_depth_stencil_format(struct vk_physical_device *phy_dev); 117 | 118 | void vk_free_images(struct vk_device *dev, struct vk_image *images, uint32_t image_count); 119 | void vk_free_buffers(struct vk_device *dev, struct vk_buffer *buffers, uint32_t buffer_count); 120 | void vk_free_shaders(struct vk_device *dev, struct vk_shader *shaders, uint32_t shader_count); 121 | void vk_free_graphics_buffers(struct vk_device *dev, struct vk_graphics_buffers *graphics_buffers, uint32_t graphics_buffer_count, 122 | VkRenderPass render_pass); 123 | 124 | vk_error vk_make_graphics_layouts(struct vk_device *dev, struct vk_layout *layouts, uint32_t layout_count); 125 | vk_error vk_make_graphics_pipelines(struct vk_device *dev, struct vk_pipeline *pipelines, uint32_t pipeline_count, bool is_blend); 126 | 127 | void vk_free_layouts(struct vk_device *dev, struct vk_layout *layouts, uint32_t layout_count); 128 | void vk_free_pipelines(struct vk_device *dev, struct vk_pipeline *pipelines, uint32_t pipeline_count); 129 | 130 | vk_error vk_create_offscreen_buffers(struct vk_physical_device *phy_dev, struct vk_device *dev, VkFormat format, 131 | struct vk_offscreen_buffers *offscreen_buffers, uint32_t offscreen_buffer_count, VkRenderPass *render_pass, 132 | enum vk_render_pass_load_op keeps_contents, enum vk_make_depth_buffer has_depth); 133 | vk_error vk_create_graphics_buffers(struct vk_physical_device *phy_dev, struct vk_device *dev, VkFormat format, 134 | struct vk_graphics_buffers *graphics_buffers, uint32_t graphics_buffer_count, VkRenderPass *render_pass, 135 | enum vk_render_pass_load_op keeps_contents, enum vk_make_depth_buffer has_depth); 136 | 137 | void vk_free_offscreen_buffers(struct vk_device *dev, struct vk_offscreen_buffers *offscreen_buffers, uint32_t offscreen_buffer_count, 138 | VkRenderPass render_pass); 139 | 140 | #endif 141 | -------------------------------------------------------------------------------- /wayland_xdg/xdg-shell-client-protocol.c: -------------------------------------------------------------------------------- 1 | /* Generated by wayland-scanner 1.18.0 */ 2 | 3 | /* 4 | * Copyright © 2008-2013 Kristian Høgsberg 5 | * Copyright © 2013 Rafael Antognolli 6 | * Copyright © 2013 Jasper St. Pierre 7 | * Copyright © 2010-2013 Intel Corporation 8 | * Copyright © 2015-2017 Samsung Electronics Co., Ltd 9 | * Copyright © 2015-2017 Red Hat Inc. 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a 12 | * copy of this software and associated documentation files (the "Software"), 13 | * to deal in the Software without restriction, including without limitation 14 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 15 | * and/or sell copies of the Software, and to permit persons to whom the 16 | * Software is furnished to do so, subject to the following conditions: 17 | * 18 | * The above copyright notice and this permission notice (including the next 19 | * paragraph) shall be included in all copies or substantial portions of the 20 | * Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 25 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 28 | * DEALINGS IN THE SOFTWARE. 29 | */ 30 | 31 | #include 32 | #include 33 | #include "wayland-util.h" 34 | 35 | #ifndef __has_attribute 36 | # define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ 37 | #endif 38 | 39 | #if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) 40 | #define WL_PRIVATE __attribute__ ((visibility("hidden"))) 41 | #else 42 | #define WL_PRIVATE 43 | #endif 44 | 45 | extern const struct wl_interface wl_output_interface; 46 | extern const struct wl_interface wl_seat_interface; 47 | extern const struct wl_interface wl_surface_interface; 48 | extern const struct wl_interface xdg_popup_interface; 49 | extern const struct wl_interface xdg_positioner_interface; 50 | extern const struct wl_interface xdg_surface_interface; 51 | extern const struct wl_interface xdg_toplevel_interface; 52 | 53 | static const struct wl_interface *xdg_shell_types[] = { 54 | NULL, 55 | NULL, 56 | NULL, 57 | NULL, 58 | &xdg_positioner_interface, 59 | &xdg_surface_interface, 60 | &wl_surface_interface, 61 | &xdg_toplevel_interface, 62 | &xdg_popup_interface, 63 | &xdg_surface_interface, 64 | &xdg_positioner_interface, 65 | &xdg_toplevel_interface, 66 | &wl_seat_interface, 67 | NULL, 68 | NULL, 69 | NULL, 70 | &wl_seat_interface, 71 | NULL, 72 | &wl_seat_interface, 73 | NULL, 74 | NULL, 75 | &wl_output_interface, 76 | &wl_seat_interface, 77 | NULL, 78 | &xdg_positioner_interface, 79 | NULL, 80 | }; 81 | 82 | static const struct wl_message xdg_wm_base_requests[] = { 83 | { "destroy", "", xdg_shell_types + 0 }, 84 | { "create_positioner", "n", xdg_shell_types + 4 }, 85 | { "get_xdg_surface", "no", xdg_shell_types + 5 }, 86 | { "pong", "u", xdg_shell_types + 0 }, 87 | }; 88 | 89 | static const struct wl_message xdg_wm_base_events[] = { 90 | { "ping", "u", xdg_shell_types + 0 }, 91 | }; 92 | 93 | WL_PRIVATE const struct wl_interface xdg_wm_base_interface = { 94 | "xdg_wm_base", 3, 95 | 4, xdg_wm_base_requests, 96 | 1, xdg_wm_base_events, 97 | }; 98 | 99 | static const struct wl_message xdg_positioner_requests[] = { 100 | { "destroy", "", xdg_shell_types + 0 }, 101 | { "set_size", "ii", xdg_shell_types + 0 }, 102 | { "set_anchor_rect", "iiii", xdg_shell_types + 0 }, 103 | { "set_anchor", "u", xdg_shell_types + 0 }, 104 | { "set_gravity", "u", xdg_shell_types + 0 }, 105 | { "set_constraint_adjustment", "u", xdg_shell_types + 0 }, 106 | { "set_offset", "ii", xdg_shell_types + 0 }, 107 | { "set_reactive", "3", xdg_shell_types + 0 }, 108 | { "set_parent_size", "3ii", xdg_shell_types + 0 }, 109 | { "set_parent_configure", "3u", xdg_shell_types + 0 }, 110 | }; 111 | 112 | WL_PRIVATE const struct wl_interface xdg_positioner_interface = { 113 | "xdg_positioner", 3, 114 | 10, xdg_positioner_requests, 115 | 0, NULL, 116 | }; 117 | 118 | static const struct wl_message xdg_surface_requests[] = { 119 | { "destroy", "", xdg_shell_types + 0 }, 120 | { "get_toplevel", "n", xdg_shell_types + 7 }, 121 | { "get_popup", "n?oo", xdg_shell_types + 8 }, 122 | { "set_window_geometry", "iiii", xdg_shell_types + 0 }, 123 | { "ack_configure", "u", xdg_shell_types + 0 }, 124 | }; 125 | 126 | static const struct wl_message xdg_surface_events[] = { 127 | { "configure", "u", xdg_shell_types + 0 }, 128 | }; 129 | 130 | WL_PRIVATE const struct wl_interface xdg_surface_interface = { 131 | "xdg_surface", 3, 132 | 5, xdg_surface_requests, 133 | 1, xdg_surface_events, 134 | }; 135 | 136 | static const struct wl_message xdg_toplevel_requests[] = { 137 | { "destroy", "", xdg_shell_types + 0 }, 138 | { "set_parent", "?o", xdg_shell_types + 11 }, 139 | { "set_title", "s", xdg_shell_types + 0 }, 140 | { "set_app_id", "s", xdg_shell_types + 0 }, 141 | { "show_window_menu", "ouii", xdg_shell_types + 12 }, 142 | { "move", "ou", xdg_shell_types + 16 }, 143 | { "resize", "ouu", xdg_shell_types + 18 }, 144 | { "set_max_size", "ii", xdg_shell_types + 0 }, 145 | { "set_min_size", "ii", xdg_shell_types + 0 }, 146 | { "set_maximized", "", xdg_shell_types + 0 }, 147 | { "unset_maximized", "", xdg_shell_types + 0 }, 148 | { "set_fullscreen", "?o", xdg_shell_types + 21 }, 149 | { "unset_fullscreen", "", xdg_shell_types + 0 }, 150 | { "set_minimized", "", xdg_shell_types + 0 }, 151 | }; 152 | 153 | static const struct wl_message xdg_toplevel_events[] = { 154 | { "configure", "iia", xdg_shell_types + 0 }, 155 | { "close", "", xdg_shell_types + 0 }, 156 | }; 157 | 158 | WL_PRIVATE const struct wl_interface xdg_toplevel_interface = { 159 | "xdg_toplevel", 3, 160 | 14, xdg_toplevel_requests, 161 | 2, xdg_toplevel_events, 162 | }; 163 | 164 | static const struct wl_message xdg_popup_requests[] = { 165 | { "destroy", "", xdg_shell_types + 0 }, 166 | { "grab", "ou", xdg_shell_types + 22 }, 167 | { "reposition", "3ou", xdg_shell_types + 24 }, 168 | }; 169 | 170 | static const struct wl_message xdg_popup_events[] = { 171 | { "configure", "iiii", xdg_shell_types + 0 }, 172 | { "popup_done", "", xdg_shell_types + 0 }, 173 | { "repositioned", "3u", xdg_shell_types + 0 }, 174 | }; 175 | 176 | WL_PRIVATE const struct wl_interface xdg_popup_interface = { 177 | "xdg_popup", 3, 178 | 3, xdg_popup_requests, 179 | 3, xdg_popup_events, 180 | }; 181 | 182 | -------------------------------------------------------------------------------- /yariv/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12) 2 | 3 | project(yariv) 4 | 5 | set(SOURCES 6 | "main.c" 7 | ) 8 | 9 | add_executable( 10 | yariv_pack 11 | ${SOURCES} 12 | ) 13 | 14 | if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") 15 | add_definitions(/Wall /WX /wd4514) 16 | #target_link_libraries(yariv_pack) 17 | elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") 18 | add_definitions(-Wall -Wextra) 19 | #target_link_libraries(yariv_pack) 20 | else() 21 | message(WARNING "Unknown compiler '${CMAKE_C_COMPILER_ID}'!") 22 | endif() 23 | -------------------------------------------------------------------------------- /yariv/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "yariv.h" 5 | 6 | void *spirv; 7 | size_t spirv_size; 8 | 9 | static void replacestr(char *line, const char *search, const char *replace) 10 | { 11 | char *sp; 12 | 13 | if ((sp = strstr(line, search)) == NULL) { 14 | return; 15 | } 16 | int search_len = strlen(search); 17 | int replace_len = strlen(replace); 18 | int tail_len = strlen(sp+search_len); 19 | 20 | memmove(sp+replace_len,sp+search_len,tail_len+1); 21 | memcpy(sp, replace, replace_len); 22 | } 23 | 24 | int main(int argc,char* argv[]) { 25 | 26 | if(argc > 2) { 27 | printf("Too many arguments supplied. One argument expected.\n"); 28 | return 0; 29 | } 30 | if(argc == 1) { 31 | printf("One argument expected.\n"); 32 | return 0; 33 | } 34 | 35 | if(strstr(argv[1], ".spv") == NULL){ 36 | printf("error in file name, need file.spv \n"); 37 | return 0; 38 | } 39 | 40 | FILE *f = fopen(argv[1], "rb"); 41 | if (f==NULL){ 42 | printf("File not found.\n"); 43 | return 0; 44 | } 45 | 46 | fseek(f, 0, SEEK_END); 47 | spirv_size = ftell(f); 48 | fseek(f, 0, SEEK_SET); 49 | spirv = malloc(spirv_size); 50 | 51 | fread(spirv, 1, spirv_size, f); 52 | fclose(f); 53 | 54 | void *out_yariv; 55 | size_t out_yariv_size; 56 | out_yariv_size = yariv_encode_size(yariv_encode_flags_strip, spirv, spirv_size); 57 | out_yariv = malloc(out_yariv_size); 58 | yariv_encode(yariv_encode_flags_strip, out_yariv, out_yariv_size, spirv, spirv_size); 59 | 60 | 61 | char str[200]; 62 | strcpy(str,argv[1]); 63 | replacestr(str,".spv",".yariv"); 64 | FILE *fp; 65 | fp = fopen(str, "w"); 66 | fwrite(out_yariv,out_yariv_size,1,fp); 67 | fclose(fp); 68 | free(out_yariv); 69 | 70 | printf("converted %s to %s yariv_size %ld \n",argv[1],str,out_yariv_size); 71 | } 72 | 73 | --------------------------------------------------------------------------------